Smoke test plan: what's testable on main today #149
Replies: 3 comments
-
|
Walked lanes 1, 4, 11 on an isolated daemon — port What workedLane 1 — Daemon control
Lane 4 — Orchestrator sessions (partial — see "broke" below)
Lane 11 — HTTP API surface
What brokeLane 4.1 — SQLite migration is at version 7 (so not the §3.3 stale-migration footgun), and the Lane 11 — Same opaque-500 pattern (no log detail). For comparison, Lane 1.3 — What was unclear
|
Beta Was this translation helpful? Give feedback.
-
|
Walked lanes 2, 3, 5, 7, 9, 10 on an isolated daemon — port What worked
What broke / discrepancies
What was unclear
|
Beta Was this translation helpful? Give feedback.
-
|
Walked lanes 6 (SCM observer) and 8 (PR claim) on an isolated daemon — port What workedLane 6 — SCM observer
Lane 8 — PR claim
What broke1. §8.2 rollback is incomplete.
2. §6.6 — 3. §6.3 — missing log line. Spec says: with no token, expect 4. 5. Spawn returns opaque
Daemon log shows only the request line + 500 status; no error message. Caller can't tell whether it's a worktree collision, a missing ref, or something else — yet another instance of the "Known issues / What was unclear
|
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
This is a manual smoke-test runbook for what is actually shipped on
maintoday — the lanes the rewrite already exposes end-to-end (daemon, projects, sessions, spawn, SCM observer, agent activity hooks, PR claim, reaper, CDC, HTTP API). It is intended as a 1–3 hour walk-through before more wiring lands, so we can catch lane-level regressions while the surface is still small enough to cover by hand.Anyone is welcome to walk a section, report findings as a reply (what worked, what broke, what was unclear), or call out a capability that should have been listed but isn't.
AO smoke-test checklist — what's testable on
maintodayA manual runbook for validating the AO rewrite end-to-end. Walk the lanes in order — earlier lanes set up state used later. Target wall-clock: 1–3 hours.
CLI shape was captured against the current
main(commitb13f413); flag names are copy-pasteable.0. One-time prerequisites
go≥ 1.22,git≥ 2.25.0 (worktree-capable),zellij≥ the version pinned inbackend/internal/adapters/runtime/zellij,gh≥ 2.0.gh auth logincomplete, ORAO_GITHUB_TOKEN/GITHUB_TOKENexported (needed for SCM observer + claim-pr lanes).originremote points at github.com.claude,codex, oropencode.Build the binary once
Isolated data dir (mirrors the issue-#89 recipe)
Keep this env exported in every shell you use. Use the same
/tmp/ao_smokebinary throughout so the daemon and CLI agree on the schema.1. Daemon control
1.1
ao start{state: "ready", port: 4101, pid: <int>}.cat /tmp/ao-smoke-running.jsonshows the same PID;curl -fsS http://127.0.0.1:4101/healthzreturns{"status":"ok"...};curl -fsS http://127.0.0.1:4101/readyzreturns{"status":"ready"...}.1.2
ao statusstate: "ready", port matches, no error string.running.json.1.3
ao doctorrunDoctor()(backend/internal/cli/doctor.go):config,data-dir,data-dir-write,sqlite,daemon— all PASS.gitPASS (≥ 2.25.0),zellijPASS.claude-codeandcodex— PASS if installed, WARN if not.github-tokenPASS ifgh auth loginorAO_GITHUB_TOKENresolves to a valid token; WARN if neither present.PATH=/usr/bin:/bin /tmp/ao_smoke doctor(stripgit/zellij) → expect FAIL on git, WARN on zellij.AO_GITHUB_TOKEN= GITHUB_TOKEN= PATH=/usr/bin:/bin /tmp/ao_smoke doctor→ expect WARN on github-token with a "no GitHub token found" message.chmod -w "$AO_DATA_DIR"(then revert) → expect FAIL ondata-dir-write.1.4
ao version/tmp/ao_smoke --versionworks.1.5
ao stop/tmp/ao-smoke-running.jsonis absent or marked stopped.kill -0 <pid>returns 1;ao statusreportsnot_running.Restart with
/tmp/ao_smoke start --json --log-file /tmp/ao-smoke.logbefore continuing.2. Project management
2.1
ao project addPre-stage two git repos on disk: a clean clone of your test GH repo (
/tmp/ao-smoke-repo) and a throwaway local-only repo (/tmp/ao-smoke-local,git initthen commit a file).repo(mapped from the internalRepoOriginURLcolumn byprojectFromRow):https://github.com/<owner>/<repo>.gitURL. For the local-only repo it will be"".2.2
ao project ls2.3
ao project get--jsonyou get the full record includingrepoOriginURL.2.4
ao project rmDefer until teardown — sessions in later lanes need these projects.
3. Spawn / session lifecycle
3.1
ao spawn(worker)ws-01. A new worktree at~/.agent-orchestrator/projects/<project>/worktrees/<session-id>/exists and is on branchao/smoke-1.ls $AO_DATA_DIR/ao.dbexists./tmp/ao_smoke session ls --jsonshows the session withkind: "worker"andstate: "active"(or whichever the lifecycle reduces to once the runtime is up).ZELLIJ_SOCKET_DIR=/tmp/ao-zellij-$(id -u) zellij list-sessions— the AO session should be listed.3.2
--agent/--harnessselectionTop-level help shows
--harnessis also documented as--agent. Spawn one of each:session getJSON'sharnessfield).AO_AGENT=opencode /tmp/ao_smoke spawn --project <gh-project-id> --prompt "noop" --branch ao/smoke-env. The daemon's default agent comes fromAO_AGENT(config.go); confirm the spawned session reportsharness=opencode.3.3 Agent registry coverage
Confirm the registry exposes the eight adapters added by #119 and #145 (claude-code, codex, opencode, grok, cursor, qwen, copilot, kimi). The four newest don't ship hook installers; spawning is enough to confirm the registry accepts them.
Binary-freshness precondition. Migration
0007_allow_implemented_harnesses.sqlwidens thesessions.harnessCHECK constraint to include the new harnesses. If/tmp/ao_smokewas built before #119 landed, migration 0007 isn't embedded and all five spawns below fail withINTERNAL_ERRORin <1ms (the daemon log shows only the request line — see "Known issues"). Verify before running the loop:If it's
6, rebuild and restart:3.4
ao session ls--include-terminatedadds any sessions you killed.3.5
ao session getactivity/ state fields — used in lane §8.-p <project>is supported but optional.3.6
ao session renamesession get --jsonshows updateddisplayName. HTTP path isPATCH /api/v1/sessions/{id}.3.7
ao session killsession lsno longer shows it without--include-terminated; zellij session has been destroyed; the worktree directory is preserved (cleanup is a separate step).3.8
ao session restoresession getshows it active again.3.9
ao session cleanupgit -C ~/.agent-orchestrator/projects/<project> worktree listthat pruned ones are gone.4. Orchestrator sessions
4.1 Spawn via API (no CLI shortcut for spawn)
{orchestrator:{id, projectId}}.4.2
ao orchestrator lsGET /api/v1/orchestratorsreturns the same set;GET /api/v1/orchestrators/{id}returns one; querying with a non-orchestrator id returns 404 (SESSION_NOT_FOUND).5. Inter-session messaging (
ao send)5.1 Plain send
zellij attach <session>) shows the message piped to the harness.5.2 PR #85 sender-prefix behavior
The CLI prepends
[from <sender>]whenAO_SESSION_IDis set (seebackend/internal/cli/send.go:46):[from aa-orchestrator] ping. Confirm in the pane.5.3 Validation
--message→ 400 withMESSAGE_REQUIRED.MESSAGE_TOO_LONG.stripUnsafeControlChars).6. SCM observer (issues #76 + #108 + #114 + #115)
6.1 Pre-conditions
repoOriginURLis non-empty inproject get --json.AO_GITHUB_TOKEN,GITHUB_TOKEN, orgh auth token.--branch <pr-head-branch>, or--claim-pr <pr-url>to immediately attach (lane §9).6.2 Discovery + initial nudge
Wait ≥ 30s (default tick =
DefaultTickIntervalinbackend/internal/observe/scm/observer.go:25).zellij attach): a CI-failing observation should send a single CI-failure message to the agent.6.3 No-token graceful no-op
Stop the daemon, unset every token, restart:
scm observer disabled: provider credentials unavailableand observer loop becomes a no-op (o.disabled = true). No nudges fire. Restore the token /ghconfig when done.6.4 Dedup across restart
With a live token and a still-red PR:
/tmp/ao_smoke stop→/tmp/ao_smoke start.CIHash/MetadataHash/ReviewHash).6.5 RepoOriginURL backfill
For the local-only project you registered without origin (lane §2),
repoOriginURLis empty. Add anoriginremote pointing at your GH repo, then spawn a worker on it. The observer'sdiscoverSubjectsrunsgit remote get-url originand backfills + persists the URL (observer.go:451-459).project get <local-project-id> --json | jq .project.reponow matches the configured remote.6.6 Review-thread polling
Pick a PR with at least one unresolved review thread.
DefaultReviewInterval), threads appear viaGET /api/v1/sessions/<id>/pr(reviewComments).resolved. Confirm via the CDC log (§10) — apr_review_thread_resolvedevent lands.7. Agent activity hooks (issue #113, #119)
7.1 Hook config installed in workspace
Spawn a fresh
claude-codeworker, then in the worktree:backend/internal/adapters/agent/claudecode/hooks.go. Entries point atao hooks claudecode <event>.Spawn a
codexworker; expect<worktree>/.codex/hooks.jsonwith similar entries (backend/internal/adapters/agent/codex/hooks.go). Forcursor, expect<worktree>/.cursor/hooks.json.opencodeandgrokhave no native hook config — note "no-op" in your run log.7.2 Activity transitions land in the daemon
From inside an active session, trigger the hook manually (the harness will do this naturally too):
/api/v1/sessions/{id}/activitywith one ofactive|idle|waiting_input|exited.sqlite3 $AO_DATA_DIR/ao.db 'select type,payload from change_log order by seq desc limit 5;'shows a recentsession_updatedevent reflecting the activity column.8. PR claim (#101)
8.1
ao session claim-prSpawn a worker; in parallel, you have an open PR on the test repo.
branchChangedandtakenOverFrom. The worktree's branch may flip to the PR's head branch (branchChanged: true).session get --jsonshows the PR attached;git -C <worktree> rev-parse --abbrev-ref HEADmatches PR head branch.8.2
ao spawn --claim-pr(single-step)session ls --include-terminateddoes not show a leftover. The orchestrator-spawn path rolls back the half-spawned session.8.3
--no-takeoverWith a PR already claimed by an active session, run claim from a different session without
--no-takeoverand expect takeover; rerun with--no-takeoverand expect aPR_CLAIMED_BY_ACTIVE_SESSION409 (seewriteSessionPRError).9. Reaper
9.1 External kill
Spawn a session. From a separate shell:
session ls --include-terminatedshows the session terminated with a reaper-attributed reason;session get --jsonshows the runtime gone. The reaper transitions the row without racing the activity hook (lane §7's single lifecycle.Manager guarantee — seesessions.go:260-263).10. CDC events
10.1
change_logtable directlybackend/internal/cdc/event.go):session_created,session_updatedpr_created,pr_updated,pr_check_recorded,pr_session_changedpr_review_thread_added,pr_review_thread_resolved10.2 SSE replay stream
text/event-streamresponse with the same events, in order, then live updates as you trigger more actions. TheLast-Event-ID/?after=cursor is honored (issue feat(cdc): add SSE event stream replay #106).11. HTTP API surface
Verify each route accepts the documented verbs. Source of truth:
backend/internal/httpd/controllers/{projects,sessions,prs}.goandbackend/internal/httpd/{api,router,events}.go. OpenAPI:GET /api/v1/openapi.yaml./healthz/readyz/shutdown/api/v1/openapi.yaml/api/v1/projects/api/v1/projects/{id}/api/v1/sessionsprojectIdrequired)/api/v1/sessions/cleanup?project=filter/api/v1/sessions/{id}displayNamerequired)/api/v1/sessions/{id}/pr/api/v1/sessions/{id}/pr/claim{pr, allowTakeover})/api/v1/sessions/{id}/restore/api/v1/sessions/{id}/kill/api/v1/sessions/{id}/send/api/v1/sessions/{id}/activitystate∈ active/idle/waiting_input/exited)/api/v1/orchestrators/api/v1/orchestrators/{id}/api/v1/prs/{id}/merge/api/v1/prs/{id}/resolve-comments{commentIds}optional)/api/v1/events?after=<seq>orLast-Event-ID)/muxSmoke them with
curlfor OPTIONS/wrong verb on a couple to confirm the locked envelope: e.g.curl -X PUT http://127.0.0.1:4101/api/v1/projects/abc→ 405METHOD_NOT_ALLOWED; unknown route → 404ROUTE_NOT_FOUND, both JSON.Teardown
Known issues that will distort tests
/tmp/ao-zellij-<uid>(zellij.DefaultSocketDir). If you overrideZELLIJ_SOCKET_DIRto anything deep (e.g. inside$TMPDIR), spawns fail with "session name must be less than 0 characters." Symptom:Create runtimeerrors at spawn time on macOS.checkCredentialsflips the observer todisabledfor the lifetime of the process. Subsequent token availability is not re-detected — restart the daemon after fixing the token, otherwise observer-dependent lanes (§6, §10's pr_* events) will silently produce nothing.INTERNAL_ERRORwith no daemon-log reason —envelope.WriteErrorreturnsINTERNAL_ERRORfor any non-apierr.Errorand does not log the wrapped err. If a spawn/kill/etc. returns 500 in <1ms and the log only shows the HTTP request line, suspect a SQLite CHECK-constraint violation (e.g. stale migration onsessions.harness— see §3.3 binary-freshness check) or another low-level store error. Diagnose viasqlite3 "$AO_DATA_DIR/ao.db" 'SELECT max(version_id) FROM goose_db_version;'and comparing tobackend/internal/storage/sqlite/migrations/.ao hooksexits silently ifAO_SESSION_IDis unset — only run from within an agent process (or set it manually as shown in §7.2).ao session cleanupis a no-op on a worktree with uncommitted changes. Either commit/discard inside the worktree orrm -rfit manually.Not yet testable (designed but not on
main)frontend/is a placeholder; no UI to walk through.notifier-openclaw/slack/webhooklog lines at daemon startup are no-ops until reconfigured.ao plugin,ao events,ao update,ao migrate-storageare intentionally absent onmain; don't test them.How to participate
Pick a lane (§1 through §11). Walk the steps top to bottom. Reply on this thread with:
ao status --json/ao doctor --jsonoutput.Mention which OS, zellij version, and
ao versionyou ran against.Related
rewriteBeta Was this translation helpful? Give feedback.
All reactions