From 9f97f27056db2d5e5a5df5718142aab4d52694a6 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 10 May 2026 07:57:38 +0000 Subject: [PATCH 1/3] docs: add task DAG for phase 9 remediation plan Captures the dependency structure of the 2026-03-10 phase 9 health review remediation plan: prerequisites, intra-stage ordering (1.11 after all other Stage 1, 2A.2 after 2A.1, 2B.1 after 1.11, 2C wiring after 2B refactors, 3.x after the OpenAPI gate and 3.0 reference, 6C after Stage 3), the topological layers a coordinator can fan out, and the critical path. --- ...10-phase9-health-review-remediation-dag.md | 172 ++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 dev/plans/2026-03-10-phase9-health-review-remediation-dag.md diff --git a/dev/plans/2026-03-10-phase9-health-review-remediation-dag.md b/dev/plans/2026-03-10-phase9-health-review-remediation-dag.md new file mode 100644 index 0000000..128bfe5 --- /dev/null +++ b/dev/plans/2026-03-10-phase9-health-review-remediation-dag.md @@ -0,0 +1,172 @@ +# Phase 9 Health Review Remediation — Task DAG + +Dependency graph for `dev/plans/2026-03-10-phase9-health-review-remediation-plan.md`. + +Sources of edges: +- Stage Overview "Dependency graph" block in the plan (lines 43–51) +- Stage 1 prologue: "Task 1.11 must execute AFTER all other Stage 1 tasks have been committed" (line 83) +- Stage 2B prologue: "These tasks clean up the evaluator internals BEFORE wiring it into the runtime (Stage 2C)" (line 961) +- Task 2B.1 body: post-filter target type is `generated.CVE`, "type was renamed from `Cfe` to `CVE` by Task 1.11" (line 980) → 2B.1 ⟵ 1.11 +- Task 2A.2 body: query asserts via `tdb.AppStore` (the `NOBYPASSRLS` role) → 2A.2 ⟵ 2A.1 +- Task 2C.2 body: realtime hook fires after merge once batch/EPSS jobs are registered → 2C.2 ⟵ 2C.1 +- Task 6C body: "DEFERRED — depends on Stage 3 completing" (line 2761) +- Stage 3 body: "implementation plan for the revised Stage 3 will be written after the OpenAPI evaluation gate completes" (line 1282) + +## Mermaid graph + +```mermaid +graph TD + P8["Phase 8 merges
(8B Observe, 8C Operate, 8D, 8E)"]:::prereq + + %% ── Stage 1 ────────────────────────────────────────── + subgraph S1["Stage 1: Quick Wins"] + T1_1["1.1 Close api.Server"] + T1_2["1.2 Close stdlib DB wrappers"] + T1_3["1.3 Validate COOKIE_SECURE"] + T1_4["1.4 Worker pool ctx cancel"] + T1_5["1.5 Remove dead readTx"] + T1_6["1.6 Fix GetCVEDetail comment"] + T1_7["1.7 Add missing assertion"] + T1_8["1.8 Stop discarding setup errors"] + T1_9["1.9 DownloadToTemp pkg state"] + T1_10["1.10 Validate InCISAKEV bool"] + T1_12["1.12 Dedup toNullString"] + T1_11["1.11 sqlc rename Cfe → CVE
(after all other Stage 1)"]:::ordering + end + + %% ── Stage 2A ───────────────────────────────────────── + subgraph S2A["Stage 2A: RLS Security"] + T2A_1["2A.1 Restricted app DB role"] + T2A_2["2A.2 RLS cross-tenant test"] + end + + %% ── Stage 2B ───────────────────────────────────────── + subgraph S2B["Stage 2B: Evaluator Refactor"] + T2B_1["2B.1 Extract post-filter"] + T2B_2["2B.2 Merge queryCandidates"] + end + + %% ── Stage 2C ───────────────────────────────────────── + subgraph S2C["Stage 2C: Alert Wiring"] + T2C_1["2C.1 Schedule batch + EPSS jobs"] + T2C_2["2C.2 Realtime post-merge hook"] + end + + %% ── Stage 3 ────────────────────────────────────────── + GATE["OpenAPI evaluation gate
(see proposal doc)"]:::gate + subgraph S3["Stage 3: API Contract Convergence"] + T3_0["3.0 Reference: Groups"] + T3_1["3.1 Saved Searches"] + T3_2["3.2 API Keys"] + T3_3["3.3 Channels"] + T3_4["3.4 Watchlists"] + T3_5["3.5 Alert Rules"] + T3_6["3.6 Deliveries (#43)"] + T3_7["3.7 Reports"] + T3_8["3.8 Orgs (#34)"] + T3_9["3.9 Members + Invitations"] + T3_10["3.10 Audit Log"] + T3_11["3.11 Admin Endpoints"] + T3_12["3.12 Feeds Admin"] + T3_CLEAN["Post-migration cleanup
(delete orgFetch + writeJSON)"] + end + + %% ── Stage 4 ────────────────────────────────────────── + subgraph S4["Stage 4: Ops Hardening"] + T4D["4D Notification semaphore eviction"] + T4E["4E Configurable statement timeout"] + end + + %% ── Stage 5 ────────────────────────────────────────── + subgraph S5["Stage 5: Test Quality"] + T5A["5A Feed adapter golden tests"] + T5B["5B Ingest handler integration test"] + T5C["5C Email testcontainer"] + T5D["5D Advisory lock concurrency test"] + end + + %% ── Stage 6 ────────────────────────────────────────── + subgraph S6["Stage 6: Architecture"] + T6A["6A ServerDeps options struct"] + T6B["6B Notification worker health"] + T6E["6E merge.Store interface"] + T6F["6F BootstrapFirstUserOrg refactor"] + T6C["6C Extract buildApp()
(deferred)"]:::deferred + T6D["6D ~~import-bulk for NVD~~
INVALIDATED"]:::invalidated + end + + %% ── Edges ──────────────────────────────────────────── + P8 --> S1 + P8 --> S2A + P8 --> S2B + P8 --> S2C + P8 --> GATE + P8 --> S4 + P8 --> S5 + P8 --> S6 + + T1_1 --> T1_11 + T1_2 --> T1_11 + T1_3 --> T1_11 + T1_4 --> T1_11 + T1_5 --> T1_11 + T1_6 --> T1_11 + T1_7 --> T1_11 + T1_8 --> T1_11 + T1_9 --> T1_11 + T1_10 --> T1_11 + T1_12 --> T1_11 + + T2A_1 --> T2A_2 + + T1_11 --> T2B_1 + + T2B_1 --> T2C_1 + T2B_2 --> T2C_1 + T2C_1 --> T2C_2 + + GATE --> T3_0 + T3_0 --> T3_1 --> T3_2 --> T3_3 --> T3_4 --> T3_5 --> T3_6 --> T3_7 --> T3_8 --> T3_9 --> T3_10 --> T3_11 --> T3_12 --> T3_CLEAN + + T3_CLEAN --> T6C + + classDef prereq fill:#fce4a6,stroke:#a06b00,color:#3a2a00 + classDef ordering fill:#e8d5ff,stroke:#5b27a8,color:#22094a + classDef gate fill:#d4edff,stroke:#1f6feb,color:#0a2540 + classDef deferred fill:#f0f0f0,stroke:#999,color:#444 + classDef invalidated fill:#f7f7f7,stroke:#bbb,color:#888,stroke-dasharray: 4 3 +``` + +## Topological layers (parallel-execution view) + +A subagent coordinator can fan out each layer in parallel; later layers wait for the prior layer's edges. + +| Layer | Tasks | Notes | +|-------|-------|-------| +| L0 | Phase 8 merges | Prerequisite — out of scope for this plan | +| L1 | 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 1.10, 1.12 · 2A.1 · 2B.2 · 4D · 4E · 5A · 5B · 5C · 5D · 6A · 6B · 6E · 6F · OpenAPI gate | All independent. Stage 1 (excl. 1.11) is the prime parallel batch. | +| L2 | 1.11 · 2A.2 · 3.0 | 1.11 waits on all other Stage 1; 2A.2 waits on 2A.1; 3.0 waits on the OpenAPI gate. | +| L3 | 2B.1 | Needs the `generated.CVE` rename from 1.11. | +| L4 | 2C.1 | Needs both 2B.1 and 2B.2 complete. | +| L5 | 2C.2 | Sequential after 2C.1. | +| L6 | 3.1 → 3.2 → 3.3 → 3.4 → 3.5 → 3.6 → 3.7 → 3.8 → 3.9 → 3.10 → 3.11 → 3.12 | Sequential migrations following the 3.0 reference; each is one commit per the plan. | +| L7 | Stage 3 post-migration cleanup | After 3.12. | +| L8 | 6C (extract `buildApp()`) | Deferred until Stage 3 is complete and stable. | + +Tasks not on the critical path: 4D, 4E, 5A–5D, 6A, 6B, 6E, 6F can finish at any point after L1. + +## Critical path + +`Phase 8 → {1.1–1.10, 1.12} → 1.11 → 2B.1 → 2C.1 → 2C.2` + +Stage 3 has its own parallel critical path gated by the OpenAPI evaluation: + +`Phase 8 → OpenAPI gate → 3.0 → 3.1 → … → 3.12 → cleanup → 6C` + +The two paths don't intersect, so they can progress concurrently once Phase 8 lands. + +## Resolved / invalidated (no DAG nodes) + +- **Findings 3, 10, 11, 38** — resolved by Phase 8 or already correct; no task. +- **Task 6D (Finding 19)** — invalidated; NVD has no bulk download archives. +- **Task 4A, 4B, 4C** — 4A/4B subsumed by Phase 8; 4C moved into Stage 6 as 6C. From 7267fa9845fe194f6339be3192b7d01eea07d0fd Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 10 May 2026 08:05:16 +0000 Subject: [PATCH 2/3] docs: correct phase 9 remediation DAG after adversarial review Removes superseded Stage 3 tasks 3.0-3.12 and replaces them with a single external-plan node pointing at the 2026-03-15 stage 3 convergence plan. Removes the fabricated 2C.1->2C.2 edge so the two runtime-wiring tasks are siblings under 2B. Drops T6D from the graph to match the resolved/invalidated text. Demotes the 1.11->2B.1 edge from a dedicated arrow to a soft-conflict note. Splits the Phase 8 prerequisite into 8B/8C/8D/8E with per-task dotted edges. Adds a soft-conflicts table for file-level overlaps in L1. Recomputes the critical path as two independent chains, with chain B's depth set by the external Stage 3 plan. --- ...10-phase9-health-review-remediation-dag.md | 182 +++++++++++------- 1 file changed, 108 insertions(+), 74 deletions(-) diff --git a/dev/plans/2026-03-10-phase9-health-review-remediation-dag.md b/dev/plans/2026-03-10-phase9-health-review-remediation-dag.md index 128bfe5..a4b5e88 100644 --- a/dev/plans/2026-03-10-phase9-health-review-remediation-dag.md +++ b/dev/plans/2026-03-10-phase9-health-review-remediation-dag.md @@ -2,21 +2,26 @@ Dependency graph for `dev/plans/2026-03-10-phase9-health-review-remediation-plan.md`. -Sources of edges: -- Stage Overview "Dependency graph" block in the plan (lines 43–51) -- Stage 1 prologue: "Task 1.11 must execute AFTER all other Stage 1 tasks have been committed" (line 83) -- Stage 2B prologue: "These tasks clean up the evaluator internals BEFORE wiring it into the runtime (Stage 2C)" (line 961) -- Task 2B.1 body: post-filter target type is `generated.CVE`, "type was renamed from `Cfe` to `CVE` by Task 1.11" (line 980) → 2B.1 ⟵ 1.11 -- Task 2A.2 body: query asserts via `tdb.AppStore` (the `NOBYPASSRLS` role) → 2A.2 ⟵ 2A.1 -- Task 2C.2 body: realtime hook fires after merge once batch/EPSS jobs are registered → 2C.2 ⟵ 2C.1 -- Task 6C body: "DEFERRED — depends on Stage 3 completing" (line 2761) -- Stage 3 body: "implementation plan for the revised Stage 3 will be written after the OpenAPI evaluation gate completes" (line 1282) +Sources of edges (line refs into the plan): +- Stage Overview "Dependency graph" block (lines 43–51) +- Stage 1 prologue: 1.11 must run after all other Stage 1 tasks (line 83) +- Stage 2B prologue: 2B finishes before Stage 2C wires into runtime (line 961) +- Task 2A.2: cross-tenant test asserts via `tdb.AppStore` (the restricted role enabled by 2A.1) (lines 929–941) +- Task 6C: "DEFERRED — depends on Stage 3 completing" (line 2761) +- Stage 3 wrapper: tasks 3.0–3.12 are inside a `
` block marked **superseded — Do not execute** (lines 1280, 1284, 1912). The actual Stage 3 work lives in `dev/plans/2026-03-15-phase9-stage3-api-contract-convergence-plan.md`. +- Per-pillar Phase 8 notes in the prerequisites table (lines 17–28) and per-task warnings (e.g. 6A line 2589, 6B line 2660, 5A appendix line 3001, 2B.1/2B.2 lines 969, 1079). ## Mermaid graph ```mermaid graph TD - P8["Phase 8 merges
(8B Observe, 8C Operate, 8D, 8E)"]:::prereq + %% ── Phase 8 prerequisite (per pillar) ─────────────── + subgraph P8["Phase 8 merges (prerequisite)"] + P8B["8B Observe
(metrics, instrumentation)"]:::prereq + P8C["8C Operate
(/healthz, /readyz, doctor, admin)"]:::prereq + P8D["8D Generic feed adapter"]:::prereq + P8E["8E (other operational work)"]:::prereq + end %% ── Stage 1 ────────────────────────────────────────── subgraph S1["Stage 1: Quick Wins"] @@ -47,29 +52,14 @@ graph TD end %% ── Stage 2C ───────────────────────────────────────── - subgraph S2C["Stage 2C: Alert Wiring"] + subgraph S2C["Stage 2C: Alert Wiring (parallel siblings)"] T2C_1["2C.1 Schedule batch + EPSS jobs"] T2C_2["2C.2 Realtime post-merge hook"] end - %% ── Stage 3 ────────────────────────────────────────── - GATE["OpenAPI evaluation gate
(see proposal doc)"]:::gate - subgraph S3["Stage 3: API Contract Convergence"] - T3_0["3.0 Reference: Groups"] - T3_1["3.1 Saved Searches"] - T3_2["3.2 API Keys"] - T3_3["3.3 Channels"] - T3_4["3.4 Watchlists"] - T3_5["3.5 Alert Rules"] - T3_6["3.6 Deliveries (#43)"] - T3_7["3.7 Reports"] - T3_8["3.8 Orgs (#34)"] - T3_9["3.9 Members + Invitations"] - T3_10["3.10 Audit Log"] - T3_11["3.11 Admin Endpoints"] - T3_12["3.12 Feeds Admin"] - T3_CLEAN["Post-migration cleanup
(delete orgFetch + writeJSON)"] - end + %% ── Stage 3 (gate only — implementation lives elsewhere) ── + GATE["OpenAPI evaluation gate
(timeboxed, in-plan)"]:::gate + S3EXT["Stage 3 implementation
(external plan:
2026-03-15-phase9-stage3-
api-contract-convergence-plan.md)"]:::external %% ── Stage 4 ────────────────────────────────────────── subgraph S4["Stage 4: Ops Hardening"] @@ -92,19 +82,37 @@ graph TD T6E["6E merge.Store interface"] T6F["6F BootstrapFirstUserOrg refactor"] T6C["6C Extract buildApp()
(deferred)"]:::deferred - T6D["6D ~~import-bulk for NVD~~
INVALIDATED"]:::invalidated end - %% ── Edges ──────────────────────────────────────────── - P8 --> S1 - P8 --> S2A - P8 --> S2B - P8 --> S2C - P8 --> GATE - P8 --> S4 - P8 --> S5 - P8 --> S6 - + %% ── Phase 8 prerequisite edges (whole-stage gating) ── + P8B --> S1 + P8B --> S2A + P8B --> S2B + P8B --> S2C + P8B --> GATE + P8B --> S4 + P8B --> S5 + P8C --> S1 + P8C --> S2A + P8C --> S2B + P8C --> S2C + P8C --> GATE + P8C --> S4 + P8C --> S5 + P8D --> S5 + P8E --> S1 + P8E --> S2A + + %% ── Phase 8 prerequisite edges (per-task call-outs) ── + P8C -.->|adds Server deps captured by ServerDeps| T6A + P8C -.->|exposes /readyz target| T6B + P8D -.->|generic adapter covered by golden tests| T5A + P8B -.->|metric instrumentation may shift| T2B_1 + P8B -.->|metric instrumentation may shift| T2B_2 + P8B -.->|alert metrics activate once wired| T2C_1 + P8B -.->|alert metrics activate once wired| T2C_2 + + %% ── Stage 1 fan-in to 1.11 ─────────────────────────── T1_1 --> T1_11 T1_2 --> T1_11 T1_3 --> T1_11 @@ -117,56 +125,82 @@ graph TD T1_10 --> T1_11 T1_12 --> T1_11 + %% ── Stage 2A internal edge ─────────────────────────── T2A_1 --> T2A_2 - T1_11 --> T2B_1 - + %% ── Stage 2B → 2C (both 2B tasks must complete) ────── T2B_1 --> T2C_1 T2B_2 --> T2C_1 - T2C_1 --> T2C_2 - - GATE --> T3_0 - T3_0 --> T3_1 --> T3_2 --> T3_3 --> T3_4 --> T3_5 --> T3_6 --> T3_7 --> T3_8 --> T3_9 --> T3_10 --> T3_11 --> T3_12 --> T3_CLEAN - - T3_CLEAN --> T6C - - classDef prereq fill:#fce4a6,stroke:#a06b00,color:#3a2a00 - classDef ordering fill:#e8d5ff,stroke:#5b27a8,color:#22094a - classDef gate fill:#d4edff,stroke:#1f6feb,color:#0a2540 - classDef deferred fill:#f0f0f0,stroke:#999,color:#444 - classDef invalidated fill:#f7f7f7,stroke:#bbb,color:#888,stroke-dasharray: 4 3 + T2B_1 --> T2C_2 + T2B_2 --> T2C_2 + + %% ── Stage 3 gate → external plan → 6C ──────────────── + GATE --> S3EXT + S3EXT --> T6C + + classDef prereq fill:#fce4a6,stroke:#a06b00,color:#3a2a00 + classDef ordering fill:#e8d5ff,stroke:#5b27a8,color:#22094a + classDef gate fill:#d4edff,stroke:#1f6feb,color:#0a2540 + classDef external fill:#dff5e0,stroke:#1a7f37,color:#0a2a12 + classDef deferred fill:#f0f0f0,stroke:#999,color:#444 ``` +Solid arrows = hard ordering required by the plan. Dotted arrows = pillar-specific pre-conditions / metric instrumentation hand-offs called out in the plan body. + ## Topological layers (parallel-execution view) -A subagent coordinator can fan out each layer in parallel; later layers wait for the prior layer's edges. +A subagent coordinator can fan out each layer in parallel; later layers wait for the prior layer's edges. **Read the soft-conflicts section before dispatching L1 in parallel.** | Layer | Tasks | Notes | |-------|-------|-------| -| L0 | Phase 8 merges | Prerequisite — out of scope for this plan | -| L1 | 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 1.10, 1.12 · 2A.1 · 2B.2 · 4D · 4E · 5A · 5B · 5C · 5D · 6A · 6B · 6E · 6F · OpenAPI gate | All independent. Stage 1 (excl. 1.11) is the prime parallel batch. | -| L2 | 1.11 · 2A.2 · 3.0 | 1.11 waits on all other Stage 1; 2A.2 waits on 2A.1; 3.0 waits on the OpenAPI gate. | -| L3 | 2B.1 | Needs the `generated.CVE` rename from 1.11. | -| L4 | 2C.1 | Needs both 2B.1 and 2B.2 complete. | -| L5 | 2C.2 | Sequential after 2C.1. | -| L6 | 3.1 → 3.2 → 3.3 → 3.4 → 3.5 → 3.6 → 3.7 → 3.8 → 3.9 → 3.10 → 3.11 → 3.12 | Sequential migrations following the 3.0 reference; each is one commit per the plan. | -| L7 | Stage 3 post-migration cleanup | After 3.12. | -| L8 | 6C (extract `buildApp()`) | Deferred until Stage 3 is complete and stable. | - -Tasks not on the critical path: 4D, 4E, 5A–5D, 6A, 6B, 6E, 6F can finish at any point after L1. +| L0 | 8B Observe · 8C Operate · 8D · 8E | Phase 8 prerequisite — out of scope for this plan | +| L1 | 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 1.10, 1.12 · 2A.1 · 2B.1 · 2B.2 · 4D · 4E · 5A · 5B · 5C · 5D · 6A · 6B · 6E · 6F · OpenAPI gate | All independent per the plan's dependency block. 2A.1, 2B.1, 2B.2 have no stated Stage 1 prerequisites, so they belong here. | +| L2 | 1.11 · 2A.2 | 1.11 waits on the Stage 1 fan-in. 2A.2 waits on 2A.1. | +| L3 | 2C.1 · 2C.2 | Both wait on 2B.1 + 2B.2. They are siblings — the plan does not require one before the other. | +| L4 | Stage 3 implementation (external plan) | Waits on the OpenAPI gate's outcome. | +| L5 | 6C (extract `buildApp()`) | Waits on the external Stage 3 plan landing. | + +`6D` is excluded entirely — invalidated, no node in the graph. + +## Soft conflicts (file-level, not logical) + +These pairs are independent in the plan's dependency model but touch the same file. Dispatching them simultaneously will produce merge conflicts; sequence them in the queue. + +| Pair | Shared file | Conflict | +|------|-------------|----------| +| 4D ↔ 6B | `internal/notify/worker.go` | Both add fields to `Worker` struct and modify `Start()` | +| 1.12 ↔ 6E | `internal/merge/pipeline.go` | toNullString call sites vs. `merge.Store` interface signature change | +| 1.4 ↔ 2C.1 | worker pool registration sites | Context-cancel fix vs. new `alert_batch`/`alert_epss`/`alert_zombie_sweep` handlers | +| 5B ↔ 2C.2 | `internal/ingest/handler.go` | Integration test vs. realtime-eval hook on the same handler | +| 1.11 ↔ 2B.1, 5B, 6E, Stage 3 work | every file importing `generated.Cfe` | 1.11 mass-renames the type. Tasks that write code referencing the type pre-rename will need a trivial rebase — not a hard dep, but a real coordination cost. The plan resolves this by sequencing 1.11 last in Stage 1 before later stages start writing new code against the type. | +| 6A ↔ 8C-derived setters | `internal/api/server.go`, `cmd/cvert-ops/main.go` | If Phase 8C added new `Set*Deps` methods, 6A must absorb them too (called out in plan §6A Step 2 note). | ## Critical path -`Phase 8 → {1.1–1.10, 1.12} → 1.11 → 2B.1 → 2C.1 → 2C.2` +There are two largely independent chains; the plan does not connect them, and the second is only partially defined here. + +**Chain A (alert wiring):** + +``` +P8 (8B + 8C + 8E) → {Stage 1 batch, longest task} → 1.11 → {2B.1 ∥ 2B.2} → {2C.1 ∥ 2C.2} +``` + +The `2C.x` fan-out at the end means the chain-A bottleneck is `max(2C.1, 2C.2)` after Stage 2B completes — neither blocks the other. + +**Chain B (API contract convergence):** -Stage 3 has its own parallel critical path gated by the OpenAPI evaluation: +``` +P8 (8B + 8C) → OpenAPI gate → external Stage 3 plan (Tasks 0–14b) → 6C +``` -`Phase 8 → OpenAPI gate → 3.0 → 3.1 → … → 3.12 → cleanup → 6C` +Chain B's true length is set by `2026-03-15-phase9-stage3-api-contract-convergence-plan.md`, which has 14+ tasks of its own. From this plan's perspective the depth is unknown; treat Chain B as the project critical path until the external plan's own DAG is summarized. -The two paths don't intersect, so they can progress concurrently once Phase 8 lands. +The two chains share only the Phase 8 prerequisite, so they run concurrently after L0. Stages 4, 5, 6A, 6B, 6E, 6F are off the critical path entirely — they can land any time after their Phase 8 pillar is in. -## Resolved / invalidated (no DAG nodes) +## Resolved / invalidated (excluded from the graph) -- **Findings 3, 10, 11, 38** — resolved by Phase 8 or already correct; no task. -- **Task 6D (Finding 19)** — invalidated; NVD has no bulk download archives. -- **Task 4A, 4B, 4C** — 4A/4B subsumed by Phase 8; 4C moved into Stage 6 as 6C. +- **Findings 3, 10, 11, 38** — resolved by Phase 8 or already correct; no task ever existed. +- **Tasks 4A, 4B** — subsumed by Phase 8B/8C; removed from Stage 4 scope. +- **Task 4C** — moved into Stage 6 as 6C (already a node). +- **Task 6D (Finding 19)** — invalidated; NVD has no bulk download archives. Not a node. +- **Original Tasks 3.0–3.12** — superseded; lives behind `
` in the plan with "Do not execute." Not nodes; replaced by the single `S3EXT` node pointing at the external implementation plan. From 9997ccd1cc8596468178bf6920dce1e4fbc295b2 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 10 May 2026 08:06:19 +0000 Subject: [PATCH 3/3] docs: clarify DAG scope is inter-task ordering only Adds a scope note that intra-task ordering (e.g. 6B's TDD sequence) is not modeled here. Closes the last open item from the adversarial review. --- dev/plans/2026-03-10-phase9-health-review-remediation-dag.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dev/plans/2026-03-10-phase9-health-review-remediation-dag.md b/dev/plans/2026-03-10-phase9-health-review-remediation-dag.md index a4b5e88..78e9282 100644 --- a/dev/plans/2026-03-10-phase9-health-review-remediation-dag.md +++ b/dev/plans/2026-03-10-phase9-health-review-remediation-dag.md @@ -1,6 +1,8 @@ # Phase 9 Health Review Remediation — Task DAG -Dependency graph for `dev/plans/2026-03-10-phase9-health-review-remediation-plan.md`. +Inter-task dependency graph for `dev/plans/2026-03-10-phase9-health-review-remediation-plan.md`. + +**Scope:** ordering between named tasks (e.g. `1.11 → 2C.1`). Intra-task ordering — TDD steps inside a single task body, such as 6B's "scaffolding → stub → failing test → real impl → wire to readiness" — is not modeled here. Read the task body in the plan for those details. Sources of edges (line refs into the plan): - Stage Overview "Dependency graph" block (lines 43–51)