|
| 1 | +# Implementation Plan: Docs Index Progress, SKILL Integration & Coverage Dashboard Fix |
| 2 | + |
| 3 | +**Branch**: `024-docs-skill-coverage-fix` | **Date**: 2026-04-08 | **Spec**: [spec.md](spec.md) |
| 4 | +**Input**: Feature specification from `/specs/024-docs-skill-coverage-fix/spec.md` |
| 5 | + |
| 6 | +## Summary |
| 7 | + |
| 8 | +Three related issues surfaced when running SPECTRA through VS Code Copilot Chat SKILLs: (1) `spectra docs index` blocks in SKILL flows because it has no result/progress files and auto-triggers interactive criteria extraction, (2) remaining "requirements" terminology that should be "acceptance criteria", and (3) a broken dashboard Coverage tab. The fix adds result/progress file writing to `DocsIndexHandler` (replicating the `GenerateHandler` pattern), creates a dedicated `spectra-docs` SKILL, completes the terminology rename, and fixes dashboard JavaScript field references. |
| 9 | + |
| 10 | +## Technical Context |
| 11 | + |
| 12 | +**Language/Version**: C# 12, .NET 8+ |
| 13 | +**Primary Dependencies**: System.CommandLine, Spectre.Console, System.Text.Json, GitHub Copilot SDK |
| 14 | +**Storage**: File system (`.spectra-result.json`, `.spectra-progress.html`, `_criteria_index.yaml`) |
| 15 | +**Testing**: xUnit (1280+ existing tests across 3 test projects) |
| 16 | +**Target Platform**: Windows, macOS, Linux (cross-platform CLI) |
| 17 | +**Project Type**: CLI tool + MCP server |
| 18 | +**Performance Goals**: N/A (no performance-critical changes) |
| 19 | +**Constraints**: Must maintain backward compatibility for `--extract-requirements` alias, `requirements` YAML field, `requirements_file` config key |
| 20 | +**Scale/Scope**: ~15 files modified, 1 new embedded resource file, ~15 new tests |
| 21 | + |
| 22 | +## Constitution Check |
| 23 | + |
| 24 | +*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.* |
| 25 | + |
| 26 | +| Principle | Status | Notes | |
| 27 | +|-----------|--------|-------| |
| 28 | +| I. GitHub as Source of Truth | PASS | All changes are file-based (result JSON, progress HTML, SKILL markdown, config) | |
| 29 | +| II. Deterministic Execution | PASS | No state machine changes; result files are deterministic outputs | |
| 30 | +| III. Orchestrator-Agnostic Design | PASS | SKILL files work with any Copilot Chat agent; result files are plain JSON | |
| 31 | +| IV. CLI-First Interface | PASS | All functionality exposed via CLI flags (`--skip-criteria`, `--no-interaction`); SKILL is a wrapper | |
| 32 | +| V. Simplicity (YAGNI) | PASS | Reusing existing `ProgressPageWriter` and `FlushWriteFile` patterns; no new abstractions | |
| 33 | + |
| 34 | +No violations. All gates pass. |
| 35 | + |
| 36 | +## Project Structure |
| 37 | + |
| 38 | +### Documentation (this feature) |
| 39 | + |
| 40 | +```text |
| 41 | +specs/024-docs-skill-coverage-fix/ |
| 42 | +├── plan.md # This file |
| 43 | +├── spec.md # Feature specification |
| 44 | +├── research.md # Phase 0 output |
| 45 | +├── data-model.md # Phase 1 output |
| 46 | +├── checklists/ |
| 47 | +│ └── requirements.md # Spec quality checklist |
| 48 | +└── tasks.md # Phase 2 output (created by /speckit.tasks) |
| 49 | +``` |
| 50 | + |
| 51 | +### Source Code (repository root) |
| 52 | + |
| 53 | +```text |
| 54 | +src/ |
| 55 | +├── Spectra.CLI/ |
| 56 | +│ ├── Commands/ |
| 57 | +│ │ ├── Docs/ |
| 58 | +│ │ │ ├── DocsIndexHandler.cs # MODIFY: Add result/progress writing, --skip-criteria, fix strings |
| 59 | +│ │ │ └── DocsIndexCommand.cs # MODIFY: Add --skip-criteria option |
| 60 | +│ │ ├── Analyze/ |
| 61 | +│ │ │ └── AnalyzeCommand.cs # VERIFY: --extract-requirements alias preserved |
| 62 | +│ │ └── Init/ |
| 63 | +│ │ └── InitHandler.cs # MODIFY: Add spectra-docs SKILL to init flow |
| 64 | +│ ├── Agent/ |
| 65 | +│ │ └── Copilot/ |
| 66 | +│ │ └── RequirementsExtractor.cs # MODIFY: Fix user-facing strings |
| 67 | +│ ├── Skills/ |
| 68 | +│ │ ├── Content/ |
| 69 | +│ │ │ ├── Skills/ |
| 70 | +│ │ │ │ └── spectra-docs.md # CREATE: New SKILL file (embedded resource) |
| 71 | +│ │ │ └── Agents/ |
| 72 | +│ │ │ └── spectra-generation.agent.md # MODIFY: Update docs index flow |
| 73 | +│ │ ├── SkillContent.cs # MODIFY: Add DocsIndex property |
| 74 | +│ │ └── SkillsManifest.cs # MODIFY: Bump count 8→9 |
| 75 | +│ ├── Results/ |
| 76 | +│ │ └── DocsIndexResult.cs # MODIFY: Add new fields |
| 77 | +│ ├── Progress/ |
| 78 | +│ │ └── ProgressPageWriter.cs # MODIFY: Support docs-index status rendering |
| 79 | +│ └── Dashboard/ |
| 80 | +│ └── DataCollector.cs # MODIFY: Null-safe coverage defaults |
| 81 | +├── Spectra.Core/ |
| 82 | +│ ├── Parsing/ |
| 83 | +│ │ └── AcceptanceCriteriaParser.cs # MODIFY: Add _requirements.yaml → .bak rename |
| 84 | +│ └── Models/ |
| 85 | +│ └── Config/ |
| 86 | +│ └── CoverageConfig.cs # VERIFY: requirements_file fallback works |
| 87 | +dashboard-site/ |
| 88 | +├── scripts/ |
| 89 | +│ └── app.js # MODIFY: Fix "requirements" help text |
| 90 | +└── index.html # VERIFY: Labels already correct |
| 91 | +
|
| 92 | +tests/ |
| 93 | +├── Spectra.CLI.Tests/ |
| 94 | +│ └── Commands/ |
| 95 | +│ └── DocsIndexHandlerTests.cs # MODIFY: Add result/progress/skip-criteria tests |
| 96 | +└── Spectra.Core.Tests/ |
| 97 | + └── Parsing/ |
| 98 | + └── AcceptanceCriteriaParserTests.cs # MODIFY: Add migration tests |
| 99 | +``` |
| 100 | + |
| 101 | +**Structure Decision**: All changes fit within the existing project structure. No new projects or directories needed (except the embedded resource file for the new SKILL). |
| 102 | + |
| 103 | +## Implementation Approach |
| 104 | + |
| 105 | +### Part C: Terminology Rename (do first — unblocks everything) |
| 106 | + |
| 107 | +**C1: Fix user-facing strings in CLI** |
| 108 | + |
| 109 | +Files with remaining "requirement" strings to fix: |
| 110 | +- `src/Spectra.CLI/Agent/Copilot/RequirementsExtractor.cs`: "Extracting requirements from documentation..." → "Extracting acceptance criteria from documentation..." |
| 111 | +- `src/Spectra.CLI/Agent/Copilot/RequirementsExtractor.cs`: "Extracted {n} requirement(s)" → "Extracted {n} acceptance criteria" |
| 112 | +- `dashboard-site/scripts/app.js` line ~1386: Help text references "requirements field" → "criteria field" |
| 113 | + |
| 114 | +**Exclude from rename** (intentional backward compat): |
| 115 | +- `--extract-requirements` hidden alias in `AnalyzeCommand.cs` |
| 116 | +- `requirements` YAML key fallback in `AcceptanceCriteriaParser.cs` |
| 117 | +- `RequirementsFile` config property (read fallback) |
| 118 | +- Class names (`RequirementsExtractor`, `RequirementsWriter`, `RequirementsParser`) — renaming these would be a larger refactor; the spec says only user-facing strings |
| 119 | + |
| 120 | +**C2: Auto-rename `_requirements.yaml` in criteria reader** |
| 121 | + |
| 122 | +In `AcceptanceCriteriaParser.cs` (or the `CriteriaIndexReader`), when attempting to read criteria: |
| 123 | +1. Check if `_criteria_index.yaml` exists → use it |
| 124 | +2. If not, check if `_requirements.yaml` exists → rename to `_requirements.yaml.bak`, log message |
| 125 | +3. Return empty/null criteria (fresh `_criteria_index.yaml` will be created by next extraction run) |
| 126 | + |
| 127 | +### Part D: Dashboard Coverage Fix |
| 128 | + |
| 129 | +**D1: Fix help text in app.js** |
| 130 | + |
| 131 | +The dashboard JS already uses `acceptance_criteria` field names correctly (confirmed by research). Only the empty-state help text at line ~1386 references "requirements". Fix that one string. |
| 132 | + |
| 133 | +**D2: Null-safe coverage defaults in DataCollector** |
| 134 | + |
| 135 | +Ensure `DataCollector.CollectAsync()` never produces null sections. If criteria data is missing, provide zero-state: |
| 136 | +```csharp |
| 137 | +AcceptanceCriteria = criteriaCoverage ?? new AcceptanceCriteriaSectionData { Covered = 0, Total = 0, Percentage = 0, HasCriteriaFile = false, Details = [] } |
| 138 | +``` |
| 139 | + |
| 140 | +### Part A: DocsIndexHandler Result & Progress |
| 141 | + |
| 142 | +**A1: Extend `DocsIndexResult` model** |
| 143 | + |
| 144 | +Add fields to match the spec's result schema: |
| 145 | +- `DocumentsNew` (int) |
| 146 | +- `DocumentsChanged` (int) |
| 147 | +- `DocumentsUnchanged` (int) |
| 148 | +- `CriteriaExtracted` (int, nullable) |
| 149 | +- `CriteriaFile` (string, nullable) |
| 150 | + |
| 151 | +**A2: Add result/progress file writing to DocsIndexHandler** |
| 152 | + |
| 153 | +Replicate the `GenerateHandler` pattern: |
| 154 | +1. Delete stale `.spectra-result.json` and `.spectra-progress.html` at start |
| 155 | +2. Write in-progress result with status `"scanning"` → `"indexing"` → `"extracting-criteria"` |
| 156 | +3. Call `ProgressPageWriter.WriteProgressPage()` at each phase transition |
| 157 | +4. Write final result with status `"completed"` or `"failed"` |
| 158 | +5. Use `FlushWriteFile` for Windows NTFS reliability |
| 159 | + |
| 160 | +**A3: Extend `ProgressPageWriter` for docs-index** |
| 161 | + |
| 162 | +The existing `ProgressPageWriter.WriteProgressPage()` parses JSON `status` field and renders phase-appropriate HTML. Current phases: `analyzing`, `analyzed`, `generating`, `completed`, `failed`. |
| 163 | + |
| 164 | +Add handling for docs-index statuses: `scanning`, `indexing`, `extracting-criteria`. The writer will render: |
| 165 | +- Phase stepper: Scanning → Indexing → Extracting Criteria → Completed |
| 166 | +- Summary cards: documents scanned, indexed, skipped, criteria extracted |
| 167 | +- Same auto-refresh and `vscode://file/` link patterns |
| 168 | + |
| 169 | +**A4: Add `--skip-criteria` flag** |
| 170 | + |
| 171 | +In `DocsIndexCommand.cs`, add `--skip-criteria` option. Pass through to `DocsIndexHandler`. When set, skip the `TryExtractRequirementsAsync()` call. |
| 172 | + |
| 173 | +**A5: Pass `--no-interaction` to criteria extraction** |
| 174 | + |
| 175 | +The `TryExtractRequirementsAsync()` method doesn't currently receive the `noInteraction` flag. Thread it through so criteria extraction runs non-interactively when the parent command is non-interactive. |
| 176 | + |
| 177 | +### Part B: New SKILL — `spectra-docs` |
| 178 | + |
| 179 | +**B1: Create embedded SKILL file** |
| 180 | + |
| 181 | +Create `src/Spectra.CLI/Skills/Content/Skills/spectra-docs.md` with the structured tool-call-sequence format matching existing SKILL patterns. Include: |
| 182 | +- `show preview .spectra-progress.html` step |
| 183 | +- `runInTerminal: spectra docs index --no-interaction --output-format json --verbosity quiet` |
| 184 | +- `awaitTerminal` |
| 185 | +- `readFile .spectra-result.json` |
| 186 | +- Result presentation instructions |
| 187 | +- Next step suggestions |
| 188 | + |
| 189 | +**B2: Update SkillContent.cs** |
| 190 | + |
| 191 | +Add `DocsIndex` static property pointing to the new embedded resource. |
| 192 | + |
| 193 | +**B3: Update SkillsManifest** |
| 194 | + |
| 195 | +The manifest auto-discovers embedded resources, so no manual count bump needed — just ensure the `.md` file is set as an embedded resource in the `.csproj`. |
| 196 | + |
| 197 | +**B4: Update InitHandler** |
| 198 | + |
| 199 | +The `CreateBundledSkillFilesAsync` method iterates `SkillContent.All` which auto-includes new SKILLs. Verify it works. |
| 200 | + |
| 201 | +**B5: Update generation agent prompt** |
| 202 | + |
| 203 | +In `spectra-generation.agent.md`, update the docs index section to reference progress page and `--no-interaction`. |
0 commit comments