Skip to content

feat(tasks): add project:render PROJECT-DEFINITION regeneration tool (#323)#342

Merged
MScottAdams merged 2 commits intophase2/vbrief-cutoverfrom
agent4/feat/323-project-render
Apr 13, 2026
Merged

feat(tasks): add project:render PROJECT-DEFINITION regeneration tool (#323)#342
MScottAdams merged 2 commits intophase2/vbrief-cutoverfrom
agent4/feat/323-project-render

Conversation

@MScottAdams
Copy link
Copy Markdown
Collaborator

Summary

Add deterministic PROJECT-DEFINITION regeneration tool ( ask project:render) per RFC #309 Decision D14.

Deterministic layer (scripts/project_render.py):

  • Scans all 5 lifecycle folders (proposed/, pending/, active/, completed/, cancelled/) for *.vbrief.json files
  • Updates items registry in �brief/PROJECT-DEFINITION.vbrief.json with scope entries (title, status, file path, references)
  • Timestamps freshness (�BRIEFInfo.updated)
  • Flags narratives that may be stale based on completed scope topics (camelCase-aware keyword matching + general threshold)
  • Creates skeleton with empty narratives if no PROJECT-DEFINITION exists
  • Handles missing/empty lifecycle folders and malformed files gracefully

Agent-assisted layer (documented in code comments, not implemented as code):

  • During sync/refinement, agent reads staleness flags and proposes narrative updates
  • User approves -- never fully automatic for content requiring judgment

Taskfile integration:

  • asks/project.yml with PYTHONUTF8=1 for Windows compatibility
  • Include + alias wired in Taskfile.yml

Tests: 23 subprocess-based tests in ests/cli/test_project_render.py covering skeleton creation, 5-folder scanning, update preservation, timestamp refresh, staleness flagging, determinism, graceful error handling, CLI usage.

Checklist

  • CHANGELOG.md entry under [Unreleased]
  • ask check passes (1055 tests, 0 failures)
  • New source file has corresponding test file
  • Feature branch (not direct commit to master)
  • Conventional commit message

Part of #309. Closes #323. Tracking: #338.

@MScottAdams MScottAdams force-pushed the agent4/feat/323-project-render branch from 890cbea to 168978f Compare April 13, 2026 18:19
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 13, 2026

Greptile Summary

Adds task project:render — a deterministic tool that scans all 5 lifecycle folders and regenerates vbrief/PROJECT-DEFINITION.vbrief.json (items registry, freshness timestamp, staleness flags), creating a skeleton if none exists. The three previously flagged issues (circular alias, USER_WORKING_DIR, whitespace-only title split) are all resolved in the fix commit.

Confidence Score: 5/5

Safe to merge — all previously flagged P1 issues are resolved and remaining findings are display-only P2 nits.

The three prior review concerns (circular alias, invocation-relative path, whitespace-only title split) are all fixed in the batch fix commit. The only remaining findings are a singular/plural grammar nit in the output message and a redundant exists() call — neither affects correctness or test coverage.

No files require special attention.

Important Files Changed

Filename Overview
scripts/project_render.py Core render script — deterministic scanning, staleness flagging, and skeleton creation are all correct; two minor style issues (plural grammar nit, redundant exists() call)
tests/cli/test_project_render.py 23 subprocess-based tests covering all major paths; test at line 259 also asserts "1 scope items" (mirrors the grammar nit in the source), otherwise thorough
tasks/project.yml Single render task using {{.ROOT_DIR}} (correct, invocation-directory-independent) with PYTHONUTF8=1 env var for Windows compatibility
Taskfile.yml project include wired in; previously flagged circular project:render alias has been removed — task is accessible as project:render via the include namespace
CHANGELOG.md Unreleased entry added following existing verbose format; covers feature scope accurately

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A([task project:render]) --> B[render_project_definition]
    B --> C[scan_lifecycle_folders\nproposed/pending/active/\ncompleted/cancelled]
    C --> D{*.vbrief.json\nfound?}
    D -->|valid JSON| E[Extract title, status,\nrefs → items list]
    D -->|parse error| F[Append unreadable\nitem with status=draft]
    E --> G[Build items list]
    F --> G
    G --> H{PROJECT-DEFINITION\nexists?}
    H -->|no| I[create_skeleton\nitems + timestamps +\nempty narratives]
    H -->|yes| J[Load existing file]
    J --> K[Replace items registry]
    K --> L[Refresh vBRIEFInfo.updated]
    L --> M[flag_stale_narratives\nfor completed items]
    M --> N{keyword overlap\nor ≥3 completed?}
    N -->|yes| O[Append staleness flags]
    N -->|no| P[No flags]
    O --> Q[Write JSON output]
    P --> Q
    I --> Q
    Q --> R([Print summary report\n✓ N scope items])
Loading
Prompt To Fix All With AI
This is a comment left during a code review.
Path: scripts/project_render.py
Line: 251

Comment:
**Singular/plural inconsistency in output message**

The format string always uses `"scope items"` regardless of count, producing `"1 scope items"` when a single scope is found. The test in `tests/cli/test_project_render.py` (line 259) also asserts `"1 scope items"` so both would need updating together.

```suggestion
    noun = "item" if item_count == 1 else "items"
    parts = [f"✓ PROJECT-DEFINITION.vbrief.json {action} ({item_count} scope {noun})"]
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: scripts/project_render.py
Line: 207-209

Comment:
**Redundant `exists()` calls**

`created_new` is computed from `project_def_path.exists()` on line 207, then `project_def_path.exists()` is called again on line 209 instead of reusing `created_new`. The second call is redundant and creates a minor TOCTOU window.

```suggestion
    created_new = not project_def_path.exists()

    if not created_new:
```

How can I resolve this? If you propose a fix, please make it concise.

Reviews (3): Last reviewed commit: "fix: address Greptile review findings (b..." | Re-trigger Greptile

Comment thread Taskfile.yml Outdated
Comment thread tasks/project.yml Outdated
Comment thread scripts/project_render.py Outdated
…323)

- Create scripts/project_render.py: deterministic regeneration for
  vbrief/PROJECT-DEFINITION.vbrief.json per RFC #309 Decision D14
- Scan all 5 lifecycle folders (proposed/, pending/, active/,
  completed/, cancelled/) for *.vbrief.json scope files
- Update items registry with title, status, file path, and references
- Timestamp freshness via vBRIEFInfo.updated on each run
- Flag stale narratives based on completed scope topic keywords
  (camelCase-aware key splitting + general threshold at >=3 completed)
- Create skeleton with empty narratives if no PROJECT-DEFINITION exists
- Handle missing/empty lifecycle folders and malformed files gracefully
- Document agent-assisted narrative review layer in code comments
- Add tasks/project.yml with PYTHONUTF8=1 for Windows compatibility
- Wire as project:render include + alias in Taskfile.yml
- Add 23 subprocess-based tests in tests/cli/test_project_render.py
  covering skeleton creation, 5-folder scanning, update preservation,
  timestamp refresh, staleness flagging, determinism, error handling,
  and CLI argument validation
- Add CHANGELOG.md entry under [Unreleased]
- Remove circular project:render alias from Taskfile.yml (P1): the
  included task is already accessible as project:render without an alias
- Switch USER_WORKING_DIR to ROOT_DIR in tasks/project.yml (P2): ensures
  vbrief/ path resolves to project root regardless of invocation directory
- Use re.split for title word extraction in staleness flagging (P2):
  catches hyphenated title words like 'tech-stack' that whitespace-only
  split would miss
- MCP unavailable in this session -- used gh api fallback for review
  comments
@MScottAdams MScottAdams force-pushed the agent4/feat/323-project-render branch from 688bfe1 to 5e6071a Compare April 13, 2026 19:12
@MScottAdams MScottAdams merged commit 4904ab1 into phase2/vbrief-cutover Apr 13, 2026
@MScottAdams MScottAdams deleted the agent4/feat/323-project-render branch April 13, 2026 19:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant