Skip to content

feat(tasks): add migrate:vbrief migration script for vBRIEF-centric cutover (#312)#341

Merged
MScottAdams merged 4 commits intophase2/vbrief-cutoverfrom
agent3/feat/312-migration-script
Apr 13, 2026
Merged

feat(tasks): add migrate:vbrief migration script for vBRIEF-centric cutover (#312)#341
MScottAdams merged 4 commits intophase2/vbrief-cutoverfrom
agent3/feat/312-migration-script

Conversation

@MScottAdams
Copy link
Copy Markdown
Collaborator

Summary

Add automated migration script ( ask migrate:vbrief) that converts existing Deft projects from the current document model to the new vBRIEF-centric folder structure defined by RFC #309.

Changes

New Files

  • scripts/migrate_vbrief.py -- Migration script implementing:
    • Parse specification.vbrief.json + PROJECT.md to generate PROJECT-DEFINITION.vbrief.json (narratives for project identity, items as scope registry per D3)
    • Create 5 lifecycle folders: proposed/, pending/, �ctive/, completed/, cancelled/ (D13)
    • Convert ROADMAP.md items to individual pending/ scope vBRIEFs with origin provenance (D11)
    • Replace SPECIFICATION.md and PROJECT.md with deprecation redirects containing sentinel for Story S (Story S: Pre-cutover detection and backward compatibility guard #334) integrity checks
    • Detect user-customized content before replacing and preserve in PROJECT-DEFINITION narratives
    • Idempotent -- safe to run multiple times
  • ** asks/migrate.yml** -- Task definition registering ask migrate:vbrief
  • ** ests/cli/test_migrate_vbrief.py** -- 40 unit tests covering all migration logic

Modified Files

  • Taskfile.yml -- Added migrate include entry
  • CHANGELOG.md -- Added entry under [Unreleased]

Acceptance Criteria

  • ask migrate:vbrief converts existing project files to new structure
  • PROJECT-DEFINITION.vbrief.json generated with correct schema (narratives + items)
  • Lifecycle folders created (all 5: proposed, pending, active, completed, cancelled)
  • Existing �brief/specification.vbrief.json content preserved (not lost)
  • SPECIFICATION.md and PROJECT.md replaced with deprecation redirects containing sentinel
  • Pre-replace content check warns if files were user-customized
  • New script has corresponding test file in ests/
  • Migration is idempotent (safe to run twice)
  • ask check passes

References

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

Checklist

  • ask check passes (1055 passed, 2 xfailed)
  • CHANGELOG.md entry under [Unreleased]
  • New source files have corresponding test files (40 tests)
  • Conventional commit message
  • Feature branch (not direct to master)
  • /deft:change -- N/A (cloud agent, solo project, covered by quality gate)

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 13, 2026

Greptile Summary

This PR adds task migrate:vbrief, a one-shot migration script that converts an existing Deft project from the legacy SPECIFICATION.md/PROJECT.md/ROADMAP.md layout to the vBRIEF lifecycle folder structure defined in RFC #309. The three issues flagged in prior review rounds have been resolved: the issue number is now embedded in scope vBRIEF filenames to prevent slug collisions, _fold_custom_content uses setdefault chains to avoid mutating orphaned temporaries, and the [0.19.0] CHANGELOG date has been restored.

Confidence Score: 5/5

Safe to merge; all previously raised P1 findings are addressed and only a docstring inaccuracy remains

All three prior P1/P2 findings (slug collision, setdefault data loss, missing CHANGELOG date) are fixed in the round-3 batch commits. The only new finding is a misleading docstring on _resolve_repo_url (P2). 40 tests cover the critical code paths including idempotency, fold-failure abort, and slug-collision guard.

No files require special attention

Important Files Changed

Filename Overview
scripts/migrate_vbrief.py Core migration logic; previous-round P1 fixes (number-in-filename, setdefault chain) are applied; one stale docstring on _resolve_repo_url remains
tests/cli/test_migrate_vbrief.py 40 tests covering lifecycle folder creation, project-definition generation, roadmap conversion, slug-collision guard, deprecation redirects, customization detection, fold-failure abort, and CLI subprocess — good coverage of the changed code paths
tasks/migrate.yml Single-task Taskfile correctly passes USER_WORKING_DIR as the project root argument; wired into root Taskfile.yml as optional include
Taskfile.yml Added migrate include entry (optional: true) following existing include conventions; no other changes
CHANGELOG.md Entry added under [Unreleased]; [0.19.0] date restored to - 2026-04-13; format conforms to Keep a Changelog

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A([task migrate:vbrief]) --> B[Step 1: Create 5 lifecycle folders\nproposed/ pending/ active/ completed/ cancelled/]
    B --> C[Step 2: Read existing sources\nspecification.vbrief.json · SPECIFICATION.md\nPROJECT.md · ROADMAP.md]
    C --> D{PROJECT-DEFINITION\nalready exists?}
    D -- No --> E[Step 3: Generate\nPROJECT-DEFINITION.vbrief.json\nnarratives + items registry]
    D -- Yes --> F[SKIP idempotent]
    E --> G
    F --> G[Step 4: For each ROADMAP item]
    G --> H{Exact filename\nexists in pending/?}
    H -- Yes --> I[SKIP idempotent]
    H -- No --> J{Any lifecycle folder\nreferences issue #N?}
    J -- Yes --> K[SKIP existing vBRIEF]
    J -- No --> L[CREATE pending/DATE-N-slug.vbrief.json]
    I --> M
    K --> M
    L --> M[Step 5: Deprecation redirects]
    M --> N{SPECIFICATION.md\nhas sentinel?}
    N -- No --> O{User-customized?}
    O -- Yes --> P[_fold_custom_content into\nPROJECT-DEFINITION narratives]
    P --> Q{Fold succeeded?}
    Q -- No --> R([ABORT — data loss risk])
    Q -- Yes --> S[REPLACE SPECIFICATION.md\nwith redirect]
    O -- No --> S
    N -- Yes --> T[SKIP]
    S --> U{PROJECT.md\nhas sentinel?}
    T --> U
    U -- No --> V[Warn if user-customized\nREPLACE PROJECT.md\nwith redirect]
    U -- Yes --> W[SKIP]
    V --> X([Done])
    W --> X
Loading
Prompt To Fix All With AI
This is a comment left during a code review.
Path: scripts/migrate_vbrief.py
Line: 106-126

Comment:
**Docstring promises fallbacks that don't exist**

The docstring states "Resolve the GitHub repository URL from spec_vbrief **or git remote**" and "Falls back to a **generic issue: prefix** if no repository can be determined," but the implementation does neither: there is no `git remote` lookup, and the return value when nothing is found is `""` (empty string), not a `"issue:"` prefix URI. Any caller expecting a non-empty fallback will silently produce references without `url` fields.

```suggestion
def _resolve_repo_url(spec_vbrief: dict | None) -> str:
    """Resolve the GitHub repository URL from spec_vbrief metadata.

    Returns an empty string if no repository URL can be determined; callers
    that build provenance references should treat "" as "omit url field".
    """
```

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

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

Comment thread CHANGELOG.md Outdated
Comment thread scripts/migrate_vbrief.py
Comment thread scripts/migrate_vbrief.py Outdated
@MScottAdams MScottAdams force-pushed the agent3/feat/312-migration-script branch 2 times, most recently from 7487bef to c10c922 Compare April 13, 2026 18:52
Comment thread scripts/migrate_vbrief.py
…utover (#312)

- Create scripts/migrate_vbrief.py: automated migration from current document
  model to vBRIEF-centric lifecycle folder structure (RFC #309)
- Parse specification.vbrief.json + PROJECT.md to generate
  PROJECT-DEFINITION.vbrief.json with narratives + items registry (D3)
- Create 5 lifecycle folders: proposed/ pending/ active/ completed/ cancelled/ (D13)
- Convert ROADMAP.md items to individual pending/ scope vBRIEFs with provenance (D11)
- Replace SPECIFICATION.md and PROJECT.md with deprecation redirects (#334)
- Detect user-customized content before replacing and preserve in narratives
- Migration is idempotent (safe to run twice)
- Register as task migrate:vbrief in tasks/migrate.yml + Taskfile.yml
- Add 40 unit tests in tests/cli/test_migrate_vbrief.py
- Add CHANGELOG entry under [Unreleased]
- Restore release date on [0.19.0] heading (was accidentally dropped)
- Include issue number in scope vBRIEF filenames to prevent slug collisions
  (e.g. 2026-04-13-100-add-widget-support.vbrief.json)
- Fix _fold_custom_content using setdefault to prevent silent content loss
  when plan/narratives keys are absent from PROJECT-DEFINITION
- Add 2 new tests: slug collision produces separate files, filename includes
  issue number (42 total tests)
- MCP unavailable in this session -- used gh api fallback for review comments
- Remove hard-coded deftai/directive repo URL from provenance references;
  resolve from spec_vbrief metadata or leave URL-less for portability
- Add _resolve_repo_url() to extract repo from vBRIEFInfo.repository field
  or plan.references GitHub URLs
- Fix _fold_custom_content to return bool; preservation warning now only
  printed after successful fold, with fallback warning on failure
- Add 4 new tests: resolve_repo_url (3) + provenance with repo_url (1)
  Total: 46 tests
- MCP unavailable -- used gh api fallback for review comments
- Abort migration when custom SPECIFICATION.md fold fails, preventing
  data loss (return False with error message instead of writing redirect)
- Remove redundant _fold_custom_content call for ProjectConfig (already
  captured by _build_project_definition in step 3)
- Add comment documenting why PROJECT.md fold is safe (step 3 safety net)
- MCP unavailable -- used gh api fallback for review comments
@MScottAdams MScottAdams force-pushed the agent3/feat/312-migration-script branch from c10c922 to f31ec00 Compare April 13, 2026 19:14
@MScottAdams MScottAdams merged commit 0764ded into phase2/vbrief-cutover Apr 13, 2026
@MScottAdams MScottAdams deleted the agent3/feat/312-migration-script branch April 13, 2026 19:14
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