@sandrinio/vbounce 1.7.0 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/README.md +168 -160
  2. package/bin/vbounce.mjs +250 -25
  3. package/brains/AGENTS.md +4 -4
  4. package/brains/CHANGELOG.md +2 -2
  5. package/brains/CLAUDE.md +4 -4
  6. package/brains/GEMINI.md +5 -5
  7. package/brains/SETUP.md +15 -15
  8. package/brains/claude-agents/architect.md +1 -1
  9. package/brains/claude-agents/developer.md +1 -1
  10. package/brains/claude-agents/devops.md +1 -1
  11. package/brains/claude-agents/qa.md +2 -1
  12. package/brains/claude-agents/scribe.md +1 -1
  13. package/brains/copilot/copilot-instructions.md +3 -3
  14. package/brains/cursor-rules/vbounce-docs.mdc +2 -2
  15. package/brains/cursor-rules/vbounce-process.mdc +3 -3
  16. package/brains/cursor-rules/vbounce-rules.mdc +2 -2
  17. package/brains/windsurf/.windsurfrules +2 -2
  18. package/docs/HOTFIX_EDGE_CASES.md +1 -1
  19. package/package.json +5 -5
  20. package/scripts/doctor.mjs +3 -3
  21. package/scripts/hotfix_manager.sh +2 -2
  22. package/scripts/init_gate_config.sh +1 -1
  23. package/scripts/pre_gate_common.sh +1 -1
  24. package/scripts/pre_gate_runner.sh +1 -1
  25. package/scripts/prep_qa_context.mjs +19 -1
  26. package/scripts/prep_sprint_context.mjs +24 -1
  27. package/scripts/suggest_improvements.mjs +1 -1
  28. package/scripts/validate_bounce_readiness.mjs +27 -0
  29. package/scripts/validate_report.mjs +1 -1
  30. package/scripts/vdoc_match.mjs +269 -0
  31. package/scripts/vdoc_staleness.mjs +199 -0
  32. package/scripts/verify_framework.mjs +1 -1
  33. package/skills/agent-team/SKILL.md +18 -11
  34. package/skills/doc-manager/SKILL.md +5 -5
  35. package/skills/improve/SKILL.md +2 -2
  36. package/templates/sprint_report.md +6 -2
@@ -0,0 +1,199 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * vdoc_staleness.mjs
5
+ * Cross-references Dev Reports' files_modified against vdoc manifest key files.
6
+ * Generates a targeted Scribe task file listing stale docs.
7
+ *
8
+ * Usage:
9
+ * ./scripts/vdoc_staleness.mjs S-05
10
+ *
11
+ * Output: .bounce/scribe-task-S-05.md
12
+ */
13
+
14
+ import fs from 'fs';
15
+ import path from 'path';
16
+ import { fileURLToPath } from 'url';
17
+ import yaml from 'js-yaml';
18
+
19
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
20
+ const ROOT = path.resolve(__dirname, '..');
21
+
22
+ const sprintId = process.argv[2];
23
+ if (!sprintId) {
24
+ console.error('Usage: vdoc_staleness.mjs S-XX');
25
+ process.exit(1);
26
+ }
27
+
28
+ const VDOCS_DIR = path.join(ROOT, 'vdocs');
29
+ const MANIFEST_PATH = path.join(VDOCS_DIR, '_manifest.json');
30
+
31
+ // ── Check manifest ────────────────────────────────────────────────
32
+
33
+ if (!fs.existsSync(MANIFEST_PATH)) {
34
+ console.log('No vdocs/_manifest.json found — skipping staleness check');
35
+ process.exit(0);
36
+ }
37
+
38
+ const manifest = JSON.parse(fs.readFileSync(MANIFEST_PATH, 'utf8'));
39
+ const docs = manifest.documentation || [];
40
+
41
+ // ── Collect all files_modified from Dev Reports ───────────────────
42
+
43
+ const allModifiedFiles = new Set();
44
+ const storyModifications = {}; // storyId -> files
45
+
46
+ function findDevReports(dir) {
47
+ if (!fs.existsSync(dir)) return [];
48
+ const results = [];
49
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
50
+ for (const e of entries) {
51
+ const full = path.join(dir, e.name);
52
+ if (e.isDirectory()) results.push(...findDevReports(full));
53
+ else if (e.name.endsWith('-dev.md')) results.push(full);
54
+ }
55
+ return results;
56
+ }
57
+
58
+ const reportDirs = [
59
+ path.join(ROOT, '.bounce', 'reports'),
60
+ path.join(ROOT, '.bounce', 'archive', sprintId),
61
+ ];
62
+
63
+ for (const dir of reportDirs) {
64
+ const reports = findDevReports(dir);
65
+ for (const report of reports) {
66
+ try {
67
+ const content = fs.readFileSync(report, 'utf8');
68
+ const fmMatch = content.match(/^---\s*\n([\s\S]*?)\n---/);
69
+ if (!fmMatch) continue;
70
+ const fm = yaml.load(fmMatch[1]) || {};
71
+ const files = fm.files_modified || [];
72
+ const storyMatch = path.basename(report).match(/STORY-[\w-]+/);
73
+ const storyId = storyMatch ? storyMatch[0] : 'unknown';
74
+ storyModifications[storyId] = files;
75
+ files.forEach(f => allModifiedFiles.add(f));
76
+ } catch { /* skip malformed reports */ }
77
+ }
78
+ }
79
+
80
+ if (allModifiedFiles.size === 0) {
81
+ console.log('No files_modified found in Dev Reports — nothing to check');
82
+ process.exit(0);
83
+ }
84
+
85
+ // ── Cross-reference against manifest key files ────────────────────
86
+
87
+ const staleDocs = [];
88
+
89
+ for (const doc of docs) {
90
+ // Get key files from doc frontmatter or Key Files section
91
+ const docKeyFiles = [];
92
+
93
+ // From manifest entry
94
+ if (doc.keyFiles) docKeyFiles.push(...doc.keyFiles);
95
+
96
+ // From the doc file itself
97
+ const docPath = path.join(VDOCS_DIR, doc.filepath);
98
+ if (fs.existsSync(docPath)) {
99
+ const content = fs.readFileSync(docPath, 'utf8');
100
+
101
+ // Parse frontmatter keyFiles
102
+ const fmMatch = content.match(/^---\s*\n([\s\S]*?)\n---/);
103
+ if (fmMatch) {
104
+ try {
105
+ const fm = yaml.load(fmMatch[1]) || {};
106
+ if (fm.keyFiles) docKeyFiles.push(...fm.keyFiles);
107
+ } catch { /* ignore */ }
108
+ }
109
+
110
+ // Parse Key Files table
111
+ const tableMatch = content.match(/## Key Files[\s\S]*?\|[^|]+\|[^|]+\|[^|]+\|([\s\S]*?)(?=\n---|\n##)/);
112
+ if (tableMatch) {
113
+ const rows = tableMatch[1].split('\n').filter(r => r.includes('|'));
114
+ for (const row of rows) {
115
+ const cells = row.split('|').map(c => c.trim());
116
+ const filePath = cells[1]?.replace(/`/g, '');
117
+ if (filePath && filePath.includes('/')) docKeyFiles.push(filePath);
118
+ }
119
+ }
120
+ }
121
+
122
+ // Check for overlap
123
+ const uniqueKeyFiles = [...new Set(docKeyFiles)];
124
+ const overlapping = uniqueKeyFiles.filter(kf =>
125
+ [...allModifiedFiles].some(mf => mf.includes(kf) || kf.includes(mf))
126
+ );
127
+
128
+ if (overlapping.length > 0) {
129
+ // Find which stories touched these files
130
+ const touchedBy = [];
131
+ for (const [sid, files] of Object.entries(storyModifications)) {
132
+ if (files.some(f => overlapping.some(o => f.includes(o) || o.includes(f)))) {
133
+ touchedBy.push(sid);
134
+ }
135
+ }
136
+
137
+ staleDocs.push({
138
+ filepath: doc.filepath,
139
+ title: doc.title,
140
+ overlappingFiles: overlapping,
141
+ touchedBy,
142
+ });
143
+ }
144
+ }
145
+
146
+ if (staleDocs.length === 0) {
147
+ console.log('✓ No stale vdocs detected — all docs are current');
148
+ process.exit(0);
149
+ }
150
+
151
+ // ── Generate Scribe task file ─────────────────────────────────────
152
+
153
+ const taskLines = [
154
+ `---`,
155
+ `sprint_id: "${sprintId}"`,
156
+ `mode: "audit"`,
157
+ `stale_docs: ${staleDocs.length}`,
158
+ `generated: "${new Date().toISOString().split('T')[0]}"`,
159
+ `---`,
160
+ ``,
161
+ `# Scribe Task: ${sprintId} — Targeted Doc Update`,
162
+ ``,
163
+ `> Auto-generated by staleness detection. ${staleDocs.length} doc(s) need updating.`,
164
+ ``,
165
+ `## Stale Documents`,
166
+ ``,
167
+ `| Doc | Title | Files Modified | Touched By |`,
168
+ `|-----|-------|---------------|------------|`,
169
+ ...staleDocs.map(d =>
170
+ `| ${d.filepath} | ${d.title} | ${d.overlappingFiles.slice(0, 3).join(', ')}${d.overlappingFiles.length > 3 ? ` (+${d.overlappingFiles.length - 3})` : ''} | ${d.touchedBy.join(', ')} |`
171
+ ),
172
+ ``,
173
+ `## Instructions`,
174
+ ``,
175
+ `For each stale doc:`,
176
+ `1. Read the current doc and the Dev Reports from the stories listed above`,
177
+ `2. Re-read the modified source files to understand what changed`,
178
+ `3. Update only the affected sections — do not rewrite the entire doc`,
179
+ `4. Bump frontmatter \`version\` (increment by 1) and set \`lastUpdated\` to today`,
180
+ `5. Update the manifest entry if tags or description need adjustment`,
181
+ `6. Regenerate the context slice in \`vdocs/_slices/\``,
182
+ ``,
183
+ `## Priority`,
184
+ ``,
185
+ ...staleDocs.map(d => {
186
+ const fileCount = d.overlappingFiles.length;
187
+ const priority = fileCount >= 3 ? 'HIGH' : fileCount >= 2 ? 'MEDIUM' : 'LOW';
188
+ return `- **${d.filepath}**: ${priority} (${fileCount} key file(s) modified)`;
189
+ }),
190
+ ];
191
+
192
+ const taskFile = path.join(ROOT, '.bounce', `scribe-task-${sprintId}.md`);
193
+ fs.writeFileSync(taskFile, taskLines.join('\n'));
194
+
195
+ console.log(`✓ Scribe task written to .bounce/scribe-task-${sprintId}.md`);
196
+ console.log(` ${staleDocs.length} stale doc(s) detected:`);
197
+ for (const d of staleDocs) {
198
+ console.log(` - ${d.filepath} (${d.overlappingFiles.length} key files modified by ${d.touchedBy.join(', ')})`);
199
+ }
@@ -63,7 +63,7 @@ const EXPECTED_PROMPT_SIGNATURES = {
63
63
 
64
64
  function main() {
65
65
  console.log("===========================================");
66
- console.log(" V-Bounce OS: Framework Integrity Check");
66
+ console.log(" V-Bounce Engine: Framework Integrity Check");
67
67
  console.log("===========================================\n");
68
68
 
69
69
  let hasErrors = false;
@@ -359,17 +359,24 @@ After ALL stories are merged into `sprint/S-01`:
359
359
  - Offer to run the `improve` skill to propose framework changes
360
360
  - If user approves → read `skills/improve/SKILL.md` and execute the improvement process
361
361
  8. Product Documentation check (runs on `main` after sprint merge):
362
- - If sprint delivered 3+ features, or if any Developer report flagged
363
- stale product docs offer to run vdoc to generate/update
364
- vdocs/
365
- - If user approves spawn scribe subagent on `main` branch with:
366
- - Sprint Report (what was built)
367
- - Dev reports that flagged affected product docs
368
- - Current _manifest.json (if exists)
369
- - Mode: "audit" (if docs exist) or "init" (if first time)
370
- - Scribe generates/updates docs and writes Scribe Report
371
- - Documentation is post-implementation it reflects what was built
372
- - Scribe commits documentation as a follow-up commit on `main`
362
+ a. **Staleness Detection** run `./scripts/vdoc_staleness.mjs S-{XX}`
363
+ - Cross-references all Dev Reports' `files_modified` against manifest key files
364
+ - Generates `.bounce/scribe-task-S-{XX}.md` with targeted list of stale docs
365
+ - Populates Sprint Report §1 "Product Docs Affected" table
366
+ - If no `vdocs/_manifest.json` exists → skip silently (graceful no-op)
367
+ b. **Scribe Task Decision:**
368
+ - If staleness detection found stale docs → offer targeted Scribe task
369
+ - If sprint delivered 3+ features and no vdocs exist offer vdoc init
370
+ - If any Developer report flagged stale product docs offer Scribe update
371
+ c. If user approves spawn scribe subagent on `main` branch with:
372
+ - `.bounce/scribe-task-S-{XX}.md` (targeted task when available)
373
+ - Sprint Report (what was built)
374
+ - Dev reports that flagged affected product docs
375
+ - Current _manifest.json (if exists)
376
+ - Mode: "audit" (if docs exist) or "init" (if first time)
377
+ d. Scribe generates/updates docs and writes Scribe Report
378
+ - Documentation is post-implementation — it reflects what was built
379
+ - Scribe commits documentation as a follow-up commit on `main`
373
380
  ```
374
381
 
375
382
  ---
@@ -1,13 +1,13 @@
1
1
  ---
2
2
  name: doc-manager
3
- description: "Use when creating, modifying, or navigating V-Bounce OS planning documents. Trigger on any request to create a charter, roadmap, epic, story, delivery plan, or risk registry — or when the user asks to update, refine, decompose, or transition documents between phases. Also trigger when an agent needs to know which template to use, where a document fits in the hierarchy, or what upstream/downstream documents to read before writing. This skill manages the full document lifecycle from Charter through Sprint execution."
3
+ description: "Use when creating, modifying, or navigating V-Bounce Engine planning documents. Trigger on any request to create a charter, roadmap, epic, story, delivery plan, or risk registry — or when the user asks to update, refine, decompose, or transition documents between phases. Also trigger when an agent needs to know which template to use, where a document fits in the hierarchy, or what upstream/downstream documents to read before writing. This skill manages the full document lifecycle from Charter through Sprint execution."
4
4
  ---
5
5
 
6
6
  # Document Hierarchy Manager
7
7
 
8
8
  ## Purpose
9
9
 
10
- This skill is the navigation system for V-Bounce OS planning documents. It knows the full document hierarchy, what each template contains, where to find templates, and the rules for creating, modifying, and transitioning documents between phases.
10
+ This skill is the navigation system for V-Bounce Engine planning documents. It knows the full document hierarchy, what each template contains, where to find templates, and the rules for creating, modifying, and transitioning documents between phases.
11
11
 
12
12
  **Core principle:** No document exists in isolation. Every document inherits context from upstream and feeds downstream consumers. YOU MUST read upstream documents before creating any new document.
13
13
 
@@ -120,10 +120,10 @@ product_plans/
120
120
  - `sprints/` contains active 1-week execution boundaries. A Story file physically moves here when a sprint begins.
121
121
  - `archive/` is where finished Sprints and finished Epics are moved for permanent record keeping.
122
122
 
123
- ### V-Bounce OS Framework Structure
123
+ ### V-Bounce Engine Framework Structure
124
124
 
125
125
  ```
126
- V-Bounce OS/
126
+ V-Bounce Engine/
127
127
  ├── brains/ — Agent brain files for each AI coding tool
128
128
  │ ├── CLAUDE.md — Claude Code brain
129
129
  │ ├── AGENTS.md — Codex CLI brain
@@ -148,7 +148,7 @@ When initializing a new project, deploy the correct brain file for the AI coding
148
148
  | Gemini CLI | `brains/GEMINI.md` | Project root as `GEMINI.md` |
149
149
  | Antigravity | `brains/GEMINI.md` | Project root + copy `skills/` to `.agents/skills/` |
150
150
 
151
- Brain files contain the V-Bounce process, critical rules, and skill references. Each tool's brain file is self-contained and authoritative. When updating V-Bounce OS rules, update each brain file directly and keep them in sync.
151
+ Brain files contain the V-Bounce process, critical rules, and skill references. Each tool's brain file is self-contained and authoritative. When updating V-Bounce Engine rules, update each brain file directly and keep them in sync.
152
152
 
153
153
  ## Document Operations
154
154
 
@@ -1,13 +1,13 @@
1
1
  ---
2
2
  name: improve
3
- description: "Use when the V-Bounce OS framework needs to evolve based on accumulated agent feedback. Activates after sprint retros, when recurring friction patterns emerge, or when the user explicitly asks to improve the framework. Reads Process Feedback from sprint reports, identifies patterns, proposes specific changes to templates, skills, brain files, scripts, and agent configs, and applies approved changes. This is the system's self-improvement loop."
3
+ description: "Use when the V-Bounce Engine framework needs to evolve based on accumulated agent feedback. Activates after sprint retros, when recurring friction patterns emerge, or when the user explicitly asks to improve the framework. Reads Process Feedback from sprint reports, identifies patterns, proposes specific changes to templates, skills, brain files, scripts, and agent configs, and applies approved changes. This is the system's self-improvement loop."
4
4
  ---
5
5
 
6
6
  # Framework Self-Improvement
7
7
 
8
8
  ## Purpose
9
9
 
10
- V-Bounce OS is not static. Every sprint generates friction signals from agents who work within the framework daily. This skill closes the feedback loop: it reads what agents struggled with, identifies patterns, and proposes targeted improvements to the framework itself.
10
+ V-Bounce Engine is not static. Every sprint generates friction signals from agents who work within the framework daily. This skill closes the feedback loop: it reads what agents struggled with, identifies patterns, and proposes targeted improvements to the framework itself.
11
11
 
12
12
  **Core principle:** No framework change happens without human approval. The system suggests — the human decides.
13
13
 
@@ -54,9 +54,13 @@ delivery_plan_ref: "product_plans/{delivery}/DELIVERY_PLAN.md"
54
54
  - {e.g., "STORY-001-03-email_notifications — Escalated (template integration failed 3x)"}
55
55
 
56
56
  ### Product Docs Affected
57
- > Any product documentation files modified, created, or identified for updates. Handed off to Scribe agent.
57
+ > Auto-populated from staleness detection (`vbounce docs check S-{XX}`). Shows which vdocs were impacted by this sprint's code changes. Scribe agent receives a targeted task from `.bounce/scribe-task-S-{XX}.md`.
58
58
 
59
- - {e.g., "vdocs/api_reference.md Added rate limiting details"}
59
+ | Doc | Stale Key Files | Touched By | Priority | Scribe Action |
60
+ |-----|----------------|------------|----------|---------------|
61
+ | {e.g., `AUTHENTICATION_DOC.md`} | {e.g., `src/auth/index.ts`} | {e.g., `STORY-001-02`} | {HIGH/MEDIUM/LOW} | {Update / Quality Fix / New} |
62
+
63
+ > If no `vdocs/_manifest.json` exists, write "N/A — vdoc not installed".
60
64
 
61
65
  ---
62
66