Skip to content

Commit d9654bf

Browse files
Docs index SKILL, progress page, coverage fix & terminology rename
- Add .spectra-result.json and .spectra-progress.html to DocsIndexHandler - Add --skip-criteria and --no-interaction support to docs index command - Extend DocsIndexResult with new fields (skipped, new, total, criteria) - Extend ProgressPageWriter for docs-index phases (scanning, indexing, extracting-criteria) - Create spectra-docs SKILL (9th bundled SKILL) with structured tool-call-sequence - Fix remaining "requirements" → "acceptance criteria" in user-facing strings - Add _requirements.yaml → .bak auto-rename in CriteriaIndexReader - Fix dashboard coverage null crash with zero-state defaults - Fix app.js empty-state help text ("requirements" → "criteria") - Update generation agent prompt for docs index progress-aware flow - Bump version to 1.30.0
1 parent 1336356 commit d9654bf

File tree

22 files changed

+1105
-47
lines changed

22 files changed

+1105
-47
lines changed

dashboard-site/scripts/app.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1331,6 +1331,7 @@ function renderCoverageGaps(summary) {
13311331
* Render a single coverage section with progress bar, empty state, and detail toggle.
13321332
*/
13331333
function renderCoverageSection(label, sectionData, unit, renderDetailsFn) {
1334+
sectionData = sectionData || { covered: 0, total: 0, percentage: 0 };
13341335
const pct = sectionData.percentage || 0;
13351336
const colorClass = pct >= 80 ? 'coverage-green' : pct >= 50 ? 'coverage-yellow' : 'coverage-red';
13361337
const covered = sectionData.covered || 0;
@@ -1383,7 +1384,7 @@ function getEmptyState(label, sectionData, total, pct) {
13831384
return `<div class="coverage-empty-state">
13841385
<span class="empty-icon">&#9432;</span>
13851386
<div class="empty-text"><strong>No acceptance criteria tracked yet.</strong>
1386-
Add a <code>requirements</code> field to test YAML frontmatter, or create a <code>_criteria_index.yaml</code> file in your docs directory.</div>
1387+
Add a <code>criteria</code> field to test YAML frontmatter, or create a <code>_criteria_index.yaml</code> file in your docs directory.</div>
13871388
</div>`;
13881389
}
13891390
return null;
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Specification Quality Checklist: Docs Index Progress, SKILL Integration & Coverage Dashboard Fix
2+
3+
**Purpose**: Validate specification completeness and quality before proceeding to planning
4+
**Created**: 2026-04-08
5+
**Feature**: [spec.md](../spec.md)
6+
7+
## Content Quality
8+
9+
- [x] No implementation details (languages, frameworks, APIs)
10+
- [x] Focused on user value and business needs
11+
- [x] Written for non-technical stakeholders
12+
- [x] All mandatory sections completed
13+
14+
## Requirement Completeness
15+
16+
- [x] No [NEEDS CLARIFICATION] markers remain
17+
- [x] Requirements are testable and unambiguous
18+
- [x] Success criteria are measurable
19+
- [x] Success criteria are technology-agnostic (no implementation details)
20+
- [x] All acceptance scenarios are defined
21+
- [x] Edge cases are identified
22+
- [x] Scope is clearly bounded
23+
- [x] Dependencies and assumptions identified
24+
25+
## Feature Readiness
26+
27+
- [x] All functional requirements have clear acceptance criteria
28+
- [x] User scenarios cover primary flows
29+
- [x] Feature meets measurable outcomes defined in Success Criteria
30+
- [x] No implementation details leak into specification
31+
32+
## Notes
33+
34+
- All items pass. The spec is ready for `/speckit.clarify` or `/speckit.plan`.
35+
- The spec makes reasonable assumptions about existing infrastructure (ProgressHtmlWriter, DocsIndexResult model) documented in the Assumptions section.
36+
- No [NEEDS CLARIFICATION] markers were needed — the feature description was comprehensive enough to make informed decisions for all aspects.
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# Data Model: 024-docs-skill-coverage-fix
2+
3+
## Modified Entities
4+
5+
### DocsIndexResult (extend existing)
6+
7+
**File**: `src/Spectra.CLI/Results/DocsIndexResult.cs`
8+
9+
Current fields:
10+
- `DocumentsIndexed` (int)
11+
- `DocumentsUpdated` (int)
12+
- `IndexPath` (string)
13+
14+
New fields:
15+
- `DocumentsSkipped` (int) — documents unchanged (hash match)
16+
- `DocumentsNew` (int) — documents added to index for the first time
17+
- `DocumentsTotal` (int) — total documents found
18+
- `CriteriaExtracted` (int?) — number of acceptance criteria extracted (null if skipped)
19+
- `CriteriaFile` (string?) — path to `_criteria_index.yaml` (null if skipped)
20+
21+
Inherited from `CommandResult`:
22+
- `Command` (string) = "docs-index"
23+
- `Status` (string) = "completed" | "failed"
24+
- `Timestamp` (DateTimeOffset)
25+
- `Message` (string?)
26+
27+
### DocsIndexResult JSON Schema
28+
29+
```json
30+
{
31+
"command": "docs-index",
32+
"status": "completed",
33+
"message": "Documentation index updated",
34+
"timestamp": "2026-04-08T14:30:00Z",
35+
"documentsIndexed": 12,
36+
"documentsUpdated": 4,
37+
"documentsSkipped": 3,
38+
"documentsNew": 2,
39+
"documentsTotal": 15,
40+
"indexPath": "docs/_index.md",
41+
"criteriaExtracted": 45,
42+
"criteriaFile": "docs/requirements/_criteria_index.yaml"
43+
}
44+
```
45+
46+
### In-Progress Result JSON (for `.spectra-result.json` during execution)
47+
48+
```json
49+
{
50+
"command": "docs-index",
51+
"status": "indexing",
52+
"message": "Indexing checkout.md (3/15)...",
53+
"timestamp": "2026-04-08T14:30:00Z",
54+
"documentsIndexed": 2,
55+
"documentsTotal": 15,
56+
"indexPath": "docs/_index.md"
57+
}
58+
```
59+
60+
Status lifecycle: `scanning``indexing``extracting-criteria``completed` | `failed`
61+
62+
## Unchanged Entities (verified correct)
63+
64+
### CoverageSummaryData
65+
66+
Already uses correct field names post-spec-023:
67+
- `DocumentationSectionData` (serialized as `documentation`)
68+
- `AcceptanceCriteriaSectionData` (serialized as `acceptance_criteria`)
69+
- `AutomationSectionData` (serialized as `automation`)
70+
71+
No changes needed to the model. Fix is in `DataCollector` to ensure non-null defaults.
72+
73+
### AcceptanceCriteriaSectionData
74+
75+
Fields already correct:
76+
- `Covered` (int)
77+
- `Total` (int)
78+
- `Percentage` (decimal)
79+
- `HasCriteriaFile` (bool)
80+
- `Details` (list of `CriteriaCoverageDetail`)
81+
82+
## File Rename Behavior
83+
84+
### `_requirements.yaml``_requirements.yaml.bak`
85+
86+
**Trigger**: Any criteria reader access when `_criteria_index.yaml` does not exist but `_requirements.yaml` does.
87+
88+
**Actions**:
89+
1. `File.Move("_requirements.yaml", "_requirements.yaml.bak")`
90+
2. Log: "Renamed _requirements.yaml → _requirements.yaml.bak (legacy format)"
91+
3. Return empty criteria set (next extraction will create fresh `_criteria_index.yaml`)
92+
93+
**No new models needed** for this behavior.
Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
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 neededjust 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

Comments
 (0)