feat(scripts): spec_render + roadmap_render v0.20 GA blockers (#458, #434, #435)#474
Conversation
|
| Filename | Overview |
|---|---|
| scripts/roadmap_render.py | Adds _read_edge_endpoints helper and updates _build_edge_map to support both {from,to} and {source,target} edge conventions; logic is correct and the or-chain correctly treats empty-string canonical keys the same as absent ones. |
| scripts/spec_render.py | Adds SPECIFICATION_NARRATIVE_KEY_ORDER, narrative-ordered rendering, lifecycle-scope aggregator (--include-scopes), and bilingual edge reader; the heading level collision between ### Pending bucket headers and ### stem: title scope entries is a readability P2. |
| tests/cli/test_spec_render.py | Comprehensive test suite covering narrative ordering, alphabetical-remaining-keys, legacy interview shape, aggregator with status-pin filter, --include-scopes=off regression, CLI smoke tests, bilingual edge ordering, and graceful-skip for missing folders. |
| tests/cli/test_roadmap_render.py | Switches primary edge fixture to canonical {from,to}, adds legacy {source,target} regression fixture, mixed-keys fixture with canonical-wins assertion, and a topo-ordering regression test for legacy edges; all well-scoped. |
| CHANGELOG.md | Three [Unreleased] entries added, one per commit; format is consistent with existing entries. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[spec_render.main] --> B{--include-scopes?}
B -- "on (default)" --> C[render_spec include_scopes=True]
B -- "off" --> D[render_spec include_scopes=False]
C --> E[validate_spec]
D --> E
E --> F[Render H1 title]
F --> G[Render narratives in SPECIFICATION_NARRATIVE_KEY_ORDER]
G --> H[Render remaining keys alphabetically]
H --> I[Render plan.items]
I --> J{include_scopes?}
J -- yes --> K[_aggregate_scope_section vbrief_dir]
J -- no --> M[Write output file]
K --> L1[_load_scope_vbriefs pending/]
K --> L2[_load_scope_vbriefs active/]
K --> L3[_load_scope_vbriefs completed/ status-pin filter]
L1 --> N[Per-bucket: _cross_scope_dep_map]
L2 --> N
L3 --> N
N --> O[_topo_sort_scopes bilingual _read_edge_endpoints]
O --> P[_render_scope_block stem: title + summary + Acceptance]
P --> M
Prompt To Fix All With AI
This is a comment left during a code review.
Path: scripts/spec_render.py
Line: 248-254
Comment:
**Same heading level for bucket headers and scope entries**
Both `### Pending` / `### Active` / `### Completed` bucket headers and the per-scope `### stem: title` headings use H3. In the rendered output they are visually indistinguishable, so a reader scanning the document (or a TOC) cannot tell bucket labels apart from individual scope entries without reading the text.
Consider bumping scope headings to H4 (`#### {stem}: {title}`) so the hierarchy maps cleanly: `## Implementation Plan` → `### Pending` → `#### scope: title`.
(Change requires also updating `_render_scope_block` to emit `####` and updating matching test assertions.)
How can I resolve this? If you propose a fix, please make it concise.Reviews (2): Last reviewed commit: "feat(scripts): spec_render aggregates sc..." | Re-trigger Greptile
e27ab54 to
c6d8929
Compare
Summary
Three v0.20 GA blockers for the spec / roadmap renderers, delivered as one
PR against
phase2/vbrief-cutover. Each task ships as its own commit with amatching CHANGELOG.md entry under
[Unreleased].Closes #458, closes #434, closes #435.
Changes
Task A (#458) — bilingual edge reader
scripts/roadmap_render._build_edge_mapnow reads both the schema-canonical{from,to}and legacy{source,target}edge conventions via a new_read_edge_endpointshelper. When both forms are present on a single edge,canonical
from/towins. The primary test fixture intests/cli/test_roadmap_render.pyis switched to{from,to}; legacyregression and mixed-keys-within-single-plan fixtures are added, with direct
_build_edge_mapassertions plus a topological-ordering regression test.strategies/speckit.mdPhase 4 edge example already uses{from,to}.Task B (#434) — narrative-ordered spec_render
scripts/spec_render.pynow mirrors the narrative-centric model fromprd_render.py. A newSPECIFICATION_NARRATIVE_KEY_ORDERcovers both theinterview/light and speckit key sets (Overview, ProblemStatement, Goals,
UserStories, Requirements, SuccessMetrics, EdgeCases, Architecture,
TechDecisions, ImplementationPhases, PreImplementationGates). Present
narratives render in declared order first, then remaining keys alphabetically,
then
plan.itemsfor hybrid/legacy specs. Eliminates the 44-byte H1-onlyfailure mode for speckit-shaped specs.
New
tests/cli/test_spec_render.pyadds:## ProblemStatement,## Goals,## Requirementsheadings with non-empty bodiesTask C (#435) — lifecycle-scope aggregator
scripts/spec_render.pygains a--include-scopesflag (default on) thatwalks
vbrief/pending/,vbrief/active/, andvbrief/completed/relative tothe spec file and emits an
## Implementation Plansection grouped into### Pending,### Active,### Completedsub-buckets. Each scope rendersas
### <filename-stem>: <title>with status code-span, its summarynarrative (resolved Overview -> Summary -> Description -> ProblemStatement ->
Problem -> Outcome -> first non-empty string narrative), and an
**Acceptance**bullet list ofplan.items. The Completed bucket isstatus-pinned, so misfiled pending/active scopes in
completed/do not leak.Cross-scope ordering uses the same bilingual edge reader pattern from Task A
(replicated inline as
spec_render._read_edge_endpoints), so{from,to}and{source,target}edges between scope IDs (plan.idor filename stem) bothdrive topological ordering.
--include-scopes=offfalls back to thepre-aggregator output.
Tests added: full aggregator fixture test,
--include-scopes=offregression,CLI default-on smoke test, CLI
--include-scopes=offsmoke test, cross-scopebilingual-edge ordering test, and a no-lifecycle-folders graceful-skip test.
Scope
Touches only:
scripts/roadmap_render.pyscripts/spec_render.pytests/cli/test_roadmap_render.pytests/cli/test_spec_render.pyCHANGELOG.mdDoes not touch any files owned by other agents in this swarm
(
migrate_vbrief.py,issue_ingest.py,speckit.md,vbrief.md,glossary.md, README,UPGRADING.md,Taskfile.yml, or any skilldocuments).
Validation
task checkwas run before each of the three commits. Final run on thepushed HEAD: 212 markdown files validated; 1692 tests passed, 1 xfailed;
verify:stubsclean;toolchain:checkgreen; vBRIEF validation passes(42 scope vBRIEFs, 4 pre-existing warnings unrelated to this PR).
Commits
fix(scripts): roadmap_render._build_edge_map reads both {from,to} and {source,target} (#458)fix(scripts): spec_render renders narratives in declared order (#434)feat(scripts): spec_render aggregates scope vBRIEFs from lifecycle folders (#435)Checklist
agent2/ga-renderers/458-434-435-spec-render-edges)[Unreleased]for every committask checkpassed before each commit