Language: English | Chinese
This guide is for maintainers and AI agents working inside this repository. It focuses on live Supervisor, Telegram, Runtime Deck, and delivery debugging.
Respect the operator's configured target. SymHarix can create issues, branches, PRs, comments, and tracker state transitions in the routed repository.
Before any live test, check:
rg -n "SYMHARIX_TRACKER_PROJECT_SLUG|repositories:|routing:|github_owner|github_repo" .env WORKFLOW.mdExpected shape:
Linear project slug: sample-project
GitHub repo: acme/demo-app
Only run live verification against a repository where automated issues, branches, PRs, comments, and cleanup are allowed.
SymHarix is a self-hostable control plane with a Telegram-first Supervisor.
- Telegram is the main clarification and approval surface.
- Runtime Deck is the diagnostics and control surface.
- Linear and GitHub are records and delivery surfaces.
- Runtime issue detail and Mini App history are the best place to inspect persisted agent-run usage, replay summaries, active PR context, and file diffs.
- Multi-repo context is explicit: Telegram can list configured routes, switch the chat default project, and read a named repo through the read-only advisor.
- Orchestrator owns dispatch, retry, dev/review handoff, delivery cleanup, and repair.
- OpenCode execution runs through
scripts/opencode-adapter.cjs.
The Supervisor is not just a model call and not just an OpenCode process. It is durable session state plus optional LLM and read-only repo-understanding paths.
Preferred local path:
bun run setup
bun run startStop:
bun run stopUse another port only when 3000 is busy:
PORT=4000 bun run start
PORT=4000 bun run healthIf startup behaves strangely, inspect before changing code:
bun run health
curl http://localhost:3000/api/v1/runtime/overview
curl http://localhost:3000/api/v1/bots/manifestFor Telegram, verify:
data.transports.telegram.healthdata.transports.telegram.webhook_urldata.transports.telegram.public_base_urldata.transports.telegram.mini_app_base_urldata.transports.telegram.webhook_pending_update_countdata.transports.telegram.webhook_last_error_message
If Telegram replies but the local manifest has an empty webhook URL, another bot process or deployment may be answering with the same token.
If the public base URL is a temporary trycloudflare.com address, treat HTTP 530, stale webhook URLs, DNS errors, and repeated pending updates as tunnel-layer failures first. Let start recover the tunnel before changing application code.
For Telegram-first Supervisor behavior, use attach mode:
bun --env-file=.env run src/cli/index.ts verify-live-supervisor \
--project-slug sample-project \
--server-url http://localhost:3000 \
--telegram-chat-id <chat-id> \
--matrixThe verifier must enter through Telegram webhook/session logic. Creating issues directly through Runtime API does not validate Telegram-first behavior.
Expected live flow:
- Telegram request arrives.
- Bot quickly ACKs.
- Supervisor creates or resumes one root session for the chat.
- Plan Card or direct answer appears.
- Approval materializes work when needed.
- Root issue remains the user-facing thread.
- Child issues run sequentially when a split plan is approved.
- Telegram receives high-signal updates only.
When something breaks, classify the layer before patching:
- Process/lease: stale local service, occupied port, primary lease conflict.
- Webhook ingress: Telegram did not reach local service.
- Telegram transport: callback ACK, card edit, sendPhoto/sendMessage, Mini App URL.
- Supervisor session: stale active session, missing approval, wrong repo context.
- Orchestrator: issue materialization, dispatch, retry, governance.
- Dev agent: adapter startup, workspace path, Anthropic key, branch drift.
- Delivery: PR, tracker transition, issue close, cleanup.
- Delivery blocker: proof is satisfied, but merge or final delivery failed, commonly
delivery_code=merge_blocked.
Check:
/api/v1/bots/manifest- webhook diagnostics
- tunnel/public URL reachability
- stale
trycloudflare.compublic base URL - callback audit logs
bot_transport_events
Classify:
- webhook did not arrive
- callback parsed but ACK failed
- ACK succeeded but async execution failed
- execution succeeded but card edit failed
Inspect:
sqlite3 symharix.db "select source, action, result, message_id, material_key, created_at from bot_transport_events order by id desc limit 30;"
sqlite3 symharix.db "select * from bot_followup_delivery_states order by updated_at desc limit 20;"
sqlite3 symharix.db "select * from bot_followup_message_states order by updated_at desc limit 20;"Prefer fixing persisted material-key or delivery-state logic over adding another in-memory guard.
Inspect:
sqlite3 symharix.db "select id, state, transport, conversation_id, repo_ref, root_issue_id, updated_at from supervisor_sessions order by updated_at desc limit 20;"The user-facing UX should offer clear choices:
- continue current thread
- cancel current thread
- new thread
Check repo understanding:
sqlite3 symharix.db "select repo_ref, local_path, commit_sha, status, summary, error, updated_at from supervisor_repo_understandings order by id desc limit 20;"If missing or failed, verify:
- chat default project
WORKFLOW.md -> repositories.routing- route local path or source cache
SYMHARIX_SUPERVISOR_REPO_UNDERSTANDING_COMMANDSYMHARIX_SUPERVISOR_READONLY_ADVISOR_COMMANDbun run runtime:checkfrom this checkout- readable repository path and valid Git
HEAD
Repo understanding is read-only. It should improve conversation and recommendations, but must not create issues or edit code before a Plan Card is approved.
Check configured routes and chat preference before changing code:
rg -n "repositories:|routing:|github_owner|github_repo|SYMHARIX_TRACKER_PROJECT_SLUG" WORKFLOW.md .envIn Telegram, ask for available repositories or switch explicitly:
What repositories are configured?Switch to sample-projectSwitch to acme/demo-appWhat does the test2 repo do?
The resolver accepts project slug, full owner/repo, or repo name. If a route is missing, the system should fail closed instead of guessing.
True runner path:
Orchestrator -> AgentRunner -> scripts/opencode-adapter.cjs -> pinned anomalyco/opencode runtime
Check:
agent_runner.commandinWORKFLOW.md, or legacycodex.commandANTHROPIC_API_KEY- local workspace path
- branch/source-of-truth mismatch
- compact dev context size
- OpenCode process startup stderr
Do not assume code evidence means delivery completed.
Check:
delivery_codedelivery_summary- active PR number
- PR head branch
- GitHub issue mapping
- tracker state conflict recovery
- orphan repair logs
If delivery_code=merge_blocked, treat it as a delivery blocker, not as failed review proof. Open the active PR, inspect the merge failure, then retry or supersede after the blocker is resolved.
Stop first when a run is confused:
bun run stopRepair local bot/GitHub residue:
bun src/cli/index.ts repair allIf a test repo was polluted by live verification, clean it deliberately:
- close open PRs and issues
- delete non-main branches
- remove local workspaces for that repo
- cancel corresponding Linear test issues
- cancel or archive local Supervisor sessions/jobs for that repo
Never run destructive cleanup against the wrong repository.
Run:
bun run test
bun run build
git diff --checkFor Telegram/Supervisor behavior, also run or schedule:
bun --env-file=.env run src/cli/index.ts verify-live-supervisor \
--project-slug sample-project \
--server-url http://localhost:3000 \
--telegram-chat-id <chat-id> \
--matrixIf live verification fails, summarize by evidence:
- exact issue/session/message ids
- first failing transition
- observed logs or DB rows
- delivery code and summary
- failing layer