fix(scripts): project_render.py SKELETON_NARRATIVES matches validator (#405)#413
Conversation
…#405) - Rename `TechStack` skeleton key to `tech stack` so `task project:render` skeletons satisfy `vbrief_validate.py` PROJECT_DEF_EXPECTED_NARRATIVES (`tech stack` after `.lower()`) immediately, unblocking `task check`. - Update `test_skeleton_has_empty_narratives` assertion to the new key. - `_split_camel` still splits the new key into `['tech', 'stack']` so staleness flagging for the TechStack narrative is unchanged. - Add scope vBRIEF `vbrief/active/2026-04-16-405-project-render-tech-stack-key.vbrief.json` with origin provenance to #405 and #402. Closes #405 Part of #402
|
| Filename | Overview |
|---|---|
| scripts/project_render.py | Renames SKELETON_NARRATIVES["TechStack"] to "tech stack" and adds a cross-reference comment; the fix is correct and the _split_camel staleness logic remains unaffected. One stale "TechStack" reference survives in the agent-workflow docstring. |
| tests/cli/test_project_render.py | Updates test_skeleton_has_empty_narratives to assert "tech stack" instead of "TechStack"; all other test fixtures that use "TechStack" are testing existing-document preservation (not skeleton creation), so they remain correct. |
| vbrief/active/2026-04-16-405-project-render-tech-stack-key.vbrief.json | New scope vBRIEF tracking this fix; schema is valid (v0.5, status "running" in active/), origin provenance references #405 and #402, no issues. |
| CHANGELOG.md | Fixed entry added under [Unreleased] correctly describing the key rename, test update, and staleness-flagging continuity. No issues. |
Sequence Diagram
sequenceDiagram
participant U as User
participant PR as project_render.py
participant PD as PROJECT-DEFINITION.vbrief.json
participant VV as vbrief_validate.py
U->>PR: task project:render
PR->>PD: create skeleton (SKELETON_NARRATIVES)
Note over PD: narratives keys include<br/>"tech stack" (fixed)
U->>VV: task vbrief:validate
VV->>PD: read narratives keys
VV->>VV: narrative_keys_lower = {k.lower() for k in narratives}<br/>check "tech stack" in narrative_keys_lower
Note over VV: "tech stack".lower() == "tech stack" ✓<br/>(was "TechStack".lower() == "techstack" ✗)
VV-->>U: PASS
Prompt To Fix All With AI
This is a comment left during a code review.
Path: scripts/project_render.py
Line: 25
Comment:
**Stale docstring references old key name**
The inline docstring on line 25 still says "update the `TechStack` narrative" — this should now read "`tech stack` narrative" to match the renamed key.
```suggestion
the completed scopes (e.g. if a "tech stack" scope completed, update the
tech stack narrative with the new technology choices).
```
How can I resolve this? If you propose a fix, please make it concise.Reviews (1): Last reviewed commit: "fix(scripts): project_render.py SKELETON..." | Re-trigger Greptile
|
Acknowledging the P2 finding on Not fixing in this PR per the swarm-402 charter severity ladder — P2 items are non-blocking style/nit/opinion and Confidence 5/5 + all CI green + no P0/P1 ⇒ proceeding to self-merge per the PO Pre-Approval gate on #402. |
Summary
Issue #405 reports that
scripts/project_render.pySKELETON_NARRATIVESuses theTechStackcamelCase key, butscripts/vbrief_validate.pyPROJECT_DEF_EXPECTED_NARRATIVESrequirestech stack(space-separated) after.lower(). As a result, the skeleton produced bytask project:renderimmediately failstask vbrief:validate(part oftask check).This PR fixes the key so the skeleton passes the validator end-to-end, matching the convention already used by
scripts/migrate_vbrief.py(which writesnarratives["tech stack"]).Changes
scripts/project_render.py— renameSKELETON_NARRATIVES["TechStack"]→SKELETON_NARRATIVES["tech stack"]; added a comment block cross-referencing D3 and the validator so the contract is explicit.tests/cli/test_project_render.py— update theTestSkeletonCreation::test_skeleton_has_empty_narrativesassertion to check the new key.vbrief/active/2026-04-16-405-project-render-tech-stack-key.vbrief.json— new scope vBRIEF with origin provenance to fix(scripts): project_render.py SKELETON_NARRATIVES TechStack key breaks vbrief:validate #405 and Pre-merge validation gate for vBRIEF cutover (#338) #402.CHANGELOG.md— Fixed entry under[Unreleased].Why the camel-case splitter still works
_split_camelusesre.sub(r"([a-z])([A-Z])", r"\1 \2", name)and then splits on whitespace and lowercases, so_split_camel("tech stack")splits on the existing space and yields['tech', 'stack']. Staleness flagging for the TechStack narrative is therefore unchanged by this rename.Validation
task check— passed locally (1539 passed, 1 xfailed).task project:renderagainst this worktree emits"tech stack": ""as expected;task vbrief:validatepasses on the fresh skeleton.Scope & constraints
scripts/project_render.py,tests/cli/test_project_render.py) plus the scope vBRIEF and CHANGELOG entry.TechStacknarrative (runcmd_project at line 1161, documentation examples, other tests) are intentionally out of scope for this narrow fix; thecmd_projectcase is a downstream instance of the same bug and will be filed separately if it matters for the v0.20.0 merge gate.Part of #402 pre-merge must-fix batch
This is PR 1 of 4 in the swarm-402 cascade on
phase2/vbrief-cutover.Closes #405
Refs #402