<objective> Register the Phase 3 doctor checks with the D-72 migration, extend the Podman gate with live-gated bodies, and extend the taxonomy suite to the new categories and all ten IDs.
Purpose: Close the D-44 Phase 3 doctor registration, gate the 5.x-only live proof, and make QUAL-02 taxonomy enforce Phase 3 coverage. Output: Doctor extension, gate bodies, taxonomy extension, and the migrated Phase 2 doctor test. </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/03-container-runtime-and-bridges/03-CONTEXT.md @.planning/phases/03-container-runtime-and-bridges/03-PATTERNS.md </context>
<tasks>
<task type="tdd"> <name>Task 1: Phase 3 doctor checks and runtime-checks suite</name> <files>src/doctor/checks.ts, test/doctor/runtime-checks.test.ts</files> <read_first> - src/doctor/checks.ts (CheckId union, DoctorOptions lines 30-38, registry constant, runChecks lines 53-56; F-P3-01 resolution: same runner, extended) - src/runtime/podman-probe.ts (from plan 03-02; podman and podman-service items probe through it) - src/anda/shape.ts (from plan 03-03; anda-bridge item probes GET /.well-known/information through it) - test/doctor/checks.test.ts (layout, resultOf, and fixOf helpers to mirror) </read_first> <behavior> - Test: podman passes on 5.x, fails with PODMAN_MISSING or PODMAN_UNSUPPORTED_VERSION plus fix otherwise (RT-02) - Test: podman-service fails with PODMAN_MACHINE_DOWN and the systemctl fix on refused socket, passes otherwise - Test: openshell runs openshell sandbox create --help and passes only when every pinned flag appears, warns on drift, fails with the 0.1.2 install fix when missing (OQ-P3-12 default) - Test: anda-bridge passes on the D-61 shape, fails with ANDA_UNREACHABLE and the engine-URL fix, warns not-configured with no URL (ANDA-02) - Test: no AgentOS id is registered - Test titles cite RT-02 and ANDA-02 </behavior> <action>Write the failing tests first per behavior, then extend src/doctor/checks.ts per D-69 through the same runner: CheckId gains podman, podman-service, openshell, and anda-bridge with no AgentOS and no control-channel id; the four checks append to the registry in report order with injected seams (runCommand, connectSocket, Anda fetch) in the DoctorOptions canWrite style; if any check awaits, runChecks returns a Promise. Each check returns id, status, detail, and fix with fix null only on pass. Doctor may import runtime and anda (D-50). Then write test/doctor/runtime-checks.test.ts mirroring the Phase 2 helpers.</action> <acceptance_criteria> - test/doctor/runtime-checks.test.ts asserts pass, warn, and fail outcomes for all four checks each with its fix - No AgentOS or control-channel check exists in the registry </acceptance_criteria> <verify> <automated>npx tsc -p tsconfig.json && node --test dist/test/doctor/runtime-checks.test.js</automated> <fails_when>non-zero exit, or the summary shows 0 passed</fails_when> </verify> <done>Four Phase 3 checks green with fixes and no uninspectable items registered.</done> </task>
<task type="auto"> <name>Task 2: D-72 doctor test migration</name> <files>test/doctor/checks.test.ts</files> <read_first> - test/doctor/checks.test.ts (REGISTERED_IDS line 8, UNINSPECTABLE_ITEMS line 9, sixteen runChecks calls lines 50-180, final test lines 179-188) - src/doctor/checks.ts (from Task 1 of this plan; seven registered ids after extension) </read_first> <action>Migrate test/doctor/checks.test.ts per D-72 and F-P3-01 option (a): update the expected ids to the three Phase 2 plus four Phase 3 checks (seven total) and narrow the absence assertion to the agentos and control-channel names, which stay unregistered. If runChecks became async in Task 1 of this plan, await each call and pass the awaited array to resultOf. All other assertions stay unchanged. This is the deliberate D-69 registration change recorded in the phase report, not an incidental edit.</action> <acceptance_criteria> - Expected-ID list holds exactly the seven registered checks - Absence assertion still covers agentos and control and nothing else removed </acceptance_criteria> <verify> <automated>npx tsc -p tsconfig.json && node --test dist/test/doctor/checks.test.js dist/test/doctor/runtime-checks.test.js</automated> <fails_when>non-zero exit, or the summary shows 0 passed</fails_when> </verify> <done>Phase 2 doctor test migrated to the seven-check registry with assertions otherwise intact.</done> </task>
<task type="tdd"> <name>Task 3: Gated live bodies and taxonomy extension</name> <files>test/integration/podman-gate.test.ts, test/quality/suite-taxonomy.test.ts</files> <read_first> - test/integration/podman-gate.test.ts (import lines 4-8, probe lines 14-24, title; the probe keeps its own execFile per F-P3-07 and D-74) - test/quality/suite-taxonomy.test.ts (import line 6, CATEGORY_DIRS, CATEGORY_MAP, D45_FILES, line 138 Phase 2 ID test) </read_first> <behavior> - Test: taxonomy asserts all ten Phase 3 IDs (CORE-05, RT-01, RT-02, RT-03, RT-04, RT-09, ANDA-01, ANDA-02, ANDA-03, ANDA-04) are each cited by at least one named test file - Test titles cite the Phase 3 IDs they assert </behavior> <action>First extend test/integration/podman-gate.test.ts in place per D-48 and D-70: change only the parser import to ../../src/runtime/podman-version.js (F-P3-07: the gate keeps its own execFile probe, which stays unchanged); replace the Phase 1 body title; add three live bodies for RT-01 hardening, RT-03 routing, and RT-09 zero orphans, each under skip: gate so they skip on 4.9.3 with PODMAN_UNSUPPORTED_VERSION and run only on a 5.x host. These bodies are NOT executed in Phase 3 verification on this host. Then extend test/quality/suite-taxonomy.test.ts per D-70: fix the import to ../../src/runtime/podman-version.js, add runtime and anda to CATEGORY_DIRS and CATEGORY_MAP, add all nineteen new test files to the file list, and add the ten-ID coverage assertion beside the kept Phase 2 sixteen-ID test.</action> <acceptance_criteria> - Gate file imports only the parser from src/runtime and skips all three bodies with PODMAN_UNSUPPORTED_VERSION on this host - Taxonomy covers the new categories, all nineteen files, and all ten Phase 3 IDs while keeping the Phase 2 test </acceptance_criteria> <verify> <automated>npx tsc -p tsconfig.json && node --test dist/test/quality/suite-taxonomy.test.js dist/test/doctor/checks.test.js</automated> <fails_when>non-zero exit, or the summary shows 0 passed</fails_when> </verify> <done>Gate extended with skipped live bodies and taxonomy enforcing full Phase 3 ID coverage.</done> </task>
</tasks>
<threat_model>
Trust Boundaries
| Boundary | Description |
|---|---|
| probe output -> doctor report | Untrusted command output crosses into user-facing status; fail and warn carry fixes, pass carries no remediation |
| taxonomy list -> gate | File lists cross into coverage enforcement; a missing file must fail the suite, never silently narrow it |
STRIDE Threat Register
| Threat ID | Category | Component | Severity | Disposition | Mitigation Plan |
|---|---|---|---|---|---|
| T-03-25 | I (Information Disclosure) | src/doctor/checks.ts | low | mitigate | Doctor reports only what it inspects; AgentOS and control-channel stay unregistered so no unverified claim is shown (D-69) |
| T-03-26 | D (Denial of Service) | test/integration/podman-gate.test.ts | low | mitigate | Live bodies stay behind skip: gate with a named reason; the unit suite never depends on Podman (D-48) |
| T-03-27 | T (Tampering) | test/quality/suite-taxonomy.test.ts | low | mitigate | Ten-ID assertion fails the suite if any Phase 3 requirement loses its named test file |
| </threat_model> |
<verification> npx tsc -p tsconfig.json && node --test dist/test/doctor/checks.test.js dist/test/doctor/runtime-checks.test.js dist/test/quality/suite-taxonomy.test.js; node --test dist/test/integration/podman-gate.test.js shows the three bodies skipped with PODMAN_UNSUPPORTED_VERSION. </verification>
<success_criteria> Doctor covers seven checks with fixes, gate bodies skip with a stated reason on 4.9.3, and taxonomy pins all ten IDs to named files. </success_criteria>
<output> Create .planning/phases/03-container-runtime-and-bridges/03-10-SUMMARY.md when done </output>