Skip to content

<!-- Authored per the the-loop:writing skill. -->

Testing plan: the clause reader stops at the phases; the close path waits for the endgame ​

Derived from bugfix.md and design.md. Planned at test-planning, results recorded at verification (below).

Test matrix ​

#TypeApplies?Scope / what it provesWhere it runs
T1Unityesstrip_signature (same line, own line, mention form, plain, absent); without_clause with a same-line signature, markup-wrapped names and numbers, a zero-width space, the second-line signature (unchanged); apply_without's 3-tuple, reasons and the position-naming refusal; the hostile-name rule still holdscd cli && uv run pytest tests/test_channels_verbs.py tests/test_selection_control.py
T2Integration (scenario, Gherkin-docstringed)yesthe typed reply through process_reply: a signed execute without capability-docs freezes the selection; a refused reply drops as unknown-phase with read on the record and the mirrored refusal; a protected phase stays unskippable-phasecd cli && uv run pytest tests/test_selection_control.py
T3Integration (scenario, Gherkin-docstringed)yesthe real Dispatcher over FakeTmux and a stub graph link: a closure at the terminal node is deferred (record live, harness not ended, session.closing); the completion claim ends the grace early (finished: true); the deadline ends it (finished: false, waited_seconds); a pointer off the terminal node, a dead pane, an unreadable graph or finishGraceSeconds: 0 close at once; a reopen cancels; a duplicate close is a no-op; merged: true on an issue closure whose PR merged; the sweeper thread finishes a pending closure on its owncd cli && uv run pytest tests/test_finish_grace.py
T4Contract (schema parity)yesthe authored and packaged cli-config.schema.json copies agree on finishGraceSeconds; TmuxConfig.from_mapping reads itcd cli && uv run pytest tests/test_schema_parity.py tests/test_routing.py -k "tmux or schema"
T5UnityesGraphContext.terminal / delivered_by_merge from a real runtime state (test_graph_drive.py)cd cli && uv run pytest tests/test_graph_drive.py
T6End-to-end (live)no — the live Slack run is the operator's next run (run 4); this PR's read field and info log are what that run reads if P1 recurs
T7UI / visualn/a
T8Snapshotn/a — refusal text asserted directly (T1/T2)
T9Security / abuse caseyesa <!channel>, @here, 60-char or design;rm -rf / item is still refused without echo; read never carries a non-token item's text; a state file that cannot be read closes at oncewith T1, T2, T3
T10Accessibilityn/a
T11Migration / upgraden/a — one additive key with a default; no state change
T12Manual exploratoryno — deferred to run 4
T13Regression (full suite)yesevery suite stays green; ruff, ruff format, pyright, markdownlint, validate_configcd cli && uv run pytest -q · make lint format-check typecheck validate

Scenarios & requirement trace ​

RowRequirement(s)Scenario / case
T1R1.1execute without capability-docs *Sent using* @Claude → ["capability-docs"]; … <@UCLAUDE> and … Sent using Claude alike; …\n*Sent using* @Claude unchanged
T1R1.2without *5*, _design_ plus a backticked 2 → ["5", "design", "2"]; a capability-docs carrying U+200B → capability-docs
T1R1.3, R1.4apply_without(rows, ["design", "*Sent"]) → composed "", a refusal opening that name (word 2 after without), reason unknown-phase; ["security-review"] → unskippable-phase; [] → empty-clause; ["9"], ["desgin"] → unknown-phase
T2R1.1, R1.4, R1.5Scenario: a signed execute-without freezes the selection — the record is the checklist with the phase unticked; Scenario: a non-token word refuses with its position and the drop names what was read — outcome unknown-phase, read == ["design", "<non-token: 5 chars>"], one mirrored comment
T3R2.1Scenario: the issue closes while the session is at its terminal node — session.closing emitted, registry record still live, tmux.terminated == [], no stamp
T3R2.2Scenario: the session claims graph complete during the grace — the next sweep closes: record closed, harness terminated, stamp present, session.autoclosed finished=true
T3R2.2Scenario: the grace expires — sweep_closing(now=deadline+1) closes with finished=false, waited_seconds ≥ grace
T3R2.3Scenario: the pointer is on implementation / the pane is dead / the graph is unreadable / finishGraceSeconds: 0 — closed at once, no session.closing
T3R2.4Scenario: reopened during the grace — pending entry gone, session.closing_cancelled, record live; Scenario: a second close arrives — one pending entry, one session.closing
T3R2.5Scenario: an issue closes after its PR merged — session.autoclosed merged=true
T3R2.1, R2.2Scenario: the sweeper thread finishes a pending closure — close_sweep_interval_seconds lowered; the record closes without the test calling sweep_closing
T4R2.2both schema copies carry finishGraceSeconds with default 300; TmuxConfig.from_mapping({"finishGraceSeconds": 12}) reads 12.0
T5R2.1, R2.5a runtime at its terminal node reports terminal=True; after complete it reports status == "complete"; a state with a merged PR reports delivered_by_merge=True
T9securitythe hostile-name test unchanged; read for <!channel> is <non-token: 10 chars>

Verification environment ​

  • Repositories: this repo only.
  • Services / containers: none; no tmux (the FakeTmux double), no network.
  • Fixtures & data: the existing CHECKLIST fixture, make_dispatcher / FakeTmux, a stub graph link returning a GraphContext per scenario.
  • Credentials: none.
  • Bring-up: uv sync · Tear-down: none.
  • If bring-up fails: record under Verification results, leave the rows unticked.

Evidence plan ​

RowEvidencePath under evidence/
T1, T2, T3, T4, T5, T9test names and run output, red → green notedautomated-tests.md
T13full-suite, lint, format, typecheck, markdownlint, validate outputautomated-tests.md

Verification activities ​

  • [x] T1 + T9 — cd cli && uv run pytest -q tests/test_channels_verbs.py tests/test_selection_control.py
  • [x] T2 — cd cli && uv run pytest -q tests/test_selection_control.py
  • [x] T3 + T9 — cd cli && uv run pytest -q tests/test_finish_grace.py
  • [x] T4 — cd cli && uv run pytest -q tests/test_config_schema_parity.py tests/test_finish_grace.py -k "schema or grace_seconds"
  • [x] T5 — cd cli && uv run pytest -q tests/test_graph_drive.py
  • [x] T13 — uv run --project cli python -m pytest -q cli · uv run ruff check cli hooks · uv run ruff format --check cli hooks · uv run pyright cli · markdownlint on the touched files · uv run python scripts/validate_config.py

Verification results ​

Recorded in evidence/automated-tests.md.

ActivityCommand / procedureOutcomeEvidence
T1 + T2 + T9cd cli && uv run python -m pytest -q tests/test_channels_verbs.py tests/test_selection_control.pypass — 52 passed (the suite failed at collection before the fix; the pre-fix reader shown red on the four P1 cases)evidence/automated-tests.md
T3 + T9 + T4cd cli && uv run python -m pytest -q tests/test_finish_grace.pypass — 12 passed (all red before the fix: GraphContext had no terminal)evidence/automated-tests.md
T4tests/test_config_schema_parity.py (in the full run)pass — both schema copies carry finishGraceSecondsevidence/automated-tests.md
T5cd cli && uv run python -m pytest -q tests/test_graph_drive.pypass — 25 passedevidence/automated-tests.md
T13full suite · ruff · ruff format · pyright · markdownlint · validatepass — 4335 passed, 1 skipped; 4 pre-existing failures in tests/test_instance.py that fail identically on the base commit in this environment (the checkout's own .the-loop/cli-config.yaml is exported into the spawn env); ruff, format, pyright, markdownlint and validate cleanevidence/automated-tests.md

Released under the MIT License.