opensymphony 3.0.0

A Rust implementation of the OpenAI Symphony orchestration design
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
# Project Memory

OpenSymphony project memory turns completed Linear work into durable development
context. During `opensymphony run`, terminal issue transitions are captured
automatically when memory auto-capture is enabled. The capture uses Linear issue
narrative, active Workpad content, issue hierarchy, milestones, GitHub PR
descriptions, reviews, checks, and source refs. It writes private issue capsules
under `.opensymphony/memory/`, updates a DuckDB index, evolves
`.opensymphony/memory/memory.yaml`, and syncs stable topics into public docs.

The operator projection reports memory scope, source freshness, degradation,
and overlay provenance without exposing memory grants or tokens. Memory
availability does not grant filesystem access.

Related specifications:

- [OKF Memory System Specification]specs/okf-memory-spec.md describes how the
  Markdown memory corpus should evolve into Open Knowledge Format bundles.
- [Knowledge Graph Specification]specs/llm-wiki-graph-view-spec.md describes
  the client-side graph explorer for those bundles.

## Rationale and Model

Linear remains OpenSymphony's short-term planning and coordination surface, but
completed issues still carry implementation knowledge that should survive queue
cleanup and archival. GitHub PRs preserve code review history, and Workpad
comments preserve useful audit details, but neither is a convenient
component-oriented project memory on its own.

OpenSymphony memory is the completed-work distillation of what mattered: the
intent, shipped outcome, decisions, validation evidence, relevant review
feedback, follow-ups, risks, and documentation impact. Implementation agents
should keep their focus on code, validation, PRs, and Workpad accuracy; long-term
memory is produced by capture and docs sync rather than by ad hoc edits during
ordinary feature work.

The memory system has two different outputs:

- Issue capsules record what happened for one completed Linear issue. They are
  compact source-referenced closeout documents, not run transcripts.
- Topic docs describe what is now true about a subsystem. They capture the
  current model, invariants, gotchas, and recent changes without requiring
  readers to know which issue introduced the knowledge.

## OKF Bundle Compatibility

OpenSymphony treats OKF as the portable Markdown contract for memory, not as a
replacement for the current local store. The logical bundle layout follows
`docs/specs/okf-memory-spec.md`:

```text
bundle-root/
  index.md
  log.md
  projects/
  milestones/
  issues/
  areas/
  repositories/
  code/
  runs/
  references/
```

The current `.opensymphony/memory/` paths stay in place for this compatibility
slice. Issue capsules map to `issues/<issue>.md`, milestone nodes map to
`milestones/<slug>.md`, generated topic docs map to `areas/<slug>.md`, and
repository memory remains a facet under `repositories/` rather than the root
taxonomy.

Every parsed OKF concept requires YAML frontmatter with a non-empty `type` and a
contained bundle-relative Markdown path. Existing legacy top-level fields such
as `issue`, `milestone`, `linear_url`, `areas`, `repository`, `prs`,
`source_refs`, and `docs_sync` are preserved as data during parse/render. The
parser also projects those fields into `opensymphony` extension metadata:
visibility, concept kind, scope refs, source refs, and docs-sync state. Unknown
frontmatter is kept in the raw frontmatter map so future writers can round-trip
documents they do not fully understand. Writers emit canonical YAML and do not
preserve the original frontmatter field order or whitespace.

`opensymphony memory lint --okf [bundle-root]` validates an OKF bundle from the
CLI, and the memory MCP admin path accepts the equivalent `memory.lint` request
with `okf` plus `bundleRoot` arguments. A user-supplied bundle root is
canonicalized and must stay inside the repository root, matching the containment
policy used by other memory admin file arguments. When no bundle root is
provided, linting uses the configured memory root.

`opensymphony memory export-okf --visibility public|private [--output DIR]`
exports the configured memory root as a directory bundle. The output directory
defaults to `okf-export-{visibility}` under the repository root when omitted and
must be new or empty so stale private files cannot survive a public export.
Export writes into a repository-contained staging directory first, runs OKF lint
on the staged bundle, and only then promotes the completed bundle to the
requested output path. If final promotion fails, OpenSymphony preserves the
lint-clean staged bundle for recovery and restores the previous empty output
directory when possible. Public export skips private concepts and fails if any
remaining public concept still references private comments, private memory
paths, or private source snapshots. Private export can include private concepts
but still keeps normal OKF lint errors fatal except for visible links back into
the private memory store, which are expected in private round-trip bundles.

The public export redaction scan is deliberately narrow and explicit: it treats
`linear:comment:`, `.opensymphony/memory/issues`,
`.opensymphony/memory/source*`, `.opensymphony/memory/snapshot*`, and their
Windows-path variants as private material when they appear in exported public
concepts. The scan uses the same markdown-visible text extraction as private
memory link linting, so fenced code blocks, inline code spans, escaped text, and
HTML comments do not create public export false positives.

The memory MCP admin surface exposes the same export operation as
`memory.export_okf` with `visibility` (`public` or `private`) and optional
`output` arguments. It uses the same repository containment, staging, lint, and
public redaction checks as the CLI command.

`opensymphony memory import-okf <bundle-root> [--force]` validates an OKF
directory bundle, copies its Markdown concepts into the configured memory root
without rewriting frontmatter, and rebuilds the derived DuckDB catalog from the
imported bundle. The import source and target memory root are canonicalized,
checked against the repository containment policy, and rejected when they
overlap. Import preflights the full copy set before writing so predictable
target conflicts do not leave partially imported Markdown files. Existing
Markdown files are not overwritten unless `--force` is supplied. Because
`import-okf` restores both public and private bundles, visible private memory
links are allowed during import and preserved in the copied Markdown. Unknown
concept types, unknown frontmatter fields, missing optional fields, broken
links, and missing generated indexes are warning-level import inputs; malformed
concepts remain errors with file paths in the diagnostic.

Import is not transactional after the preflight succeeds. A filesystem write or
DuckDB reindex failure can leave already-copied Markdown files in the memory
root. Fix the underlying failure, inspect the partially copied files, and rerun
with `--force` only when replacing those files is intentional.

The memory MCP admin surface exposes the same import operation as
`memory.import_okf` with `bundleRoot` and optional `force` arguments. Prefer the
CLI or MCP admin tools for normal maintenance; direct file or DuckDB inspection
is an offline fallback for recovery and diagnostics only.

OKF lint diagnostics are intentionally actionable. Errors cover missing or
invalid concept frontmatter, missing `type`, malformed reserved files,
containment failures, and public-export leaks of private memory. Warnings cover
missing recommended fields, unknown types, broken Markdown links, wiki-only
links without Markdown equivalents, missing generated indexes, missing
citations for source-backed claims, and unknown OKF versions. Info diagnostics
call out synthesized title/description data, retained legacy fields, and
OpenSymphony extension metadata. Warning-level findings remain nonfatal;
private-data leakage and containment breakage are reported as errors.

Migration is intentionally incremental:

- Phase 1 enriches and parses existing documents as OKF concepts while keeping
  legacy paths and fields.
- Phase 2 can mirror or move documents into the final bundle layout and rebuild
  the catalog from OKF concepts.
- Phase 3 can expose graph, hosted import/export, and visibility-filtered APIs
  from the OKF-derived catalog.

The memory graph projection is derived from the OKF catalog, not from client
edits. Graph snapshots include bundle, directory, concept, tag, resource,
citation, source-ref, and community nodes plus derived containment, Markdown,
external, citation, tag, resource, scope, source-support, and same-resource
edges. Broken Markdown links are kept as unresolved edges. Snapshot metrics
report orphan, broken-link, stale-concept, and warning counts, while node
metrics report degree, global normalized centrality across all graph node
kinds, bridge score, and community ID. Community labels prefer concept areas,
then tags, directories, and concept type. Each concept is assigned to exactly
one deterministic community; when multiple areas are present the sorted first
area wins, and tag fallback uses frontmatter order.
Tags, citations, and source refs are excluded from community membership by
default and can be included with the memory graph endpoint query flags. Those
flags also parameterize node community IDs and bridge scores because the
community membership input set changes with the query. Community IDs are stable
grouping keys, not graph node IDs; community graph nodes are separately
namespaced with `community:<id>`.

No graph-library dependency is currently selected for memory graph extraction:
the shipped backend work only derives deterministic catalog relationships and
metadata communities. Add a graph library when the server owns true clustering
or graph algorithms beyond these deterministic DTO metrics.

The default visibility posture is private memory with optional public docs.
Private capsules may include Linear comments, review context, and source
snapshots, while public docs should contain public source refs such as issue
identifiers, PR URLs, and commit SHAs. Public docs must not link directly to
private capsule paths. Public memory is supported only by explicit
configuration, and generated indexes such as DuckDB should remain local unless a
project deliberately publishes them.

Generated memory `indexes/log.md` output groups entries under `## YYYY-MM-DD`
headings with newest dates first. The date comes from indexed completion time
when available, then capture time, and finally a stable ISO sentinel for
malformed legacy rows so regeneration is deterministic.

Areas bridge issue memory and topic docs. Area inference uses Linear narrative,
labels, milestones, active Workpad content, PR narrative, review summaries, and
existing learned aliases in `.opensymphony/memory/memory.yaml`. GitHub changed
files are indexed for path-based lookup, but they do not create areas or appear
in capsule or docs prose. Merge SHAs are immutable audit refs, not inference
signals.

The CLI remains useful for setup, historical backfill, inspection, and manual
operator actions:

```bash
opensymphony memory init
opensymphony memory capture COE-123
opensymphony memory context --issue COE-456
opensymphony memory brief COE-123
opensymphony memory related --area openhands-runtime
opensymphony memory sync-docs --since-last-sync
opensymphony memory serve --addr 127.0.0.1:8765
opensymphony memory export-okf --visibility public --output public-okf
opensymphony memory import-okf public-okf
opensymphony linear archive --issues COE-123
```

Use `--dry-run` on write commands when you want a non-writing preview.

## Configuration

`config.yaml` controls run-loop automation:

```yaml
memory:
  auto_capture: true
  auto_archive: false
  serve: true
  bind: 127.0.0.1:0
```

`auto_capture` defaults to `true`. `auto_archive` defaults to `false`; when it
is enabled, OpenSymphony archives only after fresh capture succeeds with no
blocking warnings. `serve` starts the local memory server during
`opensymphony run` when memory is initialized. The default bind address selects
an available loopback port once, records it in
`<workspace-root>/.opensymphony-memory-bind.json`, and reuses that exact port on
later starts. This keeps the endpoint stable for an authenticated parent
conversation recovered after daemon restart; startup fails if the recorded
port cannot be rebound rather than rotating the conversation's endpoint.
Workers receive the resulting MCP endpoint through
`OPENSYMPHONY_MEMORY_ENDPOINT`. Workers receive only the normal read token;
admin tools require a separate `OPENSYMPHONY_MEMORY_ADMIN_TOKEN`.

### Persistent Code Graph indexing

`POST /api/v1/code/repos/{repo_id}/index` and the native `code_index_repo`
command build a bounded repository snapshot for the target branch recorded in
`WORKFLOW.md` (default `develop`). The server resolves the repository root and
commit; clients cannot provide arbitrary roots. Files are read from Git tree and
blob objects, so indexing does not execute target-repository code.

Snapshot membership is immutable and keyed by repository, commit, and path.
Documents, symbols, edges, diagnostics, and skipped coverage are persisted in
batches. A later commit reuses unchanged membership, parses changed or added
paths, and marks deleted current rows stale without rewriting older revisions.
One process-wide index writer lock serializes concurrent indexing requests while
DuckDB read paths remain usable. The gateway journals accepted/progress,
completed, unavailable, and failed outcomes; `code_graph_updated` is emitted
only after a completed snapshot is available.

This index is a shared target-branch baseline. It must not be treated as the
live code state of an issue workspace; workspace overlays provide that view.

An empty DuckDB is a supported starting state. The gateway advertises the
configured repository with zero coverage, allowing the web or desktop Code
Graph surface to start indexing directly. The surface renders accepted and
progress coverage, skipped-file diagnostics, retryable failures, and refreshes
from `code_graph_updated`; during accepted/progress work with no event delivery,
the shell polls repository summaries and recognizes a newly indexed baseline.
Production web requests use HTTP and packaged desktop requests use the
Tauri-native `code_index_repo` command against the same report contract.

Initialize the shared memory policy and learned ontology file once:

```bash
opensymphony memory init
```

This creates `.opensymphony/memory/memory.yaml` and updates `.gitignore` so only
that config is tracked. Capsules, indexes, DuckDB, source snapshots, and
automation logs remain local runtime artifacts.

The config is not a hand-maintained docs map. It is a policy plus learned
structure file that capture can evolve as more work lands:

```yaml
memory_root: .opensymphony/memory
visibility: private
index_path: .opensymphony/memory/memory.duckdb
confidence_threshold: 75
source_snapshots: hashes
markdown_indexes: true
docs:
  public_root: docs
  default_visibility: public
  deny_private_links: true
areas:
  openhands-runtime:
    title: OpenHands Runtime
    docs_target: docs/openhands-agent-server.md
    visibility: public
    status: stable
    confidence: 85
    aliases:
      - OpenHands Runtime
    source_refs:
      docs:
        - docs/openhands-agent-server.md
      linear_labels:
        - runtime
      linear_issues:
        - COE-123
```

`memory init` seeds stable areas from existing top-level `docs/*.md` files when
they exist. It does not scan `docs/tasks`, `README.md`, Cargo files, source
files, or GitHub changed-file lists to create docs topics. When no docs exist,
the config is still valid and starts with an empty `areas` map.

## Capture Evidence

Live capture requires Linear access from `WORKFLOW.md` and uses GitHub PR
discovery by default through `gh`. For each issue, OpenSymphony reads:

- Linear title, description, labels, state, URL, milestone, parent, children,
  and active Workpad comment
- GitHub PR title, body, branch, checks, review discussion summaries, commits,
  merge SHA, and changed files

Area inference treats Linear labels named `area:<slug>` as canonical. Existing
label aliases and narrative evidence from Linear and GitHub still work as
fallbacks. Merge SHA is not used for inference or search; it is stored only
under `source_refs` as the immutable audit pointer to the exact merged code
state. GitHub changed files are indexed for later lookup such as "which issues
touched this file?", but they are not rendered into capsules or docs and do not
infer areas.

Selecting a parent issue also captures its child issue closure. Capsules link
parents, children, and milestones so the Obsidian graph shows the work
structure.

Linear and GitHub are part of the normal live flow. A missing `WORKFLOW.md`,
invalid Linear config, missing issue, Linear API failure, or failing `gh`
command fails capture. Use `--no-github` only for unusual non-PR work.

## Import and Backfill

`memory import` is for deterministic backfills, migrations, tests, or external
exports. It is not the normal path.

```bash
opensymphony memory import --source-file completed.yaml
opensymphony memory import COE-123 --source-file completed.yaml
opensymphony memory import --issue-range COE-120..COE-130 --source-file completed.yaml
```

Top-level source YAML fields:

```yaml
issues: []
prs: []
overrides: {}
```

Important issue fields:

```yaml
issues:
  - id: issue-id
    identifier: COE-123
    title: Issue title
    url: https://linear.app/example/issue/COE-123
    description: Optional issue description
    state: Done
    milestone: M3
    milestone_id: milestone-id
    parent:
      identifier: COE-100
      title: Parent title
    children:
      - identifier: COE-124
        title: Child title
    labels:
      - runtime
    comments:
      - id: comment-id
        author: username
        body: "Decision or summary text"
        updated_at: 2026-03-25T22:05:00Z
        source: linear:workpad
    linked_prs:
      - 456
```

Important PR fields:

```yaml
prs:
  - number: 456
    title: COE-123 implement reconnect recovery
    url: https://github.com/example/repo/pull/456
    branch: coe-123-reconnect
    body: Pull request summary
    merge_sha: abcdef1234567890
    changed_files:
      - path: crates/opensymphony-openhands/src/client.rs
        change_kind: modified
    checks:
      - name: cargo test
        conclusion: success
    reviews:
      - reviewer: reviewer
        state: APPROVED
        disposition: Looks correct.
```

All fields except `issues[].identifier` and `prs[].number` are optional.

## Query and Docs Sync

Useful read commands:

```bash
opensymphony memory status
opensymphony memory context --issue COE-456
opensymphony memory brief COE-123
opensymphony memory related --area openhands-runtime
opensymphony memory related --paths crates/opensymphony-openhands
opensymphony memory search "reconnect recovery"
opensymphony memory docs --area openhands-runtime
```

`memory context` is a pre-implementation context compiler, not a capture
command. It fetches live Linear facts when available, excludes the current issue
capsule, and selects captured memory from deterministic buckets: explicit
includes, blocking predecessors, completed children, completed siblings, path
matches, and canonical area matches. It strips each selected brief's
`Documentation impact` section and appends one deduplicated section at the end.
When `opensymphony run` starts a worker, it asks the supervised memory server
for the same style of kickoff bundle and writes it to
`.opensymphony/generated/memory-context.md` inside the issue workspace. If the
server is disabled, the runner falls back to direct local memory reads.

Read commands open the DuckDB index in read-only mode and do not run migrations.
Startup and write paths own schema creation or migration.

When central configuration is active, one supervised memory server owns one
instance-wide catalog. Repository inventory entries are registered in that
catalog by canonical repository ID and exact checkout commit. Policy files,
public documentation, portable OKF bundles, and legacy stores remain
repository-owned sources; private issue, project, milestone, and cross-
repository records remain in the instance catalog. Source registration is a
startup/write operation and records its status and generation in DuckDB, while
ordinary MCP reads only inspect the existing schema. Code-intelligence lookups
use the registered canonical repository ID rather than a caller-supplied local
path.

Managed local OpenHands workers receive the memory endpoint and their
per-conversation scoped read grant through the worker environment. The
process-wide server read token is never placed in the shared managed-server
environment, so one worker cannot bypass its grant by reading that token from a
shared agent-server process.

`memory serve` exposes the memory command set through a local MCP-style
Streamable HTTP JSON-RPC endpoint at `/mcp`. CLI commands call that endpoint
when `OPENSYMPHONY_MEMORY_ENDPOINT` is set; otherwise they use offline direct
mode. Read tools are `memory.context`, `memory.search`, `memory.related`,
`memory.brief`, `memory.docs`, `memory.status`, and, when
`code_intel.ast.enabled` is true, `code.ast.status`, `code.ast.outline`,
`code.ast.symbols`, `code.ast.references`, `code.ast.context`, and
`code.ast.diagnostics`. `code.ast.query` is also local read-only by default,
but requires the admin token when an admin token is configured so hosted or
token-gated deployments can restrict ad hoc query execution. Admin tools are
`memory.capture`, `memory.sync_docs`, `memory.lint`, `memory.reindex`,
`memory.export_okf`, `memory.import_okf`, and `memory.ingest_code_intel`; these
require `OPENSYMPHONY_MEMORY_ADMIN_TOKEN` or `--admin-token` on
`opensymphony memory serve`. If an admin token is configured without a separate
read token, the admin token also protects read tools.
Worker-grant capability checks follow that server access decision: a local
read-only `code.ast.query` does not require an administrative grant capability,
while a configured admin token still gates the request at the server boundary.
On a supervised server with a configured workspace root, unauthenticated
unscoped reads are still rejected as worker requests; an operator using the
configured read or admin bearer may perform ordinary read calls without a
worker grant. Worker calls remain bound to a server-issued project-set,
project, work-item, canonical-repository, visibility, and capability grant.
Explicit filters can only narrow those claims. `all_accessible` is therefore
bounded by the grant, and an authorized sibling repository must be named
explicitly. Ordinary worker grants have no administrative capability. Persisted
sibling memory and target-branch code use the registered canonical source;
AST requests may name that source using the `repository` alias as well as the
legacy `repo` field; live overlays resolve only the execution repository's
verified checkout. A parent integration grant instead contains the exact
repository set from its durable runtime envelope. Persisted memory may span
that set and the parent plus recorded descendants; `all_accessible` cannot add
another repository or work item. Live overlays resolve only the envelope's
active integration checkouts, using their opaque handles, contained relative
paths, run and attempt, and target commits. An unrelated managed checkout stays
inaccessible even when its repository belongs to the same project.
The overlay must match the worker's issue, run, attempt, checkout generation,
and target commit. A worker may advance that checkout during its run; strict
discovery verifies that the current `HEAD` descends from the target commit
instead of freezing the overlay to the startup `HEAD`. Each result reports the
canonical repository, the revision that actually produced its source path or
symbol, freshness, and persisted-versus-live provenance.
`memory.context` builds the agent kickoff bundle. Add `--include-code-intel`
to include code-intelligence artifacts alongside selected memory. For requested
Rust paths, OpenSymphony renders Tree-sitter AST summaries, symbols, diagnostics,
and a trace section before falling back to repository analysis. Unsupported
languages, parser diagnostics, oversized files, and calls without requested
paths use the existing `CodebaseAnalyzer` repository-summary fallback; mixed
supported and unsupported requests can include both AST artifacts and fallback
artifacts. The trace section records parse/query counts and the fallback reason.
The rendered artifact/provider contract is owned by `opensymphony_code_intel`;
memory keeps the legacy `CodeIntelIndex` and `CodeIntelArtifact` surface as an
adapter around that provider contract instead of requiring code-intelligence
providers to import memory internals.

Worker-scoped memory access uses a server-local, non-persisted bearer grant
bound to the worker's project-set, project, work item, execution repository,
authorized repository set, visibility, run/attempt, and checkout generation.
An unchanged leaf claim set may reuse the conversation bearer; a changed leaf
run, attempt, binding, target commit, or generation rotates the bearer and
requires a fresh leaf conversation. The startup checkout `HEAD` is retained as
capture provenance, not as a live-overlay equality requirement. Durable daemon
recovery reconstructs leaf claims from the runtime envelope and forces a fresh
leaf conversation when the in-memory registry was replaced. A parent controller
instead restores the bearer already held by its persisted OpenHands
conversation into the reconstructed registry and verifies the same memory
endpoint and workspace before reattachment. A missing or different parent
conversation manifest is rejected before a replacement session can launch.
Terminal, inactive, and binding-superseded lifecycles issue the stop/cancel
fence before revoking the issue grant. Raw bearer tokens are never persisted in
manifests or diagnostics. With automatic capture enabled, terminal issues seen
at daemon startup remain capture candidates instead of being assumed captured.
Subtree cleanup revokes a bearer only when its checkout generation matches the
cleanup target. If a newer generation for the same issue already holds the
live grant, old-generation cleanup leaves that bearer and its lifecycle state
unchanged.
This grant applies to direct `memory.show` capsule reads as well as search,
context, brief, related, docs, status, and code-intelligence tools. If the
central service stops, the control-plane status is explicitly degraded and
scoped worker reads remain blocked; they do not silently fall back to an
unrelated repository-local store. Leaf capture reads the immutable runtime
envelope for repository ownership and commits, and documentation sync uses
that explicit owner. Terminal capture reads those durable envelopes from leaf
roots and from the generation-bound `parents/<parent-key>/<generation>` layout.
Completed parent roots remain retained across reconciliation and restart so a
transient capture failure cannot erase the repository/run provenance needed for
the next attempt. Their descendant leases remain active with the root so leaf
cleanup cannot invalidate registered integration worktrees before OSYM-893
records capture acknowledgement and performs ordered cleanup. The run loop
records that acknowledgement only after the capture workflow completes for the
selected parent. Cleanup first receipts hook execution and detaches the parent
integration worktrees, then removes unleased descendants bottom-up and the
parent root last. Failure to persist the acknowledgement leaves the capture
candidate eligible for retry.
For a parent, the capture path also reads validated durable controller state
and requires a matching terminal lifecycle. Successful completion additionally
requires its final attempt to be passed for the same run and input version, its
final evidence to be bound to the same conversation, and its exact repository
commit map to equal the runtime envelope. A terminal run manifest or harness
success by itself cannot authorize successful parent capture. Failed and
canceled controllers receive a repository-neutral parent binding with no
verified commit claims so their diagnostics can be captured before the explicit
retention policy runs. If restart proves that a parent launch never attached and
no `run.json` exists, the owned parent manifest plus the matching terminal
controller supplies only that neutral parent classification; it does not invent
run, attempt, command, or commit evidence. The durable binding explicitly marks
a parent even when its commit map is empty, so repository-neutral capture cannot
inherit a configured default leaf repository. A capture with an actual runtime
envelope records one repository-neutral parent-runtime source reference with
the durable run and attempt identifiers.
Retained legacy run envelopes that lack usable run/attempt provenance are
skipped as non-bindable entries during the pre-cleanup scan rather than
preventing unrelated terminal captures from completing.
The direct `code.ast.*` tools return JSON with path, line range, content hash,
parser version, query-pack version, trace, and truncation metadata for targeted
agent inspection. `memory.context` remains the recommended kickoff path.
`memory.ingest_code_intel` generates code-intelligence artifacts without
persistence by default. Admin callers can pass `persist=true` to write derived
DuckDB rows for code documents, symbols, query-pack edges, and parser
diagnostics. Persisted rows store metadata, hashes, spans, parser/query-pack
versions, freshness, and snippet hashes only; full parse trees and source
snippets are rendered from files on demand. Re-ingesting a changed file or a
different parser/query-pack version marks older derived rows stale before
writing current rows. Commit SHA and dirty-worktree state are stored as
provenance on the current rows; a clean re-ingest with identical content,
parser version, and query-pack version updates that provenance without reporting
phantom stale rows.

Generated, vendor, build, and cache directories are skipped during directory
traversal with trace warnings, as are files over `code_intel.ast.max_file_bytes`.
Explicit file requests inside skipped directory names still parse when they pass
path containment and resource limits. The AST tools only use built-in pinned
grammar crates and never execute target-repo source, build scripts, package
manager scripts, tests, or macros. See
[`docs/code-intelligence.md`](code-intelligence.md) for the operator and agent
workflow.

`opensymphony memory reindex --from-okf [bundle-root]` rebuilds the derived
DuckDB catalog from OKF concept documents, defaulting to the configured memory
root. Broken links and unknown concept types are indexed as warnings; malformed
OKF frontmatter remains fatal because those files are not parseable concepts.
The OKF rebuild clears derived GitHub metadata tables (`pull_requests`,
`changed_files`, `checks`, and `reviews`) because OKF concepts do not currently
carry that capture-enrichment data.

Docs sync writes stable topic docs by default and prints stat-style output with
file paths, line counts, and changed-line totals:

```bash
opensymphony memory sync-docs --since-last-sync
opensymphony memory sync-docs --issues COE-123
```

Candidate or low-confidence areas remain private until later captures raise
their confidence. Automation records warnings in `.opensymphony/memory/indexes`
so operators can inspect unresolved capture or docs-sync blockers. When the
Linear project overview content is available, OpenSymphony also maintains a
managed memory-status section there for capture warnings that need attention.

## Archive Guard

Archival is guarded by memory capture. For explicit issues,
`opensymphony linear archive` first performs live Linear and GitHub capture, then
archives only eligible issues:

```bash
opensymphony linear archive --issues COE-123
opensymphony linear archive --issue-range COE-120..COE-130
```

An issue is eligible when fresh captured memory exists and has no unresolved
capture warnings. `--force` bypasses the guard for a deliberate operator
recovery. To archive from already captured memory without recapturing, use
`--from-memory`.

When managed local OpenHands is configured, the archive command also moves
matching conversations into the repo-scoped `archived/` store. It first tries
the issue workspace's `.opensymphony/conversation.json` manifest, then scans
managed conversation `meta.json` files for a `workspace.working_dir` ending in
the issue key so repo-scoped active conversations and legacy flat conversations
are covered by the same archive operation.

## Troubleshooting

- If Linear fails, fix `WORKFLOW.md`, tracker credentials, or issue selection.
  Live capture does not fall back to placeholder records.
- If GitHub discovery fails, install/authenticate `gh` or intentionally rerun
  with `--no-github`.
- If docs sync writes no topic docs, inspect `.opensymphony/memory/memory.yaml`
  for candidate areas below the confidence threshold.
- Use `opensymphony memory capture --help`,
  `opensymphony memory import --help`, and
  `opensymphony linear archive --help` for the current command surface.

<!-- BEGIN OPENSYMPHONY MANAGED MEMORY SYNC -->

## Current model

- COE-252 contributed: PR #10: Implement foundation workflow and scheduler contracts
- COE-253 contributed: PR #19: COE-253: OpenHands Runtime Adapter (merge `911b0b4`)
- COE-254 contributed: PR #6: COE-254: bootstrap tracker, workspace, and orchestration core
- COE-255 contributed: PR #4: COE-255: add control plane and FrankenTUI slice
- COE-256 contributed: PR #1: COE-257: tighten hosted deployment guidance
- COE-258 contributed: PR #83: Add memory init and mapped docs sync

## Important invariants

- Preserve the behavior described in the recent captured changes unless current code and tests show it has changed.
- Use capsule source refs to inspect the original PR or Linear issue when context is ambiguous.

## Operational flow

- No generated diagram requested for this sync.

## Known gotchas

- No area-specific gotchas were inferred from the selected memory.

## Recent changes

- COE-252: Foundation and Contracts
- COE-253: OpenHands Runtime Adapter
- COE-254: Tracker, Workspaces, and Orchestration
- COE-255: Observability and FrankenTUI
- COE-256: Validation and Local Operations
- COE-258: Bootstrap workspace and crate boundaries
- COE-259: Workflow loader and typed config
- COE-260: Domain model and orchestrator state machine
- COE-261: Local agent-server supervisor
- COE-262: REST client and conversation contract
- COE-263: Workspace manager and lifecycle hooks
- COE-264: Linear read adapter and issue normalization
- COE-265: WebSocket event stream, reconciliation, and recovery
- COE-266: Issue session runner
- COE-267: Linear MCP write surface
- COE-268: Orchestrator scheduler, retries, and reconciliation
- COE-269: Control-plane API and snapshot store
- COE-270: Repository harness and generated context artifacts
- COE-271: FrankenTUI operator client
- COE-272: Fake OpenHands server and protocol contract suite
- COE-273: Live local end-to-end suite
- COE-274: CLI packaging, doctor, and local operations docs
- COE-277: Implement hierarchy-aware task selection
- COE-280: Support workflow-owned OpenHands auth, provider, and launcher overrides at runtime
- COE-281: Support path-bearing OpenHands base URLs and MCP config at runtime
- COE-282: Support workflow-owned OpenHands conversation reuse policy at runtime
- COE-284: Add orchestrator run command to CLI and make it installable
- COE-287: Add opensymphony debug command for conversational session debugging
- COE-294: Detect LLM config changes and rehydrate conversations with updated env vars
- COE-382: Add supply-chain and security audits to CI
- COE-383: Decompose oversized session and TUI modules into focused submodules
- COE-384: Expand error-path tests for Linear client and workspace hooks
- COE-385: Resolve runtime tracking TODO in OpenHands session runner
- COE-386: Wire cargo-llvm-cov coverage reporting and regression floor into CI
- COE-387: Audit tracing spans and diagnostics for secret leakage
- COE-389: Current Gateway Inventory And Vocabulary
- COE-390: Gateway Schemas And Stream Feasibility
- COE-391: Gateway Module, Capabilities, And Dashboard Snapshot
- COE-392: Task Graph, Run Detail, File, And Diff Read APIs
- COE-393: Event Journal And Stream Broker
- COE-394: Frontend Workspace And Shared Schemas
- COE-395: Planning Artifact Schema And Session Service
- COE-396: Action Receipts And Initial Run Actions
- COE-397: Gateway API Client, Transport Adapters, And Reducers
- COE-398: Tauri Shell And Security Capabilities
- COE-399: Linear Read Coverage And Task Graph Cache
- COE-400: OpenHands Event Normalization And Runtime Mirror
- COE-401: Web App Entry And Deployment Modes
- COE-402: App Shell, Dashboard, Task Graph, And Run Views
- COE-403: Terminal And Log Renderer Prototype
- COE-404: Desktop Connection Profiles And Daemon Management
- COE-405: Linear Milestone, Issue, And Sub-Issue Mutations
- COE-406: Repository, Linear, And Research Analysis
- COE-407: Browser Transport And Remote Stream Protocols
- COE-408: Harness Adapter And Capability Model
- COE-409: Desktop Settings, Keychain, And Native Actions
- COE-410: Desktop Local Stream Optimization
- COE-411: Task Graph Editor And Runtime Overlay UI
- COE-412: Runtime Timeline And Terminal/Log Association
- COE-413: Implementation Plan Generator Stage
- COE-414: Diff, Validation, Approval, And Run Action Views
- COE-415: Milestone, Issue, And Sub-Issue Compiler
- COE-416: Dependency Graph And Plan Checks
- COE-417: Planning Workspace UI
- COE-419: Hosted Auth Placeholders And Web Parity
- COE-423: Model And Credential Settings
- COE-425: OpenHands Subscription Credential Adapter
- COE-426: Codex App-Server Prototype And Benchmarks
- COE-428: Model Configuration UI And Routing Metadata
- COE-429: Codex Approvals And Cross-Harness Routing
- COE-434: Long-running harness liveness and scheduler/runtime ownership contract
- COE-435: Long-running run observability fixtures and client-facing diagnostics
- COE-448: Multi-repo memory server and deterministic context
- COE-449: Desktop alpha recovery: replace stubs with functional app
- COE-452: DuckDB Prebuilt Developer Build Mode
- COE-453: Non-Interactive Init For Automation
- COE-454: OKF Bundle Schema And Legacy Capsule Mapping
- COE-456: OKF Writer, Lint, And Migration Fixtures
- COE-458: Catalog Reindex And Query Compatibility From OKF
- COE-460: OKF Export, Import, And Visibility Boundaries
- COE-461: Memory Graph DTOs And Gateway Endpoints
- COE-463: Docs Sync And MCP Admin Parity For OKF
- COE-464: Graph Extraction, Metrics, And Community Pipeline
- COE-465: Shared Graph Frontend Package And Reducers
- COE-467: Three.js Graph Renderer And Worker Layouts
- COE-468: Concept Inspector, Search, Filters, And Accessibility Fallback
- COE-469: Live Memory Graph Integration And Privacy Gates
- COE-471: Graph Scale, Visual Regression, And Web/Desktop Hardening
- COE-473: Desktop task graph dependency and run detail parity
- COE-475: ChatGPT OAuth For Codex Harness
- COE-476: Codex Production Harness Enablement
- COE-478: Harden model profile storage and validation follow-ups
- COE-479: Codex Debug Session Resume
- COE-480: Run Detail Metrics And Density
- COE-481: Model Configuration Codex Subscription Follow-Up
- COE-482: TUI Codex Token Usage Accounting
- COE-483: Codex Event Content Summaries
- COE-484: Desktop Live Snapshot And Run Detail Refresh
- COE-485: Harden desktop live event resumption and refresh failure visibility
- COE-486: Harness Interrupt Contract And Run Diagnostics
- COE-487: Desktop Run Detail TUI Parity
- COE-488: Lazy Desktop Launcher Command
- COE-489: OpenHands Agent-Server Interrupt Adapter
- COE-490: Codex App-Server Turn Interrupt Adapter
- COE-491: Desktop Run Detail Action Wiring And Cleanup
- COE-492: Merging Supersedes Human Review Polling
- COE-493: Desktop Operations Integration Hardening
- COE-494: Project Metadata For Operator Issue Snapshots
- COE-495: FrankenTUI Project Headers And Dependency Gutter
- COE-496: Desktop Project Grouping And Collapse
- COE-497: Project Grouping Integration Hardening
- COE-498: Tree-sitter Provider Skeleton And Rust Parsing
- COE-499: Memory Context AST Provider Integration
- COE-500: Query Packs For Supported Agent Languages
- COE-501: Code Intelligence Persistence And Ingestion
- COE-502: Read-Only AST MCP And CLI Tools
- COE-503: Code Intelligence Performance Docs And Hardening
- COE-504: Linear Polling And Rate-Limit Recovery
- COE-505: Add scheduler-side Codex stdio interrupt channel
- COE-506: Invert CodeIntelIndex trait ownership after AST memory integration
- COE-507: Deduplicate query-pack assets for grammar variants
- COE-508: Cache code-intel parsers and compiled query packs
- COE-520: Route desktop Knowledge Graph through native gateway commands
- COE-521: Workflow Target Branch Model And Init Customization
- COE-522: Init Target Branch Prompt And Flag
- COE-523: Update Workflow Settings Mode
- COE-524: Template Docs And Settings Hardening
- COE-525: Desktop Installer Contract And Release Metadata
- COE-526: Desktop Release Bundle Pipeline
- COE-527: Source Build Fallback And Prerequisites
- COE-528: App Download Install And Launch Flow
- COE-529: Desktop Auto-Update Flow
- COE-530: Installer Docs And End-To-End Validation
- COE-531: Workspace Shell Graph Hero And Surface State
- COE-532: Symbol Identity Container Chain And Code Read Model
- COE-533: Code Graph DTOs Gateway Routes And Native Commands
- COE-534: Code Graph Frontend Surface Adapters And Inspector
- COE-535: Run Diff Symbol Navigation And Code Overlay
- COE-536: Cross Graph Code Memory And Work Chips
- COE-537: Code Graph Scale Accessibility And Parity Hardening
- COE-540: Canonical Codex Thread Reuse And Workspace Retention
- COE-541: Durable Codex Thread Archive And Debug Recovery
- COE-542: Target Branch Code Index And Revision Snapshots
- COE-543: Workspace Code Overlay And Composite Graph
- COE-544: Indexed Agent Code Context And Retrieval
- COE-545: Edge Delta And Module Topology Diff
- COE-546: Code Graph Bootstrap UX And End-To-End Validation
- COE-547: Central Multi-Repository Config And Safe Migration
- COE-548: Canonical Repository Binding And Task Propagation
- COE-549: Verified Checkouts Instructions And Harness Envelopes
- COE-550: Per-Instance Memory Catalog And Source Migration
- COE-551: Scoped Cross-Repository Memory And Leaf Overlays
- COE-553: Parent Execution Roots And Child Workspace Reuse
- COE-554: Restart-Safe Parent Integration Controller
- COE-555: Parent Repair Review And Merge Lifecycle
- COE-556: Bottom-Up Subtree Cleanup And Recovery
- COE-562: Implement artifact validation and digest primitives
- COE-563: Implement task-packet admission and freeze tooling
- COE-564: Implement verifier execution and outcome records
- COE-565: Implement isolated workspace materialization
- COE-566: Implement configurable run matrices and scheduling
- COE-567: Implement run lifecycle and process-protocol primitives
- COE-608: ACP Profiles And Executable Protocol Client
- COE-609: ACP Session Ownership And Durable Recovery
- COE-610: ACP Client Callbacks And Session Configuration
- COE-611: ACP Execution Routing And Worker Integration
- COE-612: ACP Operator Requests And Response Routing
- COE-613: ACP Extensions And Harness Operations
- COE-615: ACP Runtime Conformance And Live Qualification

## Source refs

- COE-252
- COE-253
- COE-254
- COE-255
- COE-256
- COE-258
- COE-259
- COE-260
- COE-261
- COE-262
- COE-263
- COE-264
- COE-265
- COE-266
- COE-267
- COE-268
- COE-269
- COE-270
- COE-271
- COE-272
- COE-273
- COE-274
- COE-277
- COE-280
- COE-281
- COE-282
- COE-284
- COE-287
- COE-294
- COE-382
- COE-383
- COE-384
- COE-385
- COE-386
- COE-387
- COE-389
- COE-390
- COE-391
- COE-392
- COE-393
- COE-394
- COE-395
- COE-396
- COE-397
- COE-398
- COE-399
- COE-400
- COE-401
- COE-402
- COE-403
- COE-404
- COE-405
- COE-406
- COE-407
- COE-408
- COE-409
- COE-410
- COE-411
- COE-412
- COE-413
- COE-414
- COE-415
- COE-416
- COE-417
- COE-419
- COE-423
- COE-425
- COE-426
- COE-428
- COE-429
- COE-434
- COE-435
- COE-448
- COE-449
- COE-452
- COE-453
- COE-454
- COE-456
- COE-458
- COE-460
- COE-461
- COE-463
- COE-464
- COE-465
- COE-467
- COE-468
- COE-469
- COE-471
- COE-473
- COE-475
- COE-476
- COE-478
- COE-479
- COE-480
- COE-481
- COE-482
- COE-483
- COE-484
- COE-485
- COE-486
- COE-487
- COE-488
- COE-489
- COE-490
- COE-491
- COE-492
- COE-493
- COE-494
- COE-495
- COE-496
- COE-497
- COE-498
- COE-499
- COE-500
- COE-501
- COE-502
- COE-503
- COE-504
- COE-505
- COE-506
- COE-507
- COE-508
- COE-520
- COE-521
- COE-522
- COE-523
- COE-524
- COE-525
- COE-526
- COE-527
- COE-528
- COE-529
- COE-530
- COE-531
- COE-532
- COE-533
- COE-534
- COE-535
- COE-536
- COE-537
- COE-540
- COE-541
- COE-542
- COE-543
- COE-544
- COE-545
- COE-546
- COE-547
- COE-548
- COE-549
- COE-550
- COE-551
- COE-553
- COE-554
- COE-555
- COE-556
- COE-562
- COE-563
- COE-564
- COE-565
- COE-566
- COE-567
- COE-608
- COE-609
- COE-610
- COE-611
- COE-612
- COE-613
- COE-615

<!-- END OPENSYMPHONY MANAGED MEMORY SYNC -->