Keeping Your PRD Alive
Your PRD starts fresh and accurate. Three months later, completed tasks still sit marked "pending", epics describe features you shipped last quarter, and findings from solved problems keep regenerating. This guide walks through keeping the PRD synchronized with reality — not just at setup, but as your codebase evolves.
The scenario
You shipped v1.0 six weeks ago. The PRD has 40 tasks — 20 are done, 10 are half-way through, 5 are blocked, and 5 were never relevant. New features went in without updating the PRD. The agent keeps re-proposing fixes for problems you already solved. The PRD has become noise instead of a tool.
This guide covers three maintenance loops:
- Post-sprint pruning — remove completed work, archive what's no longer relevant
- Monthly re-analysis — surface new drift before it compounds
- Ongoing acknowledgment — silence resolved findings so proposals stay relevant
Understanding PRD drift
PRD drift happens naturally as codebases evolve. It's not a failure — it's a signal that the PRD needs maintenance.
Common drift patterns
Completed work left in the PRD:
- Task marked
pendingbut the feature shipped 2 sprints ago - Epic still shows 3 pending tasks that were actually split and completed piecemeal
- Subtasks marked
in_progressbecause the agent was interrupted and you moved on
Obsolete items:
- Epic for a feature you've since deprecated
- Epics from RFCs that were rejected or shelved
- Tasks for refactoring that became unnecessary after a redesign
Orphaned tasks:
- Features completed outside the PRD (manually, by someone without access, or before n-dx was set up)
- Bugs fixed before they were added to the PRD
- Design debt resolved during feature work
Stale findings:
- SourceVision suggests splitting a file you've already split
- Findings from a module you've since rewritten keep regenerating
- Recommendations for problems you've explicitly decided not to fix
Detecting drift
Quick health check:
ndx status . # scan for pending/completed mismatchesLook for clusters of completed tasks from the same epic. If you see 5 completed from one epic and 3 still pending from that same epic, you likely have some stale pending items.
Full diagnostic:
rex validate . # check structural integrity
ndx ci . # full analysis pipeline (may take a few minutes)rex validate checks for orphaned items (tasks with no parent, parent-level mismatches, date anomalies).
ndx ci runs the full pipeline: re-analyzes the codebase, checks PRD health metrics (completion rate, item age distribution), and generates a report. Read the report for completion percentage, item age stats, and any structural issues flagged.
The maintenance loop
Cycle 1: Mark what's actually done
Before pruning, make sure your PRD reflects what's actually shipping.
Manual sweep (15 minutes per epic):
For each epic, walk through the pending/in-progress tasks:
ndx status .For each task, ask: "Is this shipped?" If yes, mark it completed with the resolution type:
rex update <task-id> --status=completed --resolution-type=code-changeResolution types are:
code-change— you or the agent wrote the codeconfig-override— resolved by configuration, not codeacknowledgment— you decided not to do it (mark thesedeferredinstead)deferred— explicitly postponed; keep for future reconsideration
Batch update via dashboard (if you have ndx start running):
Open the dashboard (typically http://localhost:3117), navigate to the PRD tree, and mark items complete through the UI. Changes sync to .rex/prd.json immediately.
Cycle 2: Archive completed epics
Once you've marked individual tasks, check if entire epics are done:
ndx status . # find completed epicsAn epic is "done" when all its tasks are either completed or deferred.
For epics that are fully complete and you won't revisit:
rex remove <epic-id>This moves the epic to .rex/archive.json — a permanent archive that preserves the completed work for audit trails and recovery if needed.
Recovering from archive (if you need to revisit):
rex restore <epic-id>Items in the archive are tagged with their completion timestamp, so you can search the archive for items completed in a specific time window.
Cycle 3: Re-analyze and surface new drift
Run a fresh analysis to pick up architectural changes:
ndx analyze .This generates a new .sourcevision/CONTEXT.md with updated findings. These findings may be:
- New problems from code that changed since the last analysis
- Resolved problems from work you've completed (but the findings haven't been acknowledged yet)
- Persistent problems that are still there and maybe got worse
Compare the new findings with the old ones. New findings go into the recommendation cycle (see below). Persistent findings that you can't fix belong in the backlog.
Cycle 4: Propose and acknowledge
Generate recommendations based on the fresh analysis:
ndx recommend --actionable-only .Review the proposals. For each proposed item, decide:
- Add it: accept it into the PRD
- Acknowledge it: mark the finding as resolved (you've made a deliberate choice not to fix it), so it won't keep regenerating
If you've already fixed a problem but the finding persists, acknowledge it:
ndx recommend --acknowledge .You'll be prompted for which findings are resolved. Select the ones you've already fixed. These are marked in .sourcevision/acknowledged.json — the next time you run ndx recommend, these findings won't be re-proposed.
Example maintenance session
Here's a complete cycle from start to finish:
# 0. Create a branch for the maintenance work
git checkout -b chore/prd-maintenance
# 1. Mark what's actually done
ndx status . # review the tree
rex update <task-id> --status=completed --resolution-type=code-change
rex update <task-id> --status=deferred
# ... for each task you've completed
# 2. Remove finished epics
rex remove <epic-id> # archive the epic
git add -A && git commit -m "Archive completed epic: Feature X"
# 3. Re-analyze
ndx analyze .
cat .sourcevision/CONTEXT.md | grep -A 20 "findings"
# 4. Propose and filter
ndx recommend --actionable-only .
# Review proposals; accept the ones that matter, skip noisy ones
# 5. Acknowledge resolved findings (don't re-propose them)
ndx recommend --acknowledge .
# 6. Review the cleaned PRD
ndx status .
ndx validate .
# 7. Commit
git add -A && git commit -m "PRD maintenance: updated status, acknowledged findings"
git push -u origin chore/prd-maintenanceRecommended cadence
Post-sprint (weekly or bi-weekly):
Time: 10–15 minutes.
Right after a sprint closes, mark completed tasks and remove finished epics. This is the highest-ROI maintenance — the work is fresh in your mind, and you'll catch "actually done but not marked" items before they stack up.
ndx status .
# (scan and mark)
rex remove <finished-epic-ids>Monthly deep clean:
Time: 45 minutes to 1 hour.
Once a month, do the full cycle: mark completion, analyze, recommend, acknowledge. This catches drift before it compounds.
ndx analyze .
ndx recommend --actionable-only .
ndx recommend --acknowledge .
ndx status .
git diff .rex/prd.json | wc -l # how many changes?Quarterly full reset (if PRD drift is high):
If you go 3+ months without maintenance and the PRD is 50%+ stale, consider a full reset:
ndx ci . # full analysis + health report
ndx plan --accept . # re-analyze and accept all proposals
# This rewrites the PRD from scratch based on current codebaseThis is safe — the old PRD goes to archive, and you start fresh with a clean analysis. Archive items are available for recovery if needed.
Identifying and fixing specific drift patterns
Pattern 1: Completed work not marked
Signal: You remember finishing a feature, but the task still shows pending.
Fix:
- Find the task:
ndx status . | grep <feature-name> - Review its acceptance criteria against the current codebase
- If fully met, mark it:
rex update <task-id> --status=completed --resolution-type=code-change - If partially met, edit the task to reflect what's actually pending:
rex update <task-id> --title="<narrower scope>"
Pattern 2: Stale epics
Signal: An epic describes work from last quarter that you've moved away from.
Fix:
- List the epic's tasks:
ndx status . | grep -A 10 "Epic Name" - Mark its completed tasks as complete
- If all tasks are done or deferred:
rex remove <epic-id> - If some tasks are still pending but you're deprioritizing them: move to a "backlog" epic or mark them
deferred
Pattern 3: Orphaned tasks
Signal: You see a task in the PRD, but the code it describes doesn't exist or is already done.
Fix:
- Verify the current state: read the relevant code, search for the described change
- If already done: mark
completed - If never going to happen: mark
deferredwith a reason, orremoveentirely - If partially done: narrow the task scope and mark what's completed
Pattern 4: Regenerating findings
Signal: You run ndx recommend and see the same finding about a module you've already fixed.
Fix:
- Verify the finding is actually resolved: re-read the module, check imports, verify the anti-pattern is gone
- If resolved: run
ndx recommend --acknowledge .and mark the finding as acknowledged - If not resolved: add the finding to the PRD as a task that didn't get picked up in earlier cycles, or acknowledge that you're living with the anti-pattern deliberately (sometimes acceptable for non-blocking patterns)
Using ndx sync for team-backed PRDs
If your team uses Notion, GitHub discussions, or another external system as the source of truth for your PRD, ndx sync keeps your local .rex/prd.json in sync with that system.
Setting up sync
First, configure an adapter:
ndx config rex.adapter notion . # or github, airtable, etc.
ndx config rex.adapterUrl https://notion.so/... .
ndx config rex.adapterAuthToken <token> .Adapters vary by platform. Check ndx config --help for your platform's required fields.
Two-way sync
Once configured, sync in either direction:
Pull from remote (remote is source of truth):
ndx sync --pull .Your local PRD is overwritten with what's in the remote system.
Push to remote (local is source of truth):
ndx sync --push .Your local .rex/prd.json is pushed to the remote system.
Full bidirectional sync (latest wins, conflict resolution by timestamp):
ndx sync .Items that changed locally and remotely are resolved by timestamp — the latest change wins. Items unique to one side are merged.
Team workflow with sync
Scenario 1: You and your team use Notion as the PRD source
- Team edits items in Notion (titles, descriptions, priorities)
- You pull changes locally:
ndx sync --pull . - You run
ndx analyze . && ndx recommend .based on the updated Notion items - You execute with
ndx work . - Task completion and agent runs update your local PRD
- Push completion back to Notion:
ndx sync --push .
Scenario 2: Local CLI for execution, Notion for discussion
- Team discusses features in Notion; comments, linked docs, decision history
- You sync locally to get the latest decisions:
ndx sync --pull . - You execute locally and add your own PRD items from findings:
ndx analyze . && ndx recommend --accept . - Push your PRD additions back to Notion for team visibility:
ndx sync --push .
Conflict resolution
If a field was changed both locally and remotely since the last sync, ndx sync will:
- Show the conflict
- Ask you to resolve it (keep local, keep remote, or merge manually)
- Apply the resolution to both sides
For large teams, this is rare if you establish a pattern: typically one person (a team lead or tech lead) runs the weekly pruning and sync, and the team makes PRD comments via Notion rather than direct edits.
Archive management
Every time you run rex remove <item-id>, the item goes into .rex/archive.json. The archive serves as an audit trail — you can recover items if you change your mind, and you can see what you decided not to pursue.
Viewing the archive
cat .rex/archive.json | jq '.items | length' # how many archived items?
cat .rex/archive.json | jq '.items[] | select(.completedAt != null) | .title' # show completed itemsRecovering from archive
rex restore <item-id> # restore a specific itemThe item returns to the PRD tree under its original parent, with all history intact (timestamps, completion status, all metadata).
Pruning the archive
The archive auto-trims at 100 batches (to prevent unbounded growth). You can also manually clear old items:
# Clear items archived more than 6 months ago
rex archive-prune --before="6m" .This is safe — archived items are only used for recovery/audit, and they're tagged with timestamps for audit purposes. You rarely need to prune unless the archive file gets very large.
Common pitfalls and recovery
Pitfall 1: Over-pruning (removed too much)
You ran rex remove on an epic and immediately regretted it.
Recovery:
rex restore <epic-id>
git diff .rex/prd.json # see the diffIf you committed already:
git revert <commit-hash>
rex restore <epic-id>Pitfall 2: PRD drifted so far it's unusable
You haven't done maintenance for 6+ months. The PRD is 80% stale, and it's not worth trying to salvage item-by-item.
Recovery:
ndx analyze .
ndx plan --accept . # full re-analysis and PRD rewriteThis overwrites your PRD based on the current codebase. All old items go to archive. Start fresh.
If you want to preserve some of the old PRD structure before resetting:
cp .rex/prd.json .rex/prd.backup.json
ndx plan --accept .
# Now .rex/archive.json contains your old items for recoveryPitfall 3: Findings keep regenerating even after acknowledging
You acknowledged a finding, but ndx recommend keeps proposing it.
Cause: The finding is coming from a different source (e.g., different SourceVision runs with different configurations, or the code genuinely still has the anti-pattern).
Fix:
- Verify the problem is actually fixed: re-read the code, re-run analysis with
ndx analyze --full . - If fixed: wait for the next
ndx recommendrun — acknowledgment is cached for 30 days before refreshing - If not fixed: either fix it properly, or mark it
deferredin the PRD with an explanation of why you're living with it
A complete maintenance checklist
Weekly (post-sprint):
- [ ]
ndx status .— scan for completed work not marked - [ ]
rex updatefor each completed task - [ ]
rex removefor finished epics - [ ]
git commit -m "PRD maintenance: marked completed work"
Monthly (full cycle):
- [ ] Run weekly checklist above
- [ ]
ndx analyze .— re-analyze codebase - [ ]
ndx recommend --actionable-only .— review proposals - [ ]
ndx recommend --acknowledge .— silence resolved findings - [ ]
ndx validate .— check PRD integrity - [ ]
ndx status .— confirm the PRD is healthy - [ ]
git commit -m "PRD maintenance: full cycle re-analysis and acknowledgment"
If using external adapters (Notion, GitHub, etc.):
- [ ] Run the above locally
- [ ]
ndx sync --push .— push local changes to remote - [ ] Notify team if significant PRD changes (new epics, priorities changed)
Quarterly (if PRD is heavily drifted):
- [ ]
ndx ci .— full health report - [ ] Review drift patterns from the report
- [ ] Either do a deep-clean maintenance pass, or reset the PRD with
ndx plan --accept .
Next steps
Once your PRD is healthy:
- Run
ndx work --auto --iterations=N .to execute a full sprint autonomously - Schedule a recurring maintenance task with
ndx scheduleto remind yourself to prune monthly - Set up
ndx syncif your team uses an external system for backlog management - Use
ndx self-healfor ongoing improvement between full maintenance cycles
Skills used in this guide
Each skill below is invoked during the maintenance cycles described in this guide. Edit the linked file in your project to customize that step's behavior in your assistant session.
| Skill | Source | Role in this guide |
|---|---|---|
/ndx-status | .agents/skills/ndx-status/SKILL.md | Weekly cycle: detects drift — completed work not yet marked, stale epics, orphaned tasks |
/ndx-plan | .agents/skills/ndx-plan/SKILL.md | Monthly cycle: re-analyzes the codebase and proposes items for persistent or newly surfaced findings |
/ndx-reshape | .agents/skills/ndx-reshape/SKILL.md | Quarterly: restructures a drifted PRD — regroups epics, adjusts levels, merges overlapping items |
/ndx-capture | .agents/skills/ndx-capture/SKILL.md | Throughout: adds newly surfaced requirements to the right place in the PRD hierarchy |
/ndx-config | .agents/skills/ndx-config/SKILL.md | Sync setup: configures the external adapter (rex.adapter, rex.adapterUrl, rex.adapterAuthToken) |
Related guides: Workflow (the normal development loop this guide maintains), Self-Heal Loop (automates the analyze → recommend cycle between full maintenance passes).
For the full skill inventory and customization guidance, see the Skills Reference.
