feat(symphony): port tracker + orchestrator (dispatch stubbed)#3
feat(symphony): port tracker + orchestrator (dispatch stubbed)#3
Conversation
Lands the Phase 2 deliverable from
docs/symphoney-legacy/plans/2026-04-30-archon-symphony-consolidation.md.
- Linear + GitHub trackers behind a shared Tracker interface
- Orchestrator with tick loop, slot accounting, per-state caps,
retry backoff. Re-keyed all in-memory state on dispatch_key
('<tracker>:<identifier>') so cross-tracker raw-id collisions
are impossible.
- Config snapshot rewrite: trackers as a list, no agent/codex/claude
blocks (those move to per-workflow YAML in Archon proper).
~/.archon/symphony.yaml.example committed under packages/symphony/.
- dispatchIssue stub: writes a symphony_dispatches row with
workflow_run_id = null and logs symphony.dispatch_skipped. Phase 3
replaces the stub with executeWorkflow.
- Unit + integration tests, including a multi-tracker fixture
(same raw id on Linear and GitHub -> distinct dispatch_keys, both
dispatch, no UNIQUE violation). 41 symphony tests, 0 fail.
- New CLI dev entrypoint: bun packages/symphony/src/cli/dev.ts.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…secrets
The Phase 2 manual smoke surfaced this: symphony.yaml.example uses
$LINEAR_PROJECT_SLUG, $GH_OWNER, $GH_REPO, but only $api_key and $token
were resolved through env-indirection. Non-secret fields were passed
literally to the underlying SDKs ('$LINEAR_PROJECT_SLUG' as a slug → 0
candidates with no error).
Threads `resolveEnvIndirection` (renamed locally to `resolveString`) through
every string field in `buildTracker` and `buildCodebases`: project_slug,
endpoint, repository (Linear), owner, repo (GitHub), and codebase_id /
repository (codebases). Behavior for hardcoded literals is unchanged —
`resolveEnvIndirection` returns the trimmed input when the value is not a
$VAR pattern.
Two new tests in snapshot.test.ts cover the $VAR-everywhere case and the
"env var unset → fall back to default/null" case.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Warning Rate limit exceeded
To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (24)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Review rate limit: 0/1 reviews remaining, refill in 3 minutes and 50 seconds.Comment |
Summary
symphony_dispatchesschema and CRUD. There was no runtime — no Linear/GitHub polling, no slot accounting, no retry, no dispatch path.docs/symphoney-legacy/intopackages/symphony/. NewstartSymphonyService()+bun packages/symphony/src/cli/dev.tsentrypoint.dispatchIssueis a stub that writes asymphony_dispatchesrow withworkflow_run_id = nulland logssymphony.dispatch_skipped. Plus a follow-up commit fixing env-indirection on all tracker fields (surfaced by manual smoke).UX Journey
Before
After (Phase 2 stub)
Architecture Diagram
Before
After
Connection inventory:
Label Snapshot
risk: lowsize: Ldependencies(new package gains 2 npm deps; behavior is package-scoped)symphony:orchestrator,symphony:tracker,symphony:configChange Metadata
featuremulti(new package + new deps; no other Archon packages modified)Linked Issue
Validation Evidence (required)
Ddell12/archon-symphony-smoke-test#1. Ranbun packages/symphony/src/cli/dev.ts ~/.archon/symphony.yaml. Within ~500ms after startup, bothsymphony.dispatch_skippedevents fired (Linear + GitHub).sqlite3 ~/.archon/archon.dbshowed two rows withworkflow_run_id = NULL,status = pending. SIGTERM cleanly stopped the service. Test artifacts cleaned up.$VARconfig; startup log showsprojectSlug: "d0ef0b50e836",owner: "Ddell12",repo: "archon-symphony"resolved from env.Security Impact (required)
https://api.linear.app/graphqlandhttps://api.github.com/repos/{owner}/{repo}/issues(configurable per tracker entry).LINEAR_API_KEYandGITHUB_TOKENare read from env via$VARindirection in YAML; never logged.~/.archon/symphony.yamlis user-managed (gitignored equivalent — not in repo).~/.archon/archon.dbvia the existingIDatabaseadapter.Compatibility / Migration
server,cli,web, etc.) do not import from@archon/symphony.~/.archon/symphony.yaml(new file). Users opt in by copyingpackages/symphony/symphony.yaml.example. No existing config files touched.symphony_dispatchesmigration shipped in Phase 1 (PR Phase 1: scaffold packages/symphony #1, commit 6bc4eea).Human Verification (required)
$VARresolution on non-secret fields. SIGTERM clean shutdown.state_workflow_mapentry →symphony.dispatch_no_workflow_for_statewarn log, no DB write, no claim. Existing dispatch_key on second tick →eligibilityForDispatch"already completed" gate prevents re-insert. Same raw issue id on Linear+GitHub → distinct dispatch_keys, both rows land. Tracker fetch failure on one tracker →Promise.allSettledlets the other proceed.remote_agent_workflow_runs.status, HTTP API, web UI. No real GitHub Actions or Linear automation interactions tested.Side Effects / Blast Radius (required)
@archon/symphonyonly. The package is currently not imported by any Archon-side caller, so merging this is a no-op for the running server/CLI/web.~/.archon/symphony.yaml, Symphony will hit Linear/GitHub APIs every 30s. Logs are loud (tracker_fetch_failed) so this is observable.symphony.service_started,symphony.dispatch_skipped,symphony.tracker_fetch_failed,symphony.dispatch_db_conflict).Rollback Plan (required)
git revert 50ce84c8 e1be19b9ondev. The Phase 1 schema/CRUD is unaffected.bun packages/symphony/src/cli/dev.ts. There is no auto-start.symphony.service_startedlog absent → service didn't boot. Repeatedsymphony.tracker_fetch_failed→ API/auth issue. Repeatedsymphony.dispatch_db_conflict→ DB schema drift.Risks and Mitigations
workflow_run_id. If a user runs the CLI dev entrypoint long-term,symphony_dispatcheswill accumulate.state.completed(in-memory) prevents same-key re-dispatch within one process; the unique constraint blocks duplicates across restarts.graphql-request@^7.2.0,@octokit/rest@^22.0.0).@octokit/rest@^22.0.0already in@archon/adapters;graphql-requestmatches symphoney-codex's pinned version and was the upstream choice for Linear.🤖 Generated with Claude Code