# Testing
This document defines the test strategy for OpenSymphony. For local operating
procedures, doctor guidance, rehydration, diagnostics, packaging, and safety
notes, see [operations.md](operations.md).
## 1. Testing philosophy
OpenSymphony sits at the intersection of:
- a specification-driven orchestrator
- an external issue tracker
- a remote-style agent runtime
- a terminal UI
The project needs more than unit tests. It needs layered validation with deterministic fakes and opt-in live tests.
Projection tests must cover round trips, blocked-state rendering, local versus
remote path boundaries, and secret-canary absence across Rust, TypeScript, TUI,
web, and desktop surfaces.
## 2. Test layers
## 2.1 Unit tests
Every internal subsystem module should have focused unit tests for pure logic.
Examples:
- workflow parsing and strict template rendering
- issue identifier sanitization
- config resolution and environment indirection
- retry delay math
- event ordering and deduplication
- snapshot reducers
- TUI reducers and formatting helpers
## 2.2 Contract tests
Use the internal `opensymphony_testkit` module for protocol-level checks
against stable fixtures.
Required contract suites:
- conversation create payload serialization
- user-message event payload serialization
- `run` trigger request behavior
- WebSocket event decoding for known event types
- unknown-event pass-through handling
- event-search pagination and reconciliation
- terminal state derivation from `ConversationStateUpdateEvent`
## 2.3 Integration tests with fakes
Run these in CI.
Components to fake:
- OpenHands agent-server
- Linear GraphQL responses
- local control-plane API consumer
Why fakes matter:
- deterministic edge-case coverage
- out-of-order event sequences
- disconnect and reconnect behavior
- server restart scenarios
- scheduler recovery on daemon restart
- parent integration launch-intent persistence before worker start, exact
run-bound final-verification receipts, missing/stale receipt rejection,
exact command hashing before durable redaction, prior-attempt event rejection,
production-shaped Codex and OpenHands command start/completion events,
observed parent-root and checkout working directories, orchestrator-owned
deadlines, bounded command logs/resources, rejection of prompt-authored
execution claims, uncertain cleanup fences, metadata-only prelaunch crash
recovery, authenticated same-conversation parent grants after restart,
prelaunch rejection of missing or changed bound conversation manifests and
parent harness switches, attempt-specific continuation prompts for Codex and
OpenHands, terminal-turn cleanup before retry, retryable active cancellation,
completed-parent reopen with unchanged child edges, compacted admission
idempotency, empty-target verification, recursive intermediate-descendant
memory grants, durable-controller-gated parent capture, stable default memory
endpoint recovery, event-only command-receipt persistence, dry-run preview
isolation, legacy missing-controller migration before same-conversation
reattachment, terminal-success finalization gates, and retry after a failed
durable outcome write
- parent repair branch, push, pull-request, review, merge, and refresh
reconciliation with side-effect counters; persistence failure before branch
creation; bounded current-head feedback for credential-scrubbed workers;
resolved-thread pushback; controller cancellation between repair turns and
when tracker state changes before a completed implementation turn publishes;
retention after a conversation-bound transport failure without terminal proof;
requested changes on one PR; failed checks, rejection, outage,
external closure, force-push, and conflict states; squash/rebase merge-result
reachability; retained-child reachability after target refresh; inherited
commit-signing isolation; and separately auditable attempts across repositories
## 2.4 Live local tests
These are opt-in and run against a pinned real OpenHands server on a trusted machine.
Gate them behind explicit environment variables.
Suggested gates:
- `OPENSYMPHONY_LIVE_OPENHANDS=1`
- `OPENSYMPHONY_LIVE_LINEAR=1`
Current implementation:
- the repository, CI, Clippy MSRV checks, root package, and desktop package all
use Rust 1.97.1; the Edition 2024 workspace uses Cargo Resolver 3
- `cargo check-dev`, `cargo test-dev`, and `cargo clippy-dev` are repository
aliases for iterative OpenSymphony development. The aliases set
`DUCKDB_DOWNLOAD_LIB=1` only for the aliased command and build with
`--no-default-features --features duckdb-prebuilt` so the native DuckDB
library is downloaded into
`target/duckdb-download` and reused across rebuilds in the same target
directory.
- `cargo test` exercises the full root package, including the fake-server contract suite from `tests/fake_server_contract.rs`
- `cargo test --test linear_client` exercises fixture-backed GraphQL normalization, parent/child hierarchy extraction, personal-API-key auth headers, required API-key/project/state configuration validation, issue URL/raw-priority preservation, full label pagination, raw workflow-state type preservation alongside normalized kinds, non-archived candidate polling, lightweight dispatch-summary reads, archived terminal cleanup reads, archived by-ID state refresh, GraphQL 400/429 rate-limit retries including reset-header handling, long rate-limit reset return-without-sleep behavior with the 30s inline cap, retryable 5xx GraphQL error envelopes, project-scoped by-ID state refresh with bounded unscoped fallback for moved issues, and tracker error mapping against a local stub server
- `cargo test --test linear_client live_linear_client_reads_opensymphony_project -- --ignored --nocapture` is a read-only live evidence probe for PRs that need to show the actual Linear HTTP/GraphQL client path against the OpenSymphony project
- `cargo test --test hierarchy_selection --test scheduler` exercises blocker-aware and hierarchy-aware dispatch filtering, child-edge generation reconciliation and freeze fencing, owner-identified lease acquisition, provider-evidence parent eligibility, leaf-before-parent ordering, cached per-state capacity limiting, continuation retry, exponential failure backoff, runtime-event-fed stall detection, terminal cleanup/release, active-state reconciliation, Linear cooldown behavior, separated Linear polling cadences, manifest-backed workspace recovery against fake tracker/workspace/worker backends, external retry-marker proof, metadata-only workspace recovery, binding-drift workspace rematerialization, legacy parent neutrality, same-ID generation retention, independent running/discovery cadences, and adoption of every launched worker after persistence errors
- `cargo test --lib parent_integration` exercises the restart-safe parent state machine, exact multi-repository and empty-target evidence, topology-neutral checkout handles, idempotent admission after transition compaction, bounded diagnostics, timeout and indeterminate cleanup gates, resource collisions, and higher-ancestor serialization
- the memory scope and terminal capture tests cover parent grants across exact descendants, denial of unrelated repositories and work items, parent runtime-envelope capture, and preservation of every verified repository commit
- `cargo test --lib orchestrator_run::backends::tests` covers runtime workspace-manifest recovery, in-flight run detection from `run.json`, and launch-path failure handling in the concrete CLI adapter
- `cargo test --test workspace_manager` covers durable checkout/staging ownership-marker sweeps, preservation of foreign generation-shaped directories and staging content, receipt-owned recovery, and the retry verification mode that permits legitimate worker changes while retaining checkout provenance checks
- `cargo test --lib opensymphony_workspace::manager::tests::discover_agents` and the memory scope tests cover bounded tracked-instruction probes, failure propagation, canonical project-ID filtering, and project-scoped direct capsule reads
- `scripts/hermetic_multi_repo_lifecycle.sh` is the M12.97 release gate. It
composes the inherited strict-config, migration/rollback, three-bare-repository
workspace, scheduler/provider restart, memory-scope, gateway/TUI, and
web/desktop suites and writes exact commit/config-hash evidence. The numbered
boundary and fault mapping lives in `docs/multi-repository-rollout.md`.
- `cargo test --lib orchestrator_run::backends::tests` covers deferred cross-harness retirement so a failed replacement keeps the previous session recoverable
- `tests/doctor.rs` runs the CLI live-probe path against the internal `opensymphony_testkit` module
- `scripts/smoke_local.sh` runs the static doctor pass
- `scripts/live_e2e.sh` gates the live doctor run behind `OPENSYMPHONY_LIVE_OPENHANDS=1`
- `tests/fake_server_contract.rs` and `tests/client_resilience.rs` now split the runtime stream coverage intentionally: the shared fake-server contract suite owns the scripted initial snapshot replay, attach-backlog versus buffered-live ordering, reconnect exhaustion, explicit-close shutdown semantics, reconcile, out-of-order delivery, and reconnect recovery cases, while `client_resilience.rs` keeps the narrower auth, forward-compatibility, and mirror-regression cases that still need bespoke server behavior
- `tests/live_pinned_server.rs` provides an opt-in live integration check against the pinned `openhands-agent-server==1.24.0` surface for external-mode auth success and failure
- `tests/issue_session_runner.rs` now covers continuation reuse, already-running conversation wait/retry behavior, launch reporting for reused running conversations before prior-turn drain completes, delayed `/run` conflicts that surface an active prior turn only after attach, missing-conversation recreation that stays on continuation guidance, **simplified conversation resumption that reuses conversations as-is without LLM config drift checks**, configured `persistence_dir_relative` handling, terminal-error normalization, and temp-repo smoke execution
- `tests/supervisor.rs` now covers startup rejection when a foreign ready server is already bound to the supervised target port
- `tests/update.rs` covers the new `opensymphony update` maintenance flow: skipping `cargo install opensymphony --locked` when the running CLI already matches the newest published release, running the locked install when a newer release exists, refreshing template-managed skill files in place for an existing target repo, and skipping that skill refresh outside a repo that lacks `WORKFLOW.md` plus `config.yaml`
- `tests/memory.rs` covers the first memory workflow: capture dry runs, capsule writes, DuckDB indexing, compact briefs, search, docs-sync dry-run diffs, public/private link handling, OKF lint fixture diagnostics, OKF MCP admin payloads, date-grouped generated memory logs, and Linear archive eligibility gating
- `opensymphony-gateway-schema/tests/gateway_schema.rs` and
`opensymphony-gateway/tests/gateway.rs` cover Codex local readiness rendering
with fake command outputs for installed, logged-out, unsupported, and
permission-denied states. These tests assert that the gateway exposes only
safe status metadata and `codex_cli_login` references, never raw OAuth access
or refresh material.
Focused OKF memory validation for implementation work:
- `cargo test-system-duckdb okf_lint_fixture_reports_errors_warnings_and_info`
verifies OKF lint errors, warnings, info diagnostics, and metadata
preservation for the migration fixture corpus.
- `cargo test-system-duckdb --test memory` runs the CLI-facing OKF fixture test,
MCP `memory.lint` argument coverage for `okf` and `bundleRoot`, generated
`log.md` date grouping, OKF import/export redaction checks, import preflight
failure coverage, documented non-transactional mid-copy import behavior,
source/target overlap rejection, and the rest of the memory integration
suite.
- `opensymphony memory lint --okf <repo-contained-bundle>` is the manual CLI
smoke path for a generated or fixture OKF bundle.
- `opensymphony memory export-okf --visibility public --output <empty-dir>`
followed by `opensymphony memory lint --okf --public-docs <empty-dir>` is the
public export redaction smoke path.
- `opensymphony memory import-okf <repo-contained-bundle>` is the import smoke
path for warning-tolerant OKF bundles with actionable malformed-file errors,
repository-contained sources, non-overlapping targets, and preflighted writes.
The documented post-preflight partial-write regression is Unix-gated because
it uses POSIX directory permissions to induce a deterministic mid-copy write
failure; add a separate Windows-native failure injection before treating that
path as covered on Windows.
Codex ChatGPT subscription smoke testing remains opt-in on trusted local
machines because the final exec probe can consume account quota. The supported
operator sequence is:
```bash
codex --version
codex app-server --help
codex login status
codex --ask-for-approval never exec --sandbox read-only \
"Reply with exactly: CODEX_LOGIN_OK"
```
If login is missing or expired, use `codex login --device-auth`; if the account
has not enabled device-code authorization, enable ChatGPT Settings -> Security
and login -> Enable device code authorization for Codex before retrying.
## 3. Minimum required test coverage by subsystem
## 3.1 Workflow and config
- parse valid `WORKFLOW.md`
- parse the checked-in repository and example `WORKFLOW.md` files
- fail on invalid front matter
- fail on unknown top-level workflow namespaces
- fail on unknown template variables
- resolve defaults and env vars
- fail when an explicitly referenced env token such as `tracker.api_key: $VAR` is unset
- fall back to `LINEAR_API_KEY` when `tracker.api_key` is omitted
- fail when `tracker.active_states` or `tracker.terminal_states` are omitted
- resolve workflow-relative workspace paths and relative OpenHands persistence paths
- resolve bare relative workspace roots against the `WORKFLOW.md` directory
- normalize relative workflow directories first so relative `workspace.root` values still resolve to absolute paths
- reject parent-directory traversal in relative OpenHands persistence paths
- validate `openhands` extension namespace
- leave `openhands.local_server.command` unset when omitted so the runtime-owned local tooling layer resolves the pinned launcher from the OpenSymphony checkout
- resolve `openhands.local_server.command` during workflow loading and honor it only for daemon-managed local supervision
- fail at runtime when `openhands.local_server.command` is configured for external, authenticated, or `local_server.enabled: false` targets
- fail when `openhands.local_server.enabled: false` is configured until the runtime supervisor can honor workflow-owned local-server disablement instead of still deciding launch behavior from the localhost base URL plus pinned tooling readiness
- fail when `openhands.local_server.env` is configured until the runtime supervisor creation path forwards workflow-owned launcher environment variables instead of always using runtime-owned defaults
- fail when `openhands.local_server.readiness_probe_path` is configured until the runtime supervisor launch path consumes workflow-owned probe settings instead of always using `/openapi.json`
- fail when `openhands.local_server.startup_timeout_ms` is configured until the runtime supervisor creation path consumes workflow-owned startup timeout settings instead of always using the supervisor default
- resolve the bundled `examples/target-repo/WORKFLOW.md` file end-to-end, not just parse it
- treat a leading unmatched `---` as prompt body text instead of failing front-matter parsing
- treat leading thematic-break-delimited non-mapping blocks as prompt body text instead of silently dropping prompt content
- fail on malformed, non-`http://`/`https://`, credential-bearing, query-bearing, fragment-bearing, or bracketed-IPv6 `openhands.transport.base_url` values during workflow resolution
- allow `https://` and path-prefixed OpenHands transport base URLs during workflow resolution
- fail when a non-loopback OpenHands transport base URL uses `http://`
- fail when a non-loopback OpenHands transport base URL omits `openhands.transport.session_api_key_env`
- resolve `openhands.transport.session_api_key_env`, `openhands.websocket.auth_mode`, and `openhands.websocket.query_param_name` into the runtime transport config
- normalize unauthenticated path-prefixed loopback OpenHands transport base URLs back to their origin before managed local supervisor startup while preserving configured prefixes for external or authenticated targets
- fail when `openhands.websocket.auth_mode` is invalid or requires a missing session API key env
- fail when explicit `openhands.websocket.enabled` is configured before the runtime readiness path can honor disabling the socket
- resolve `openhands.websocket.ready_timeout_ms`, `reconnect_initial_ms`, and `reconnect_max_ms` into the runtime readiness and reconnect budgets
- reject removed `openhands.mcp` config with a migration error that points users to `LINEAR_API_KEY` and the repo-local GraphQL helper assets
- resolve `openhands.conversation.reuse_policy` for runtime consumers instead of rejecting non-default values during workflow loading
- default required OpenHands conversation request fields such as `confirmation_policy` and `agent`, including `confirmation_policy.kind` when the block is present without an explicit kind
- fail when `openhands.conversation.confirmation_policy` includes options that cannot be represented in the current OpenHands request subset
- fail when `openhands.conversation.max_iterations` exceeds the downstream OpenHands `u32` request range
- fail when `openhands.conversation.agent.log_completions` or extra agent option keys are configured before the runtime conversation-create adapter can forward them
- fail when `openhands.conversation.agent.llm` is present without a non-empty `model`
- fail when `openhands.conversation.agent.llm` includes extra option keys before the runtime conversation-create adapter can forward them
- resolve `openhands.conversation.agent.llm.api_key_env` and `base_url_env` into the conversation-create payload at runtime
- fail when configured `openhands.conversation.agent.llm.api_key_env` or `base_url_env` names are missing or blank in the runtime environment
- fail on malformed `agent.max_concurrent_agents_by_state` entries
- preserve the Markdown body exactly after the front matter terminator
- treat whitespace-only prompt bodies as absent so `DEFAULT_PROMPT_TEMPLATE` still applies
## 3.1.1 Code Graph repository indexing
- exercise the empty-DuckDB gateway flow: repository discovery, target-branch
index, accepted/progress/completed events, nonempty snapshot, baseline
`code.graph.context`, dirty workspace overlay, and cleanup
- verify a dirty cross-module call produces an added edge and module-connection
delta against the configured target branch
- assert the fixture, production HTTP, and Tauri-native adapters return the same
index-report and graph DTO shapes
- bootstrap an empty DuckDB index from the configured target branch and assert
nonzero documents, symbols, and edges for supported source
- keep base and later commits independently queryable, including identical
content hashes
- re-index a changed and deleted path incrementally and verify deletion/stale
membership plus skipped-directory, unsupported-language, and size coverage
- verify target-branch selection when `develop` and `main` point to different
commits; reject client filesystem roots and never execute target-repository
code
- serialize concurrent index requests through one writer and keep reads
available during a background job
- cover gateway and native-command parity for accepted, progress, completed,
unavailable, and failed reports/events
## 3.2 Workspace manager
- sanitize issue identifiers
- refuse path escape
- create and reuse workspace
- persist issue and run manifests
- persist conversation manifests
- persist stable prompt captures plus per-run prompt archives
- persist generated `issue-context.md` and `session-context.json`
- allow fresh `after_create` hooks to bootstrap clone/worktree flows before `.opensymphony/` exists
- retry failed first-time `after_create` hooks on the next `ensure`
- remember a successful first-time `after_create` before later metadata bootstrap steps so clone/worktree hooks are not rerun after a post-hook bootstrap failure
- reject sanitized-key collisions when an existing current-path issue manifest belongs to another issue
- ignore foreign, copied, or undecodable `.opensymphony/issue.json` artifacts when deciding whether first bootstrap already completed
- hook timeout
- kill spawned hook descendants when a timeout fires
- hook stderr capture
- avoid login-shell startup files when launching Unix hooks
- reject symlinked workspace roots during reused-workspace validation
- reject symlink-based `cwd` escapes for hooks
- reject symlinked `.opensymphony` manifest reads and writes
- cleanup on terminal issue state
- revoke worker memory grants at terminal, inactive, and binding-supersession
boundaries
## 3.3 OpenHands adapter
- supervised server startup and shutdown
- HTTP client auth modes
- external server path-prefix probes
- conversation creation
- initial REST sync
- WebSocket readiness barrier
- post-ready reconcile
- reconnect with backoff
- out-of-order event insertion
- terminal state detection
- conversation reuse for `per_issue`
- `fresh_each_run` reset/new-conversation behavior
- runtime rejection of unsupported reuse-policy values
- persisted policy-drift resets
- recovered trigger-pending `/run` retry after a `409 Conflict`
- recovered `409 Conflict` baseline refresh after the previous turn drains
- preservation of untrusted superseded conversations without remote retirement
- condenser replacement evidence persistence and post-retirement clearing
- identifier-derived workspace-key supersession for same-ID tracker changes
- same-harness Codex supersession evidence and harness-specific persistence paths
- prepared Codex recovery without a persisted turn id resumes with `turn/start`
- pinned-server auth success and failure paths
- reuse after an already-active turn or `/run` conflict
- recreation of a missing conversation with persisted history
- **simplified conversation resumption without LLM config drift checks**
- workflow-owned `persistence_dir_relative` mapping
- supervised-mode rejection of foreign ready servers
## 3.4 Orchestrator
- poll candidate sorting
- blocker-aware and hierarchy-aware dispatch eligibility
- claim and release transitions
- max concurrency
- failure retry backoff
- continuation retry at fixed delay
- stall detection
- lightweight active-state refresh cadence
- Linear rate-limit cooldown that does not block worker updates
- terminal cleanup
- restart recovery from manifests
Current repository implementation:
- `tests/scheduler.rs` covers continuation retry, failure backoff, cached per-state dispatch limits across finish/stall/inactive/terminal/reconciliation transitions, runtime-event-fed stall detection, terminal reconciliation with cleanup, Linear read cooldown and cadence, lightweight running-state refresh, and manifest-backed workspace recovery using fake backends. Scheduler unit tests also cover the shorter full-detail refresh cadence for completed parent fan-in
- local restart validation should confirm that `opensymphony run` publishes a recovered snapshot before the first post-restart launch wave, so the TUI issue list repopulates even when reused conversations still take time to attach
- `crates/opensymphony-cli/src/orchestrator_run/backends.rs` covers immediate launch-failure cleanup and abort-on-drop cleanup for tracked runtime worker tasks in the production CLI adapter
## 3.5 Control plane and TUI
- snapshot derivation
- JSON serialization
- streaming update fanout
- read-only client invariants
- pane layout persistence
- event log rendering
Current implemented checks:
- snapshot serialization in `opensymphony-domain`
- parent/sub-issue tracker normalization and issue-ref terminal matching in `opensymphony-domain`
- forward-compatible snapshot decoding for unknown additive recent event kinds in `opensymphony-domain`
- forward-compatible snapshot decoding for unknown additive `daemon.state`, `runtime_state`, and `last_outcome` values in `opensymphony-control`
- control-plane HTTP plus SSE round-trip coverage in `opensymphony-control/tests/control_plane.rs`
- control-plane bootstrap snapshot timeout coverage in `opensymphony-control/tests/control_plane.rs`
- control-plane SSE connect-establishment timeout coverage in `opensymphony-control/tests/control_plane.rs`
- control-plane idle SSE timeout coverage in `opensymphony-control/tests/control_plane.rs`, including retry-in-place reconnect signaling
- control-plane post-disconnect reconnect-timeout reapplication coverage in `opensymphony-control/tests/control_plane.rs`
- control-plane monotonic lag-recovery coverage in `opensymphony-control/src/lib.rs`
- gateway compatibility coverage for `/healthz`, `/api/v1/snapshot`, `/api/v1/capabilities`, and `/api/v1/dashboard/snapshot` in `opensymphony-gateway/tests/gateway.rs`
- `opensymphony run` startup coverage that verifies the configured bind address exposes both health and gateway dashboard routes in `opensymphony-cli/tests/run.rs`
- workflow harness/model selection coverage in `opensymphony-workflow` unit
tests, including `OPENSYMPHONY_HARNESS`, `OPENSYMPHONY_MODEL`, and
`OPENSYMPHONY_MODEL_PROFILE` override resolution
- scheduler route decision coverage in `opensymphony-orchestrator/tests/scheduler.rs`
for Codex selection, environment-sourced selection, and unavailable-harness
failure
- Codex approval bridge coverage in `tests/codex_app_server.rs`, using fake
JSON-RPC approval notifications to prove approval-center DTO mapping and
approval decision audit records
- TUI reducer, visible-focus rendering, selection preservation across reorder, long-list selection windowing, narrow-layout detail budgeting, snapshot coalescing, stale snapshot rejection, post-restart snapshot reset recovery, disconnect retention, and reconnect-to-live recovery coverage in `opensymphony-tui`
## 3.6 Shared client shell (web and desktop remote)
The web and desktop clients both mount the shared `OpenSymphonyApp` shell from `@opensymphony/ui-core` against the same `GatewayTransport` interface, so remote parity is structural. Implemented checks:
- app-shell mount smoke (`packages/ui-core/__tests__/app-shell.test.ts`): status, task graph, run detail, evidence, profile, and failed-connection rendering
- auth-aware placeholder states (`packages/ui-core/__tests__/auth-states.test.ts`): unauthenticated (sign-in), unauthorized (access denied), forbidden (access forbidden), organization/project selection placeholders, and local `auth_modes:["none"]` gateways rendering the dashboard with no login gate; recovery when the gateway later permits a read
- remote web/desktop parity (`packages/ui-core/__tests__/remote-parity.test.ts`): the shell renders the same core dashboard metrics, task graph nodes, run detail, planning workspace, and stream events in both `mode:"web"` and `mode:"desktop"` against an identical fixture transport
- gateway error classification (`packages/api-client/__tests__/gateway-errors.test.ts`): `HttpGatewayTransport` maps HTTP 401/403 (including a 403 with an explicit `error_code:"unauthorized"` body signal) to a classified `GatewayRequestError`, and `authStateFromError` maps it to an `AuthState` from `@opensymphony/gateway-schema`
Code Graph UI validation also covers the real empty-state interaction: the
keyboard-accessible index button, disabled progress state, skipped-file
coverage, retry diagnostics, target-revision/provenance labels, stale and
truncated status, refresh after `code_graph_updated`, and recovery when an
accepted/progress job completes without event delivery. The packaged desktop
smoke must use production adapters; passing only `?fixtures` is insufficient.
Release-sensitive evidence for this surface includes:
```bash
cargo clippy-system-duckdb
npm run type-check
npm run package:release --workspace=@opensymphony/desktop -- --dry-run
```
Run the corresponding bundled-mode `cargo clippy --all-targets -- -D warnings`
and `cargo test` checks before publishing a release bundle.
### Evidence for UI/shell changes
The shell is pure DOM rendered by `renderOpenSymphonyApp` into a `jsdom` document, so the jest suites assert the rendered DOM directly (not mock return values). For the COE-419 auth placeholder states this means concrete runtime evidence of the rendered output:
- `data-opensymphony-app-shell="mounted"` root carries `data-auth-state` set to `unauthenticated` / `unauthorized` / `forbidden` / `open` for each scenario.
- `[data-testid="auth-placeholder"]` is present only in non-open states and carries the matching `data-auth-state`; `textContent` contains "Sign in required" (unauthenticated), "Access denied" plus "do not have permission" (unauthorized), and "Access forbidden" (forbidden).
- `[data-testid="auth-sign-in"]` appears only for `unauthenticated`; `[data-testid="auth-refresh"]` appears for `forbidden`/`unauthorized`; `[data-testid="auth-org"]`/`[data-testid="auth-project"]` render the organization/project selection surface.
- For local `auth_modes:["none"]` gateways, `[data-testid="auth-placeholder"]` is absent and `.os-task-graph-panel` renders with `data-auth-state="open"`.
These DOM assertions are the runtime evidence for the new user-facing states. A screenshot/video capture is not produced in this headless unattended environment; the assertions above exercise the real `renderAuthPlaceholder` / `renderViewContent` code paths end-to-end through the shared shell.
### Captured rendered DOM (real shell, jsdom)
The following is actual captured output from mounting the real shared shell (`renderOpenSymphonyApp`, `mode:"web"`) against a `MockGatewayTransport` that simulates a hosted gateway rejecting the snapshot, plus a local `auth_modes:["none"]` gateway. Reproduce with `npx jest packages/ui-core/__tests__/auth-states.test.ts` (and a temporary DOM-dump harness over `renderOpenSymphonyApp`).
LOCAL `auth_modes:["none"]` gateway (snapshot succeeds):
```
data-auth-state = open
auth-placeholder present = false
task-graph-panel present = true
<section class="os-panel os-task-graph-panel">...<div class="os-empty">No task graph loaded</div></section>
```
Hosted gateway, snapshot rejected with HTTP 401 (`unauthenticated`):
```
data-auth-state = unauthenticated
auth-placeholder present = true (data-auth-state="unauthenticated")
auth-sign-in present = true auth-refresh present = true auth-org/project present = true
task-graph-panel present = false
<section class="os-panel os-auth-panel" data-testid="auth-placeholder" data-auth-state="unauthenticated">
<div class="os-section-head"><h2>Sign in</h2><span>hosted</span></div>
<p class="os-auth-message" data-testid="auth-message">Sign in required to view this OpenSymphony workspace.</p>
<div class="os-auth-actions">
<button data-auth-action="sign-in" data-testid="auth-sign-in">Sign in</button>
<button data-auth-action="refresh" data-testid="auth-refresh">Retry</button>
</div>
<div class="os-auth-scope" data-testid="auth-scope">... Organization / Project selects ...</div>
</section>
```
Hosted gateway, snapshot rejected with HTTP 403 hard deny (`forbidden`):
```
data-auth-state = forbidden
auth-placeholder present = true (data-auth-state="forbidden")
auth-sign-in present = false auth-refresh present = true auth-org/project present = true
<section class="os-panel os-auth-panel os-auth-denied" data-testid="auth-placeholder" data-auth-state="forbidden">
<h2>Access forbidden</h2>
<p class="os-auth-message">Access to this workspace is forbidden.</p>
<button data-testid="auth-refresh">Retry</button>
<div class="os-auth-scope" data-testid="auth-scope">... Organization / Project selects ...</div>
</section>
```
Hosted gateway, snapshot rejected with HTTP 403 carrying `error_code:"unauthorized"` (`unauthorized` permission denial):
```
data-auth-state = unauthorized
auth-placeholder present = true (data-auth-state="unauthorized")
auth-sign-in present = false auth-refresh present = true auth-org/project present = true
<section class="os-panel os-auth-panel os-auth-denied" data-testid="auth-placeholder" data-auth-state="unauthorized">
<h2>Access denied</h2>
<p class="os-auth-message">You are signed in but do not have permission to view this workspace.</p>
<button data-testid="auth-refresh">Retry</button>
<div class="os-auth-scope" data-testid="auth-scope">... Organization / Project selects ...</div>
</section>
```
## 4. Fake OpenHands server requirements
The fake server in `opensymphony-testkit` should emulate the minimum runtime contract:
- `POST /api/conversations`
- `GET /api/conversations/{id}`
- `POST /api/conversations/{id}/events`
- `POST /api/conversations/{id}/run`
- `GET /api/conversations/{id}/events/search`
- `/sockets/events/{conversation_id}`
It should be scriptable enough to produce:
- clean success runs
- tool-heavy runs
- failure runs
- per-request `/events/search` snapshots that differ across initial sync and post-ready reconcile
- per-connection WebSocket frame sequences so reconnect attempts can observe different ready/drop behavior
- late terminal events
- duplicated events
- out-of-order timestamps
- dropped WebSocket connections
- restart and reattach scenarios
## 5. Live local acceptance suite
The live local suite proves the MVP runtime path can execute on a prepared
developer machine against the pinned local OpenHands server.
Implemented entrypoints:
- `OPENSYMPHONY_LIVE_OPENHANDS=1 cargo test --test live_local_suite -- --ignored --nocapture --test-threads=1`
- `OPENSYMPHONY_LIVE_OPENHANDS=1 ./scripts/live_e2e.sh`
Required machine inputs:
- `uv`, `git`, `curl`, and Rust 1.97.1 or newer
- `OPENSYMPHONY_OPENHANDS_MODEL`
- `OPENSYMPHONY_OPENHANDS_API_KEY` for the live `doctor` probe
- the provider environment expected by the pinned OpenHands server for normal
issue-session runs; `scripts/live_e2e.sh` sets `OPENAI_API_KEY` from
`OPENSYMPHONY_OPENHANDS_API_KEY` only when `OPENAI_API_KEY` is otherwise unset
The repository-owned script performs the full live flow:
- runs `opensymphony doctor --config examples/configs/local-dev.with-live-openhands.yaml --live-openhands`
- launches the pinned local OpenHands server on `OPENSYMPHONY_LIVE_SUITE_SERVER_PORT` (default `8010`)
- runs the ignored `live_local_suite` integration tests serially
- writes logs and scenario artifacts under `target/live-local/<timestamp>/` unless
`OPENSYMPHONY_LIVE_SUITE_OUTPUT_ROOT` overrides the root
### Scenario A: checklist-driven issue lifecycle
- generate a temp target repo with repo-owned `WORKFLOW.md`, `AGENTS.md`, and a two-step checklist
- populate the issue workspace through the documented `after_create` clone hook
- run one issue through the real `WorkspaceManager` plus `IssueSessionRunner` path
- verify workspace creation, prompt capture, conversation creation, and a deterministic first-run assistant reply
Expected artifacts:
- `lifecycle/summary.json`
- `lifecycle/workspaces/COE-LIVE-273/notes/live-suite-checklist.md`
- `lifecycle/workspaces/COE-LIVE-273/.opensymphony/conversation.json`
- `lifecycle/workspaces/COE-LIVE-273/.opensymphony/generated/session-context.json`
Expected assertions:
- the first run uses the full workflow prompt
- the first run records the exact assistant reply `run 1: workspace-created`
- `.opensymphony/` manifests and prompt captures exist for debugging
The focused terminal-envelope tests additionally use temporary Git remotes to
prove atomic staged publication, target-branch and non-shallow verification,
clean-worktree enforcement, wrong-remote quarantine, collision-resistant
checkout keys, instruction hashing, and repository-only prompt composition.
The parent execution-root fixture uses three temporary remotes, multiple
children in one repository, an actual squash merge, an actual rebase and
fast-forward merge, and a recorded shallow generation. It proves one non-Git
root, one shared-object worktree per canonical repository, exact target and
provider merge-result reachability, unchanged child HEAD/status/manifest bytes,
and rejection of stale generations, missing ancestor leases, ambiguous merge
evidence, dirty children, wrong remotes, arbitrary handles, changed root
requests, runtime-map target repinning, and symlink escapes. It also proves
checkout-local HTTP transport configuration is rejected before credential
exposure; checkout-controlled process filters, fsmonitor, custom hooks paths,
and conditional includes are rejected before parent verification; retained
`post-checkout` hooks do not run during worktree creation; colliding sanitized
parent identifiers remain distinct; and `after_create` cannot turn a parent
root into a Git repository. It also covers parent `after_create`
receipt/reuse/failure behavior and proves a child-controlled direct or
worktree-conditional fsmonitor executable is rejected without running before
the incomplete parent root is rolled back. Terminal cleanup also unregisters
the real integration worktrees while the parent and source generations still
exist, then removes the parent root and proves the same generation can be
prepared again without a stale Git registration. Scheduler regressions prove
capture acknowledgement, parent preparation before descendant removal,
deepest-first receipt recovery, hook-once behavior, exact-generation
tombstones, partial-directory deletion recovery, on-disk checkout generation
validation, completed-parent capture after restart, higher-owner preservation,
failed/canceled retention, and retry of visible cleanup failures. A lower-level
regression proves the
orchestrator Git command overrides checkout-controlled fsmonitor configuration
and default repository hooks at execution time. Focused
OpenHands and Codex tests bind the same logical `parent_multi_checkout` envelope
while preserving truthful `trusted_host` containment and omitting a leaf runtime
envelope.
The parent launch tests re-read project-set integration instructions after the
lifecycle hook boundary and reject changed bytes before harness attachment.
### Scenario B: conversation reuse
- run the same issue a second time against the same workspace
- verify the default `per_issue` policy reuses the same `conversation_id`
- verify continuation guidance is selected instead of a second full prompt
- verify the second deterministic assistant reply appears only after the reused conversation resumes
Expected artifacts:
- `lifecycle/summary.json`
- `lifecycle/workspaces/COE-LIVE-273/.opensymphony/prompts/last-continuation-prompt.md`
- `lifecycle/workspaces/COE-LIVE-273/.opensymphony/logs/git-status-after.txt`
The `git-status-after.txt` artifact comes from the workflow `after_run` hook, so the suite also
proves that worker finalization is routing through the workspace manager's `finish_run` path.
Expected assertions:
- first and second runs report the same `conversation_id`
- `last_prompt_kind` in `conversation.json` becomes `continuation`
- the recorded assistant replies end with:
```text
run 1: workspace-created
run 2: conversation-reused
```
### Scenario C: WebSocket reconnect
- place a local fault-injecting proxy in front of the pinned server
- drop the first WebSocket connection immediately after the readiness barrier
- verify the client reconnects, reconciles, and still observes terminal completion
Expected artifacts:
- `reconnect/summary.json`
- `reconnect/proxy.log`
Expected assertions:
- the proxy records at least two websocket connections
- exactly one injected drop is recorded
- the terminal runtime status is still reached after reconnect
- the final message history includes `OpenSymphony reconnect probe OK`
## 6. Operations
Operational guidance now lives in [operations.md](operations.md).
That document covers:
- `opensymphony init`, `run`, `debug`, `doctor`, and `rehydrate`
- local operator workflows and validation commands
- doctor scope and live probe behavior
- logging, manifests, and recovery inspection
- version pinning, CI, and local safety posture
## ACP stdio client tests
`cargo test-system-duckdb --test acp` includes the executable
`tests/fixtures/acp_services_peer.py` peer. It exercises line ranges and endings,
invalid UTF-8, missing write parents, traversal/symlinks, oversized content,
capability absence, cross-session rejection, UTF-8 terminal truncation, exit
races, release-before-exit, cancellation/reaping, immutable host policy,
advertised configuration changes and an authenticated scoped MCP HTTP attachment.
These deterministic tests establish client behavior; live harness qualification
is tracked separately in OSYM-906.
Run `cargo test-system-duckdb --test acp` for the executable client contract and
`cargo test-system-duckdb --lib acp` for central configuration coverage. The reusable
`tests/fixtures/acp_peer.py` peer validates initialize/authenticate/new/prompt,
process/session cwd equality, capability honesty, credential exclusion,
interleaved updates and callbacks, opaque string/zero IDs, unknown notifications,
unknown updates and stop reasons, cancellation acknowledgement/deadline, malformed
and oversized frames, EOF/crash, output floods, bounded stderr/evidence, and a hung
process tree. Regressions cover cancellation in every setup phase, pre-cancelled
launches, JSON-escaped prompt overflow, missing update payloads, preservation of
whitespace and long code chunks, ACP profile migration, environment alias
scoping, post-submission authentication errors, and opaque-ID debug redaction. Current-thread Tokio
tests check callback/cancellation responsiveness, bind a new session before an
adjacent response/update pair is dispatched, and saturate callback output while
a peer stops reading stdin. Count and encoded-byte budgets cover successful,
unknown and invalid permission callbacks; sequential round trips verify that
completed transport writes release reservations.
The native ACP peer also verifies `elicitation/create` form accept, decline and
cancel responses, private large numeric peer RPC IDs with generated public
binding tokens, disabled Cursor methods, and form-only
capability advertisement. The production scheduler/gateway fixture routes a
permission and a choice form through HTTP action receipts to the blocked peer.
The extension peer verifies a registered outbound request has the host-bound
session ID and permitted `_meta`, returns a structured result, and rejects
unregistered methods, stale runs, and unexpected argument keys. The peer sends
the operation result immediately before prompt completion; a repeated host
regression verifies all correlated results survive that ordering. Cursor
unit and host fixture tests cover plan and todo request ID `0` without a
peer-supplied session ID, the accepted plan and todo result shapes, mismatched
session cancellation, owner-bound accepted-response todo projection, duplicate
ID ambiguity across plan/todo callbacks, visible saturation failure, and
unknown request behavior.
Two separately ignored manual integration tests exercise the authenticated
pinned CLI through the production `SessionHost` plan operator route and todo
response path. These tests require local CLI authentication and are not CI gates.
The host integration suite also checks that a peer-echoed environment credential
is redacted in both the result value and metadata, and that a second batch of
operations cannot bypass the eight pending-reply limit after the first batch
times out.
The redacted wire frames and production-path qualification are recorded in
[ACP extension qualification evidence](acp-extension-evidence.md).
It uses a five-minute tracker interval and processes both callbacks through
worker-update wakeups without another tracker tick.
An un-routed native form receives protocol cancellation without failing its
turn, and a delayed worker-consume regression verifies that a timed-out
operator answer cannot reach the ACP callback after its failure receipt.
The scheduler retains a live request when the backend response queue is full or
an unconsumed answer expires, allowing a new submission. An output-reservation
test verifies that an operator answer is acknowledged only after the ACP input
sink flushes its response frame, and sink failure fails every queued receipt.
An early-finish native peer verifies that a completed prompt wakes the
scheduler and clears its pending request even if callback closure loses the
race, with tracker polling set to five minutes.
The peer writes its round-trip completion marker by atomic replacement after
closing the JSON file, so marker existence means the payload is readable.
Gateway timeout and handler-drop tests verify that delayed commands cannot
cross the scheduler application fence; a claimed command waits for its actual
acknowledgement. A concurrent reservation test holds one ACP SDK enqueue while
another callback responds and verifies output reservation and enqueue order.
The run-loop wake regression queues a callback notification and an operator
command during a selected tick, verifies that tick completes, and then drains
both queued events. A delayed ACP flush regression verifies that the actor can
tick, process a worker wake, and receive shutdown while the acknowledgement is
pending; the scheduler rejects a duplicate response and applies the eventual
receipt through its own completion path. A malformed permission callback produces no waiting event;
the routed production requests do. The shared web/desktop test retains two
form selections after refresh, submits both answers, and drops a refresh that
fetched the answered request before the successful submission.
Native Unix tests replace the bound workspace root after service creation and
verify file reads, atomic writes, and new terminal cwd remain on the original
directory inode. They also swap a pinned terminal directory for an external
symlink before spawn and verify it reads from the original directory. A narrow
`unsafe_code` allowance wraps child-only `pre_exec` registration for `fchdir`;
the repository lint is `deny`, and the closure performs no allocation, locking,
logging or host cwd mutation. Callback tests cancel a file operation queued behind
a blocked filesystem worker and verify no write occurs. Executable peers exercise
partial staged-write cancellation and atomic replacement on native platforms,
ordinary MCP environment values beside secret grants, JSON-escaped file/terminal
responses against smaller response budgets, generic credential-bearing MCP
header arguments with exact wire delivery and masked evidence, a one-turn
prompt response immediately followed by a denied file write, deferred
model-to-mode selection, and rejection of credentials embedded in MCP URLs.
Retained-owner fixtures reject abandoned-session callbacks adjacent to a missing
restoration response, reapply changed model/mode/options before the next prompt,
and keep cancellation/deadline failures ahead of durable submission.
The retained host also blocks the filesystem worker during the durable submission
checkpoint, cancels the accepted prompt, and verifies that no prompt reaches the
peer and the persisted marker closes as `cancelled_before_prompt`. On macOS,
the normal-completion retained fixture repeats short-lived terminal callbacks
through successive prompts while the full host suite runs in parallel, covering
the natural-exit process-group reap race.
The `acp-windows` CI job runs `python scripts/validation/check-acp-windows.py`
on Windows. Its temporary Cargo harness compiles the production Windows process
owner and verifies descendant termination on normal teardown, parent exit,
wait deadline, and dropped futures. It also executes the shared environment
replacement helper against a real child to verify case-insensitive alias
precedence. The shared Windows callback path validator rejects real junctions
for existing reads, nonexistent writes and terminal directories; pinned-handle
tests attempt directory and leaf swaps during I/O and terminal spawn. Windows SDK
bindings support same-directory stage promotion and deletion by
handle. Two small audited unsafe wrappers use synchronous owned handles and
bounded SDK-layout buffers; native tests verify successful atomic replacement,
original preservation on cancellation and promotion errors, stage/parent rename
exclusion, and deletion after an outstanding write handle closes. The temporary
validation harness uses the same deny-by-default unsafe lint as the root crate.
Dependencies are read from the root manifest. On another host,
`--check-target x86_64-pc-windows-gnu` checks compilation with that Rust target
installed; cross-compilation alone does not prove Windows process behavior.
Run `cargo fmt --check` and `cargo clippy-system-duckdb`; dependency changes also
require bundled-mode validation. Vendor interoperability evidence belongs to the
later live-qualification task and must not be inferred from fake-peer tests.
`cargo test-system-duckdb --test acp_session_host` exercises the retained owner
with executable subprocesses: repeated attempts, concurrent issues, live leases,
idle expiry, cancellation/busy fencing, negotiated load/replay and resume, fresh
nonpersistent reset, durable uncertain-submission refusal and stale generations.
Callback integration covers cancellation followed by a fresh turn on the same
process, stale terminal rejection, live configuration and secret-safe host-policy/
MCP grant compatibility checks. Normal-completion tests send adjacent late file
and terminal callbacks, verify rejection while idle and process reaping before
completion, then start a fresh callback epoch. A permission-policy peer checks
that `allow_once` selects the offered option during a turn and cancels a
permission request adjacent to the prompt result, both with and without an
operator route. A saturated two-slot operator event channel test holds two
`Opened` events until both peer callbacks time out, then requires both matching
`Closed` events to arrive while the prompt remains active. Scheduler tests
verify that closure removes the pending interaction and resumes the idle clock.
Pre-prompt tests reject file and
terminal requests after session binding. File and terminal-output tests verify
exact wire contents with structural redaction in retained history and evidence.
Configuration tests check preparation-frame attribution on success, cancellation
and timeout; MCP tests reject query strings and aliased excluded credentials.
The peer verifies that the submitted marker is already on disk when a prompt
arrives. `cargo test-system-duckdb --lib opensymphony_acp::durable::tests` covers
owner locks, process-group loss, the launch checkpoint gap, compatibility bounds,
identity mismatches and legacy manifests. Workspace and control-plane regression
targets remain required for changes to persistence or the host observation seam.
`cargo test-system-duckdb --test run run_dispatches_acp` exercises the actual CLI
against a fake tracker and ACP executable with an unreachable OpenHands endpoint.
It verifies exact cwd, workspace hooks, scoped memory, persisted profile routing,
public capabilities and distinct plan/context/turn usage activity with absent
counters preserved. `cargo test-system-duckdb --lib acp` covers continuation,
profile switching and dry runs, persisted recovery, permission waiting, safe
setup retry, ten concurrent workers, interrupt/abort, unreadable submission
evidence and known-finished versus uncertain owner-loss cleanup. Use `tests/fixtures/acp_worker_peer.py`
for production worker fixtures. Gateway/schema tests include a shared Rust and
TypeScript capability fixture; native OpenHands and Codex regression suites remain
required. Unset ambient `LINEAR_CLIENT_ID` and `LINEAR_CLIENT_SECRET` for fake
tracker suites so local OAuth configuration does not override fixture credentials.
## ACP live acceptance
[ACP live qualification](acp-live-qualification.md) contains reproducible
commands and redacted outcomes for two independent vendor CLIs through tracked
`opensymphony run` paths. The ignored tests assert workspace edits, Cursor
operator decision and cancellation acknowledgement, plus live Cursor/Devin
`session/load` without prompt resend. `cargo test-system-duckdb --test acp`
covers the Devin-observed pre-response update ordering, authoritative
snapshot, and wrong-session rejection. Keep these manual tests separate from
unauthenticated CI and run the full system-DuckDB and Rust/TypeScript schema
checks for changes to the adapter.
<!-- 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-275: Remote agent-server mode and auth hardening
- COE-277: Implement hierarchy-aware task selection
- COE-278: Doctor live probe resolves repo-local OpenHands launcher paths reliably
- COE-279: Reject or propagate unsupported OpenHands agent option passthrough
- 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-283: Cache per-state running counts in the orchestrator scheduler
- COE-284: Add orchestrator run command to CLI and make it installable
- COE-287: Add opensymphony debug command for conversational session debugging
- COE-288: Add context condenser support to prevent LLM context window overflow
- 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-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-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-554: Restart-Safe Parent Integration Controller
- COE-555: Parent Repair Review And Merge Lifecycle
- COE-556: Bottom-Up Subtree Cleanup And Recovery
- 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-275
- COE-277
- COE-278
- COE-279
- COE-280
- COE-281
- COE-282
- COE-283
- COE-284
- COE-287
- COE-288
- 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-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-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-554
- COE-555
- COE-556
- COE-609
- COE-610
- COE-611
- COE-612
- COE-613
- COE-615
<!-- END OPENSYMPHONY MANAGED MEMORY SYNC -->