Skip to content

<objective> Close Phase 4 with the live-gated integration bodies, the taxonomy extension, and the decision-record update.

Purpose: Deliver D-100, the D-102 integration and taxonomy rows, and the in-place podman-gate extension so the phase is traceable end to end. Output: Decision-note section plus three extended test files. </objective>

<execution_context> @~/.claude/gsd-core/workflows/execute-plan.md @~/.claude/gsd-core/templates/summary.md </execution_context>

<context> @.planning/PROJECT.md @.planning/ROADMAP.md @.planning/phases/04-reaper-egress-guard-and-shared-dispatcher/04-CONTEXT.md @.planning/phases/04-reaper-egress-guard-and-shared-dispatcher/04-PATTERNS.md </context>

<tasks>

<task type="auto"> <name>Task 1: Gated live bodies for egress, reap, and dispatcher exec (D-75, D-83, D-102)</name> <files>test/integration/podman-gate.test.ts</files> <read_first> - test/integration/podman-gate.test.ts line 29 (the sweep import to migrate to src/runtime/sweep.js) and lines 229-248 (scopedSweep to migrate) - src/runtime/sweep.ts (from plan 04-02; the moved sweep the gated reap body uses) - src/tools/dispatch.ts (from plan 04-06; the dispatcher the gated exec body drives) - src/runtime/egress.ts (from plan 04-01; the allowlist semantics the gated egress bodies assert) </read_first> <action>Extend test/integration/podman-gate.test.ts in place per D-102 (migrate, do not fork): migrate the line-29 import and the scopedSweep at lines 229-248 to the moved sweep; add live bodies for RT-05 (an allowlisted host and port succeeds, a non-allowlisted host fails, IPv6 not reachable), RT-08 (a crash reaped on a live host), and TOOL-03 (an exec through the dispatcher). The RT-05 bodies assert the D-75 proxy realization: egress is observed from inside the sandbox through the supervisor proxy, not from inside the container. No hardening property changes here: the verifier keeps NetworkMode none per D-51, so D-83 is a no-code negative recorded by these suites staying green with the verifier untouched. Every new body runs under the existing gate and skips with PODMAN_UNSUPPORTED_VERSION on 4.9.3, where the local Podman 4.9.3 install is unchanged (S-23). Each body reports live-gated outcomes only; no body may claim live verification on this host. Test titles cite RT-05, RT-08, and TOOL-03. (Implements the D-102 podman-gate row; OQ-P4-01, OQ-P4-02, and OQ-P4-04 stay gated by these suites.)</action> <acceptance_criteria> - The gate file imports the moved sweep and every new live body skips with PODMAN_UNSUPPORTED_VERSION on 4.9.3 - Live bodies exist for RT-05 allowlisted and non-allowlisted traffic, RT-08 crash reap, and TOOL-03 dispatcher exec </acceptance_criteria> <verify> <automated>npx tsc -p tsconfig.json && node --test dist/test/integration/podman-gate.test.js</automated> </verify> <done>Gated live bodies in place with skips proven on 4.9.3.</done> </task>

<task type="auto"> <name>Task 2: Taxonomy extension for tools and Phase 4 IDs (D-102)</name> <files>test/quality/suite-taxonomy.test.ts</files> <read_first> - test/quality/suite-taxonomy.test.ts lines 12-24 (CATEGORY_DIRS), line 26 (CATEGORY_MAP), line 58 (D45_FILES), line 126, and lines 222-241 (title-count style) and lines 231-241 (the Phase 3 ID check to mirror) - test/tools/dispatch.test.ts, test/tools/queue-timeout.test.ts, test/tools/workspace.test.ts, test/tools/no-bypass.test.ts, test/runtime/egress.test.ts, test/session/reap.test.ts (from plans 04-01, 04-02, 04-04, 04-06; the files whose RT-05, RT-08, TOOL-03, TOOL-04 title citations the new check counts) </read_first> <action>Extend test/quality/suite-taxonomy.test.ts per D-102: add the tools directory to CATEGORY_DIRS, add a tools category with its entries, and add a PHASE_4_REQUIREMENT_IDS check (RT-05, RT-08, TOOL-03, TOOL-04) mirroring the Phase 3 check so every Phase 4 ID is cited by at least one named test file. Keep the Phase 2 and Phase 3 lists intact. The Nyquist rule still holds: every Phase 4 automated verify names its exact test file. (Implements the D-102 taxonomy row and the QUAL-02 traceability for this phase.)</action> <acceptance_criteria> - The taxonomy counts the tools category and asserts all four Phase 4 IDs are cited by named test files - Phase 2 and Phase 3 taxonomy lists are unchanged </acceptance_criteria> <verify> <automated>npx tsc -p tsconfig.json && node --test dist/test/quality/suite-taxonomy.test.js</automated> </verify> <done>Taxonomy green with tools category and Phase 4 ID coverage.</done> </task>

<task type="auto"> <name>Task 3: Phase 4 decision-note section and its test (D-100)</name> <files>docs/integration/runtime-decision.md, test/runtime/decision-note.test.ts</files> <read_first> - docs/integration/runtime-decision.md (the Phase 3 note: OQ-P3-16 Blocked status, host observations, and the open-questions table style to extend) - test/runtime/decision-note.test.ts (existing assertion style for the Phase 3 sections) - src/runtime/egress.ts (from plan 04-01; the rendered shape facts the note records) </read_first> <action>Edit only docs/integration/runtime-decision.md to add the Phase 4 section per D-100: OQ-P3-16 resolved for Realm's fields (D-82) with the v0.1.2 URL and the 2026-10-21 read date; the exec verb pin and its --help evidence (D-93); the IPv6 partial status (D-76); the single-owner precondition (D-87 with the OQ-P4-06 residual risk); the D-90 two-lines-per-call audit note for the Phase 7 reader (per the CONTEXT specifics note); and OQ-P4-01 to OQ-P4-12 each with its default. Create no new integration note file (no new external dependency per D-100) and edit no spec. Extend test/runtime/decision-note.test.ts to assert the Phase 4 section exists with those entries. (Implements D-100.)</action> <acceptance_criteria> - The decision note carries the Phase 4 section with the OQ-P3-16 resolution, exec pin, IPv6 partial status, single-owner precondition, audit two-line note, and OQ-P4-01 to OQ-P4-12 defaults - The decision-note test asserts the section and no other doc file changes </acceptance_criteria> <verify> <automated>npx tsc -p tsconfig.json && node --test dist/test/runtime/decision-note.test.js</automated> </verify> <done>Decision record updated with the Phase 4 section and test.</done> </task>

</tasks>

<threat_model>

Trust Boundaries ​

BoundaryDescription
live host -> gated suiteA real Podman daemon crosses into tests; the gate refuses 4.9.3 before any container call
decision note -> future phaseRecorded defaults cross into Phase 5-7 builds; only documented, reviewed facts are written

STRIDE Threat Register ​

Threat IDCategoryComponentSeverityDispositionMitigation Plan
T-04-14T (Tampering)test/integration/podman-gate.test.tsmediummitigateEvery new live body runs under the existing gate and skips with PODMAN_UNSUPPORTED_VERSION on 4.9.3, so the suite can neither claim unverified live behavior nor touch the unsupported host daemon
T-04-15I (Information Disclosure)docs/integration/runtime-decision.mdlowacceptThe note records only public doc URLs, read dates, and behavior defaults; rationale: it carries no secret, path, or credential, and the decision-note test pins its required entries
</threat_model>

<verification> npx tsc -p tsconfig.json && node --test dist/test/integration/podman-gate.test.js dist/test/quality/suite-taxonomy.test.js dist/test/runtime/decision-note.test.js; grep test/integration/podman-gate.test.ts for PODMAN_UNSUPPORTED_VERSION in each new body. </verification>

<success_criteria> Gated suites skip cleanly on 4.9.3, taxonomy cites all four IDs, and the Phase 4 decision section is recorded and tested. </success_criteria>

Artifacts this phase produces (contribution of this plan) ​

  • docs/integration/runtime-decision.md Phase 4 section (new section, edited file): OQ-P3-16 resolution, exec pin, IPv6 partial, single-owner precondition, audit two-line note, OQ-P4-01 to OQ-P4-12 defaults (D-100).
  • test/integration/podman-gate.test.ts (extended in place): gated RT-05, RT-08, TOOL-03 live bodies skipping with PODMAN_UNSUPPORTED_VERSION.
  • test/quality/suite-taxonomy.test.ts (extended): tools category and Phase 4 ID citation check (D-102).
  • test/runtime/decision-note.test.ts (extended): Phase 4 section assertions (D-100, D-102).

<output> Create .planning/phases/04-reaper-egress-guard-and-shared-dispatcher/04-07-SUMMARY.md when done </output>

AGPL-3.0-only. Copyright (C) 2026 Spectrum Web Co/swcstudiospace.