Skip to content

Testing plan: the start opens the conversation

Derived from requirements.md and design.md, before tasks.md. Authored at test-planning; the results section is filled at verification.

This file is executable content. Commands below are what the agent runs; credentials appear by reference only.

Test matrix

#TypeApplies?Scope / what it provesWhere it runs
T1UnityesSlackBotChannel.open: root with origin start, no reply, idempotent, ChannelError on no channel/token/ts; bus.open_conversation: every opening channel, the ledger skipped, a failure a result + channel.open_failed; conversation_opener: config per call, no section → nothing; Dispatcher: opener called once on spawn with the ref, before the checkout, never on a refusal, a raising opener containeduv run --project cli python -m pytest -q cli/tests/test_channels.py cli/tests/test_bus.py cli/tests/test_control_integration.py cli/tests/test_eventlog.py
T2Integration (scenario)yesthe four Gherkin scenarios below through the real dispatcher + bus + Slack channel with the SDK client and tmux fakeduv run --project cli python -m pytest -q cli/tests/test_channels_integration.py cli/tests/test_control_integration.py
T3Contract (OpenAPI / GraphQL SDL)n/a — no API route changes; the start route's body and result are unchanged
T4End-to-endn/a — needs a Slack workspace and tmux; the scenario rows fake exactly the SDK client and the runner
T5UI / visualn/a — the root's Block Kit is issue-312's, asserted there
T6Snapshotn/a — field assertions on one record shape
T7Performance / loadn/a — one root post per work item, moved earlier rather than added; bounded by the SDK timeout on the work item's own worker
T8Security / abuse caseyesone negative test per abuse case A1–A5 (design.md § Security design)uv run --project cli python -m pytest -q cli/tests -k "unauthorized_start_opens or refused_start_opens or outage_never_fails_the_spawn or handed_the_ref_alone or still_opens_on_start"
T9Accessibilityn/a — no UI
T10Migration / upgradeyesa slack.json carrying origin: start read by the _record coercion path; a pre-issue-312 file still backfills (issue-312 T10 re-run); no config key changes, so no config migrationuv run --project cli python -m pytest -q cli/tests/test_channels.py -k "pre_issue_312 or origin"
T11Manual exploratoryn/a — the reviewer's walk-through is the PR briefing's "what to check"
T12Lint / format / typecheck / config validation / full suiteyesthe repository's own gates, as pre-commit and CI run themmake check
T13Security review (gate)yesthe-loop checklist against A1–A5, recorded as evidence; tier 3 needs no human sign-off (humanSignOffMinTier: 4)evidence/security-review.md

Scenarios & requirement trace

RowRequirement(s)Scenario / case
T1R1.2, R2.1, R2.2open posts one root, binds with origin start, emits channel.thread_opened with ids only
T1R1.3a second open, and an open after a post, post nothing
T1R1.5, R2.2no channel id / no token / no ts → ChannelError; the bus turns it into a result and channel.open_failed
T1R1.6open_conversation skips the ledger and any channel without open
T1R3.1, R3.2, R3.3the opener reads config per call and does nothing without a channels section; _build_dispatcher wires it; a dispatcher without one opens nothing
T1R1.1, R1.4the dispatcher calls the opener once, with the ref, before the workspace; not on a refused start; a raising opener is contained
T2R1.1, R1.2, R1.7, R2.1Scenario: A start opens the work item's thread before any event
T2R1.4Scenario: A refused start opens no thread
T2R1.3Scenario: A restarted work item keeps its thread
T2R1.5Scenario: A Slack outage never fails the spawn
T8A1–A5one negative test each, named in design.md § Security design
T10R2.1the origin coercion and the legacy backfill

Verification environment

  • Repositories: this repo only.
  • Services / containers: none. The Slack SDK client is faked at the process boundary; tmux is the test suite's FakeTmux; gh is faked where the announcer would post.
  • Fixtures & data: in-test dicts; a temp state.root per test.
  • Credentials: none. THE_LOOP_SLACK_BOT_TOKEN is set to a dummy value inside tests that need the channel enabled — by name, never a real token.
  • Bring-up: uv sync · Tear-down: none.
  • If bring-up fails: record it under Verification results and escalate.

Evidence plan

RowEvidencePath under evidence/
T1, T2, T8, T10, T12command, counts, duration, raw tail of the output; red → green per taskverification.md
T13the abuse-case table with verdicts and the tests that close eachsecurity-review.md

Verification activities

  • [x] T1 — uv run --project cli python -m pytest -q cli/tests/test_channels.py cli/tests/test_bus.py cli/tests/test_control_integration.py cli/tests/test_eventlog.py
  • [x] T2 — uv run --project cli python -m pytest -q cli/tests/test_channels_integration.py cli/tests/test_control_integration.py
  • [x] T8 — uv run --project cli python -m pytest -q cli/tests -k "unauthorized_start_opens or refused_start_opens or outage_never_fails_the_spawn or handed_the_ref_alone or still_opens_on_start"
  • [x] T10 — uv run --project cli python -m pytest -q cli/tests/test_channels.py -k "pre_issue_312 or origin"
  • [x] T12 — make check
  • [x] T13 — evidence/security-review.md

Verification results

ActivityCommand / procedureOutcomeEvidence
T1uv run --project cli python -m pytest -q cli/tests/test_channels.py cli/tests/test_bus.py cli/tests/test_control_integration.py cli/tests/test_eventlog.pypass — 153 passedevidence/verification.md
T2uv run --project cli python -m pytest -q cli/tests/test_channels_integration.py cli/tests/test_control_integration.pypass — 54 passed (the four scenarios among them)evidence/verification.md
T8uv run --project cli python -m pytest -q cli/tests -k "unauthorized_start_opens or refused_start_opens or outage_never_fails_the_spawn or handed_the_ref_alone or still_opens_on_start"pass — 6 passed (A1–A5; A2 twice, unit and scenario)evidence/verification.md
T10uv run --project cli python -m pytest -q cli/tests/test_channels.py -k "pre_issue_312 or origin"pass — 3 passedevidence/verification.md
T12make checkpass — lint, format, typecheck, config validation, full suiteevidence/verification.md
T13the-loop checklist over A1–A5pass; no human sign-off at tier 3evidence/security-review.md

Not executed: none.

Review comments

Appended by the-loop's record-feedback hook when a human gate approves with comments (issue-109). Append-only and attributed: an approval never silently discards a reviewer's suggestions, and the feedback travels with the document it concerns rather than living in a side-channel tracker.

Released under the MIT License.