Imported from azhry/my-harnesses (
agent-spec-ops/AGENTS.md). Install upstream withnpx skills add azhry/my-harnesses --skill agent-spec-ops. Copyright stays with the author.
Agent Spec Ops Instructions
Use this harness to manage delivery state. Do not treat a human prompt as a direct coding command while a run is active.
Evaluation is not passive. If the user asks to evaluate, inspect, review, or diagnose a run/session, also apply safe harness/project instruction fixes for confirmed root causes before reporting. Only stop at evaluation when the user explicitly says "evaluate only" or the fix needs approval or would touch unclear product scope.
Default/freeform OpenCode build or general sessions are not harness
orchestrators. If a prompt was not launched through /agent-spec-spawn or
@agent-spec-orchestrator, stop and ask the user to restart through the
harness command/agent before planning, spawning, editing, submitting, or
merging.
For Linear status disputes, session evaluation, or "is this still backlog/in
progress/done?" checks, run node scripts/sync-linear-task.js runs/<DELIVERY_ID>/workflow-state.json --audit and trust that issue-by-issue
report. Do not hand-roll Linear GraphQL filters in agent chat; they miss
paginated issues, stale ids, project filters, and active tasks.
For Codex session reviews, run node scripts/audit-codex-sessions.js --match <PROJECT_OR_RUN_MARKER> --state runs/<DELIVERY_ID>/workflow-state.json before
changing the harness. Treat repeated findings as harness defects to fix, not as
one-off agent mistakes.
Required Start
node scripts/read-context.js runs/<DELIVERY_ID>/workflow-state.json --role <ROLE>
node scripts/read-instructions.js runs/<DELIVERY_ID>/workflow-state.json --role <ROLE>
Use transition scripts. Do not edit workflow-state.json status fields by hand.
Real run state is sealed by trusted harness writers. If context recovery or
state validation reports an integrity failure, stop and repair before
continuing.
Do not declare the whole project complete or set a Linear project to Completed
just because task issues are done. implementation_review approves a delivery
slice only. Closing a run requires explicit human completion approval recorded
with record-completion-approval.js; otherwise, remaining scope routes back to
task_breakdown.
If the user provides Linear/GitHub credentials for a run, write them only to the
run secret env file with record-run-secrets.js. Never store raw tokens in
workflow-state.json, events, logs, docs, or prompts:
node scripts/record-run-secrets.js runs/<DELIVERY_ID>/workflow-state.json --set LINEAR_API_KEY=<value>
node scripts/record-run-secrets.js runs/<DELIVERY_ID>/workflow-state.json --set GITHUB_TOKEN=<value>
Compact Flow
intake
-> tool_readiness
-> knowledge_discovery
-> product_requirements
-> product_review
-> design_assembly
-> system_rules
-> system_rules_review
-> task_breakdown
-> implementation_in_progress
-> implementation_review
-> done
Human Gates
product_review: pass ->design_assembly; fail ->knowledge_discovery.system_rules_review: pass ->task_breakdown; fail ->design_assembly.implementation_review: pass ->done; fail ->implementation_in_progress.- User asks for rework:
task_breakdown.
Task Breakdown
Create Linear tasks only. Each task needs description, lane, role, scope,
dependencies, definition of done, verification/test plan, and MR description.
Record new task entries with record-task-breakdown.js; do not write temporary
scripts or edit workflow-state.json directly to mutate task_graph.tasks.
After recording tasks, run sync-linear-task.js --create.
Implementation
Delivery WIP is exactly one task. Dev and test are separate agents handing off
the same task; no second task may start until the first is verified, merged,
and confirmed synchronized to Linear. Same-account/admin merge and protected
checks are controlled by implementation.git_policy:
frontend_dev -> frontend_test(record-test-results) -> submit-task(push/PR/admin-merge if allowed) -> verified/Linear sync
backend_dev -> backend_test(record-test-results) -> submit-task(push/PR/admin-merge if allowed) -> verified/Linear sync
If test fails, return to dev. If the dev/test loop reaches 3 attempts, stop and tell the user what failed.
Default build/general sessions and orchestrator must not start dev servers,
background daemons, Cypress, Playwright, or full test suites. Test agents must
use bounded task-scoped commands; on timeout, hang, or first failing run, record
failed evidence and return to dev instead of rerunning full suites.
Use run-task-command.js for task build/test commands; it enforces a maximum
120-second timeout and records pass/fail/timeout evidence in workflow state.
Local browser E2E must be visible/headed by default so the user can watch. Use
headless only in CI, when the user explicitly asks, or for a final artifact-only
check; if visible mode is unavailable, stop and report it.
Hard gates:
- Orchestrator cannot write project files or run dev/test directly.
- Project writes require
check-write-scope.jswith the matching active role. - Worker sessions should pass
--agent-id(or setAGENT_SPEC_OPS_AGENT_ID) when runningcheck-write-scope.js; superseded workers must stop before writing project files. - Task transitions require a recorded spawn lease from
record-agent-spawn.jswith the exactagent-spec-*OpenCode agent name. implementedrequires scoped changed files and implementation evidence.- Test results require
testingstatus and a matching test-agent lease. verifiedrequires changed files, tests, branch, push, MR URL, passed MR status comment URL, and merged MR evidence. MR check evidence is required only whenauto_merge_requires_checks=true.review_required_before_merge=truerequires an independent matching test-agent review recorded byrecord-pr-review.jsagainst the exact submitted HEAD before merge.allow_same_github_account_review=trueandallow_admin_merge=trueauthorizesubmit-task.jsto use same-account/admin GitHub merge when normal merge is blocked by repository review protection.- Every task transition synchronizes Linear synchronously. A failed or timed-out sync exits non-zero and blocks the next task.
- Do not run raw
gh pr merge; usesubmit-task.jsso the run policy decides whether protected checks/reviews are required or admin merge is allowed. record-test-results.jsrecords tests and MR status comments only; dev-task MR check/merge evidence must come fromsubmit-task.js.submit-task.jsrefuses unrelated dirty files.seal-state.jsis trusted manual repair only. It refuses invalid workflow data and must not be used as normal recovery.
Test Execution Enforcement
Never claim tests pass without showing command output. Never claim E2E works without running the test suite. "Created test file" ≠ "tests pass."
Before recording test results with record-test-results.js:
- Actually run the test command and capture its output.
- Verify the output contains explicit pass/fail counts (e.g. "32 tests passed", "0 failing") or a zero exit code.
- For E2E tests (Cypress/Playwright): verify the dev server and any required
backend are reachable before running. Use
node scripts/check-e2e-preflight.jsor manually checkcurl localhost:<port>/api/health. - Pass the actual command output to
record-test-results.js --output "<output>". - If tests fail, transition to
failedand return to dev. Do not rerun full suites; capture the first failure evidence and stop.
Subagent Output Validation
After a subagent returns "completed", the parent must verify before accepting:
- Run
git diff --statto confirm files actually changed. - If the subagent claimed tests pass, require the actual test command output.
- If no files changed and no evidence was recorded, treat the subagent as failed and re-dispatch with clearer instructions.
- Never accept "completed" with empty output or no harness evidence.
E2E Testing Workflow
For tasks requiring Cypress/Playwright E2E tests against a running app:
- Start the dev server in the background:
npm run dev & - Wait for it to be ready (health check or port open).
- If backend is required, start it and verify health endpoint.
- Run E2E tests with
run-task-command.js(bounded timeout). - Record results with
record-test-results.js. - Stop background servers after tests complete.
Do not claim E2E tests pass without completing this sequence. If any prerequisite is unavailable, record a blocker and stop instead of fabricating results.
Commands
node scripts/transition.js runs/<DELIVERY_ID>/workflow-state.json <NEXT_STATE> "reason"
node scripts/record-task-breakdown.js runs/<DELIVERY_ID>/workflow-state.json --file runs/<DELIVERY_ID>/task-breakdown.json --dependencies-checked
node scripts/transition-task.js runs/<DELIVERY_ID>/workflow-state.json <TASK_ID> <STATUS> "reason"
node scripts/plan-agent-dispatch.js runs/<DELIVERY_ID>/workflow-state.json --enable-auto
node scripts/record-agent-spawn.js runs/<DELIVERY_ID>/workflow-state.json <REQUEST_ID> <REAL_OPENCODE_SESSION_ID> --agent <AGENT_NAME>
node scripts/record-run-secrets.js runs/<DELIVERY_ID>/workflow-state.json --set LINEAR_API_KEY=<value> --set GITHUB_TOKEN=<value>
node scripts/check-write-scope.js runs/<DELIVERY_ID>/workflow-state.json <TARGET_PATH> <ROLE>
node scripts/check-e2e-preflight.js runs/<DELIVERY_ID>/workflow-state.json [--frontend-port 3000] [--backend-port 8080] [--skip-backend]
node scripts/audit-codex-sessions.js --match <PROJECT_OR_RUN_MARKER> --state runs/<DELIVERY_ID>/workflow-state.json
node scripts/sync-linear-task.js runs/<DELIVERY_ID>/workflow-state.json --audit
node scripts/record-test-results.js runs/<DELIVERY_ID>/workflow-state.json --task <TASK_ID> --status passed --role <TEST_ROLE> --command "<COMMAND>" --output "..." --require-output --mr-comment-url "<URL>"
node scripts/record-pr-review.js runs/<DELIVERY_ID>/workflow-state.json <TASK_ID> --status passed --role <TEST_ROLE> --summary "review summary" --evidence "review evidence"
node scripts/run-task-command.js runs/<DELIVERY_ID>/workflow-state.json <TASK_ID> --role <ROLE> --label "task-scoped check" --timeout-ms 120000 -- <executable> [args...]
node scripts/submit-task.js runs/<DELIVERY_ID>/workflow-state.json <TASK_ID> --commit-msg "feat: <TASK_ID>: summary" --test-command "<OPTIONAL_RECHECK_COMMAND>"
node scripts/reopen-delivery.js runs/<DELIVERY_ID>/workflow-state.json "reason"