|
| 1 | +# TP-013: Doc DAG + Review Stamps |
| 2 | + |
| 3 | +**User Story**: US-013 |
| 4 | +**Version**: 1.0.0 |
| 5 | +**Date**: 2026-02-02 |
| 6 | +**Status**: Draft |
| 7 | +**Author**: oscar |
| 8 | + |
| 9 | +## 1. Acceptance Criteria |
| 10 | + |
| 11 | +From US-013: |
| 12 | + |
| 13 | +| ID | Acceptance Criterion | |
| 14 | +|----|---------------------| |
| 15 | +| AC-1 | A document with a changed parent is flagged as stale until re-stamped | |
| 16 | +| AC-2 | Required documents missing from the DAG are reported as missing | |
| 17 | +| AC-3 | Dun emits prompts for stale/missing docs with parent context | |
| 18 | + |
| 19 | +## 2. Existing Test Coverage |
| 20 | + |
| 21 | +### 2.1 Tests Mapped to Acceptance Criteria |
| 22 | + |
| 23 | +| AC | Existing Test | File | Status | |
| 24 | +|----|---------------|------|--------| |
| 25 | +| AC-1 | None | - | Missing | |
| 26 | +| AC-2 | None | - | Missing | |
| 27 | +| AC-3 | None | - | Missing | |
| 28 | + |
| 29 | +### 2.2 Coverage Analysis |
| 30 | + |
| 31 | +No existing tests cover doc-DAG behavior. All acceptance criteria are gaps. |
| 32 | + |
| 33 | +## 3. Test Gaps |
| 34 | + |
| 35 | +### 3.1 Critical Gaps (P0) |
| 36 | + |
| 37 | +| Gap ID | Description | Priority | Acceptance Criteria | |
| 38 | +|--------|-------------|----------|---------------------| |
| 39 | +| GAP-001 | No test for cascade stale detection | P0 | AC-1 | |
| 40 | +| GAP-002 | No test for missing required roots | P0 | AC-2 | |
| 41 | +| GAP-003 | No test for prompt envelope content | P0 | AC-3 | |
| 42 | + |
| 43 | +### 3.2 Secondary Gaps (P1) |
| 44 | + |
| 45 | +| Gap ID | Description | Priority | Acceptance Criteria | |
| 46 | +|--------|-------------|----------|---------------------| |
| 47 | +| GAP-004 | No test for `dun stamp` updating review deps | P1 | AC-1 | |
| 48 | +| GAP-005 | No test for deterministic ordering | P1 | AC-3 | |
| 49 | + |
| 50 | +## 4. Proposed Test Cases |
| 51 | + |
| 52 | +### 4.1 Unit Tests |
| 53 | + |
| 54 | +#### TC-001: Frontmatter Parsing |
| 55 | +**File**: `internal/dun/frontmatter_test.go` |
| 56 | +**Priority**: P0 |
| 57 | +**Covers**: AC-1, AC-3 |
| 58 | + |
| 59 | +```go |
| 60 | +func TestFrontmatterParseDunBlock(t *testing.T) { |
| 61 | + // Given: a markdown file with dun frontmatter |
| 62 | + // When: parsed |
| 63 | + // Then: id, depends_on, prompt, review fields are extracted |
| 64 | +} |
| 65 | +``` |
| 66 | + |
| 67 | +#### TC-002: Hash Excludes Review |
| 68 | +**File**: `internal/dun/hash_test.go` |
| 69 | +**Priority**: P0 |
| 70 | +**Covers**: AC-1 |
| 71 | + |
| 72 | +```go |
| 73 | +func TestHashExcludesReviewSection(t *testing.T) { |
| 74 | + // Given: same doc with different dun.review |
| 75 | + // Then: hash is identical |
| 76 | +} |
| 77 | +``` |
| 78 | + |
| 79 | +#### TC-003: Missing Required Root |
| 80 | +**File**: `internal/dun/doc_dag_test.go` |
| 81 | +**Priority**: P0 |
| 82 | +**Covers**: AC-2 |
| 83 | + |
| 84 | +```go |
| 85 | +func TestDocDagMissingRequiredRoot(t *testing.T) { |
| 86 | + // Given: graph file requiring prd.md, file missing |
| 87 | + // Then: missing issue is emitted |
| 88 | +} |
| 89 | +``` |
| 90 | + |
| 91 | +#### TC-004: Stamp Updates Review Deps |
| 92 | +**File**: `internal/dun/stamp_test.go` |
| 93 | +**Priority**: P1 |
| 94 | +**Covers**: AC-1 |
| 95 | + |
| 96 | +```go |
| 97 | +func TestStampUpdatesReviewDeps(t *testing.T) { |
| 98 | + // Given: parent + child |
| 99 | + // When: dun stamp runs on child |
| 100 | + // Then: review.deps[parent] matches current parent hash |
| 101 | +} |
| 102 | +``` |
| 103 | + |
| 104 | +### 4.2 Integration Tests (Required for Day 1) |
| 105 | + |
| 106 | +#### TC-005: Cascade Stale Detection (End-to-End) |
| 107 | +**File**: `internal/dun/engine_test.go` |
| 108 | +**Priority**: P0 |
| 109 | +**Covers**: AC-1, AC-3 |
| 110 | + |
| 111 | +```go |
| 112 | +func TestDocDagCascadeStale(t *testing.T) { |
| 113 | + // Given: fixture repo with parent+child, stamped |
| 114 | + // When: parent changes |
| 115 | + // Then: child is stale and prompt is emitted |
| 116 | +} |
| 117 | +``` |
| 118 | + |
| 119 | +**Fixture**: `internal/testdata/repos/doc-dag-cascade/` |
| 120 | +- `docs/helix/01-frame/prd.md` with dun.frontmatter |
| 121 | +- `docs/helix/02-design/architecture.md` depending on PRD |
| 122 | +- Both have review stamps reflecting initial hashes |
| 123 | + |
| 124 | +**Expected**: |
| 125 | +- `doc-dag` check status = warn/fail |
| 126 | +- Issue `stale:helix.architecture` |
| 127 | +- Prompt envelope includes PRD content as input |
| 128 | + |
| 129 | +#### TC-006: Missing Required Doc Prompt |
| 130 | +**File**: `internal/dun/engine_test.go` |
| 131 | +**Priority**: P0 |
| 132 | +**Covers**: AC-2, AC-3 |
| 133 | + |
| 134 | +```go |
| 135 | +func TestDocDagMissingRequiredPrompt(t *testing.T) { |
| 136 | + // Given: graph requires prd.md, file missing |
| 137 | + // Then: prompt envelope for prd creation is emitted |
| 138 | +} |
| 139 | +``` |
| 140 | + |
| 141 | +## 5. Test Data Plan |
| 142 | + |
| 143 | +- New fixtures under `internal/testdata/repos/doc-dag-*`. |
| 144 | +- Graph file under `.dun/graphs/helix.yaml` in fixtures. |
| 145 | +- Minimal prompt templates under `internal/plugins/builtin/helix/prompts/` (or test-local prompt stubs). |
| 146 | + |
| 147 | +## 6. Exit Criteria |
| 148 | + |
| 149 | +- All P0 tests implemented and passing. |
| 150 | +- Integration test TC-005 confirms cascade detection from day 1. |
0 commit comments