Skip to content

Testing plan: hand a conversation to the-loop from any surface, at any stage ​

Derived from requirements.md and design.md, before tasks.md. Each task's _Test:_ names a row below. This file is executable content: it names commands an agent will run. No credential appears here.

Test matrix ​

Most of the proof is pytest at three levels: unit tests for the parser and hook, scenario tests through the runtime and dispatcher, and abuse-case negatives. A recorded dry run of the skill is the one manual activity. It covers the part no fake can reach: the interview and a real issue.

#TypeApplies?Scope / what it provesWhere it runs
T1Unityescore/handoff.py (parse, render, STAGE_ENTRY, find_record, part splitting); import-handoff hook demotion; JiraClient.create_issue fields; declared_skips requiresHandoff rule; checklist untickingmake test
T2Integration (scenario)yesruntime walk per R6 table row, start to the first approval gate; no-handoff walk unchanged; dispatcher arming reads the record and checks out the spec branch; the-loop handoff import/note; ticket create --issue-type --parent through the API routemake test
T3Contractyesthe CLI API route POST /work-items/tickets and the MCP tool accept the two new optional fields; existing contract tests stay greenmake test
T4End-to-endn/ano environment runs a real poller against a real repo in CI; T11 covers the real-issue path by hand
T5UI / visualn/ano rendered UI changes beyond one checklist line, which T6 covers as text
T6Snapshotyesthe checklist body with a handoff (earlier rows unticked, handoff line) and the rendered handoff record; byte-stable textmake test
T7Performance / loadn/aone extra comment listing per arming of a fresh item; no hot path changes
T8Security / abuse caseyesone negative test per abuse case 1–7 in design.md §Security design, plus path/branch-name validationmake test
T9Accessibilityn/ano new visual surface
T10Migration / upgradeyesa work-item-state.json with none of the new keys loads, walks and archives unchanged; the graph compiles with the new node and edges; make validate passesmake test, make validate
T11Manual exploratoryyes, replanned to partial (owner's call, comment)the network half against real GitHub on a scratch issue: post a record with parts, read it back through the branch's parser, verify hashes and authorization. The interview and the live poller pick-up move to the owner's check at human-approval: a daemon-spawned session has no question tool, and the running daemon is the released versionprocedure below, scratch issue
T12Static checksyeslint, format, types, markdown lint over the new skill and docsmake check

Scenarios & requirement trace ​

RowRequirement(s)Scenario / case
T1R5.1, R5.5parse/render round trip; unknown version → None; unknown key → None
T1R6 tableSTAGE_ENTRY returns each row's starting step, with and without testing-plan.md
T1R5.2a body over 65,536 characters splits into parts, none truncated, rejoined byte-equal
T1R7.3, R7.5demotion un-skips the producing node and later skips only; no file verifies → brainstorming un-skipped
T1R3.4create_issue(issue_type="Story", parent_key="PROJ-1") sends issuetype and parent
T1R7.1requiresHandoff node skipped with via: no-handoff when state has no handoff
T2R6.1, R6.3, R6.4Scenario: a requirements-settled handoff walks to requirements-approval
T2R6 tableScenario: a brainstorm-settled handoff walks to brainstorm-approval
T2R6 tableScenario: an exploring handoff walks to brainstorming
T2R6 tableScenario: a design-settled handoff with a testing plan walks to design-approval
T2R6 tableScenario: a design-settled handoff without a testing plan walks to test-planning
T2R7.1Scenario: an item with no handoff walks exactly as before
T2R7.3Scenario: a requirements.md missing Security considerations demotes to requirements-definition
T2R6.5Scenario: a brainstorm carried under requirements-settled is locked as approved by the handoff
T2R6.2Scenario: arming a handed-off item checks out its spec branch
T2R5.4Scenario: handoff note points the record at the committed files and PR
T2R7.4Scenario: an imported spec-chain artifact URL is recorded and rendered in graph context
T2R3.4, R3.5Scenario: a Jira copy is created with issue type, parent and the mirror label
T3R3.4route and MCP tool accept issueType and parent; omitted → today's request
T6R6.4checklist snapshot for a requirements-settled handoff
T6R5.1record snapshot for each carrier (branch, ticket, artifact)
T8Abuse 1Scenario: a handoff record from an unauthorized user is ignored
T8Abuse 2Scenario: a handoff record entering implementation is rejected
T8Abuse 3, 6Scenario: a record posted or edited after the walk started changes nothing
T8Abuse 4Scenario: a carried file whose hash does not match is refused
T8Abuse 5an artifact body with agent-directed text is written verbatim and changes no state
T8Abuse 7Scenario: arming a Jira mirror is refused
T8Security designa part comment by another author is ignored; a branch outside the-loop/ or failing check-ref-format is refused; an artifact name outside the closed set is refused
T10Compatibility NFRlegacy state fixture loads and archives; make validate
T11R1, R2, R4, R5, R8manual procedure below

Verification environment ​

  • Repositories: this repo only. T11 uses a scratch issue in this repository, closed afterwards, and a branch under the-loop/ deleted afterwards.
  • Services / containers: none for T1–T10. Tests use the existing GitHub and Jira fakes (cli/tests/jirafakes.py and the dispatcher fixtures).
  • Fixtures & data: new fixtures under cli/tests/fixtures/handoff/: one record per carrier, artifacts for each R6 row, a malformed requirements.md, and a legacy state file.
  • Credentials: by reference only. T11 uses the operator's existing gh authentication and the daemon's configured GitHub token (cli-config.yaml variable name). No Jira credentials: T11 does not create a Jira copy, and T2 covers that path with the fake.
  • Bring-up: make install-dev · Tear-down: none (T11: close the scratch issue, delete the branch).
  • If bring-up fails: record it under Verification results, leave the dependent activities unticked, and escalate.

T11 procedure.

  1. In a checkout, discuss a small fake feature with Claude, then run /the-loop:handoff.
  2. Pick requirements settled and queue it, and confirm.
  3. Check that the issue, record and draft PR exist and every link resolves.
  4. Post the-loop start, then confirm the checklist shows earlier phases unticked and the handoff line.
  5. Reply the-loop execute.
  6. Confirm the-loop check shows skipped by handoff and the pointer reaches requirements-approval after import-handoff.

Evidence plan ​

RowEvidencePath under evidence/
T1–T3, T6, T8, T10pytest summary, plus the list of new test ids per rowtests.md
T2, T8scenario table from the-loop scenarios --format markdownscenarios.md
T10make validate outputtests.md
T11redacted transcript of the interview and confirmation; links to the scratch issue, record and PR; the-loop check outputmanual-handoff.md
T12make check summarytests.md

Verification activities ​

  • [x] T1, T2, T3, T6, T8, T10 — make test
  • [x] T10 — make validate
  • [x] T12 — make check
  • [x] T2/T8 scenario table — uv run the-loop scenarios --format markdown
  • [x] T11 (replanned to partial, see the matrix) — scratch-issue round trip

Verification results ​

Run on 2026-10-22 against branch the-loop/issue-517-handoff.

ActivityCommand / procedureOutcomeEvidence
T1, T2, T3, T6, T8, T10make test, plus the issue-517 test files on their own321 issue-517 tests pass. The full suite has 6666 passing and 22 failing, all 22 environment-only: they fail identically on main on this machine, while CI on main is greentests.md
T10make validatePasstests.md
T12make checklint, markdownlint, format, pyright (0 errors) and validate pass; tests as abovetests.md
T2/T8 scenario tableuv run the-loop scenarios --root . --format markdownAll 17 planned Scenario: titles presentscenarios.md
T11 (partial)the-loop handoff post on scratch issue #520, then a read-back through find_record / collect_parts / extract_filesRecord and part round-trip byte-equal with hashes verified; honoured for an authorized author, ignored otherwisemanual-handoff.md

Not executed: two parts of T11.

  • The interview. This daemon-spawned session has no AskUserQuestion (issue-426), and the skill refuses to interview in one (R2.10).
  • The live poller pick-up. The running daemon is the released 20.8.0, not this branch.

Both are covered in-process by the T2 walk and dispatcher scenarios. Replanned on the owner's call (B): T11 is the partial scope that ran, and the interview and live pick-up are the owner's check at human-approval.

Review comments ​

Appended by the-loop's record-feedback hook when a human gate approves with comments (issue-109). Append-only and attributed.

2026-10-21 — approved ​

@MadaraUchiha-314 wrote:

approved

Released under the MIT License.