create-byan-agent 2.19.1 → 2.20.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 (52) hide show
  1. package/CHANGELOG.md +188 -0
  2. package/README.md +4 -4
  3. package/install/src/byan-v2/generation/templates/default-agent.md +1 -1
  4. package/install/templates/.claude/CLAUDE.md +1 -1
  5. package/install/templates/.claude/hooks/fd-phase-guard.js +2 -2
  6. package/install/templates/.claude/hooks/mantra-validate.js +16 -8
  7. package/install/templates/.claude/hooks/strict-scope-guard.js +25 -7
  8. package/install/templates/.claude/rules/native-workflows.md +32 -0
  9. package/install/templates/.claude/skills/byan-byan/SKILL.md +5 -5
  10. package/install/templates/.claude/skills/byan-mantra-audit/SKILL.md +53 -0
  11. package/install/templates/.claude/skills/byan-merise-agile/SKILL.md +2 -2
  12. package/install/templates/.claude/skills/byan-native-dev-story/SKILL.md +83 -0
  13. package/install/templates/.claude/workflows/INDEX.md +35 -0
  14. package/install/templates/.claude/workflows/check-implementation-readiness.js +280 -0
  15. package/install/templates/.claude/workflows/code-review.js +179 -0
  16. package/install/templates/.claude/workflows/create-excalidraw-dataflow.js +214 -0
  17. package/install/templates/.claude/workflows/create-excalidraw-diagram.js +188 -0
  18. package/install/templates/.claude/workflows/create-excalidraw-flowchart.js +225 -0
  19. package/install/templates/.claude/workflows/create-excalidraw-wireframe.js +192 -0
  20. package/install/templates/.claude/workflows/create-story.js +216 -0
  21. package/install/templates/.claude/workflows/dev-story.js +100 -0
  22. package/install/templates/.claude/workflows/document-project.js +455 -0
  23. package/install/templates/.claude/workflows/qa-automate.js +169 -0
  24. package/install/templates/.claude/workflows/quick-dev.js +273 -0
  25. package/install/templates/.claude/workflows/sprint-planning.js +261 -0
  26. package/install/templates/.claude/workflows/testarch-atdd.js +287 -0
  27. package/install/templates/.claude/workflows/testarch-automate.js +229 -0
  28. package/install/templates/.claude/workflows/testarch-ci.js +184 -0
  29. package/install/templates/.claude/workflows/testarch-framework.js +267 -0
  30. package/install/templates/.claude/workflows/testarch-nfr.js +316 -0
  31. package/install/templates/.claude/workflows/testarch-test-design.js +293 -0
  32. package/install/templates/.claude/workflows/testarch-test-review.js +321 -0
  33. package/install/templates/.claude/workflows/testarch-trace.js +316 -0
  34. package/install/templates/.githooks/pre-commit +49 -15
  35. package/install/templates/_byan/config.yaml +15 -5
  36. package/install/templates/_byan/mcp/byan-mcp-server/bin/byan-build-workflows.js +20 -0
  37. package/install/templates/_byan/mcp/byan-mcp-server/bin/byan-lint-workflows.js +57 -0
  38. package/install/templates/_byan/mcp/byan-mcp-server/lib/native-loop.js +39 -0
  39. package/install/templates/_byan/mcp/byan-mcp-server/lib/workflows-generator.js +149 -0
  40. package/install/templates/_byan/mcp/byan-mcp-server/lib/workflows-lint.js +113 -0
  41. package/install/templates/_byan/workflow/simple/byan/feature-workflow.md +14 -11
  42. package/install/templates/docs/native-workflows-contract.md +84 -0
  43. package/package.json +2 -2
  44. package/src/byan-v2/data/agent-scopes.json +46 -0
  45. package/src/byan-v2/data/mantras.json +194 -8
  46. package/src/byan-v2/generation/mantra-audit.js +147 -0
  47. package/src/byan-v2/generation/mantra-validator.js +56 -6
  48. package/src/byan-v2/generation/scope-resolver.js +102 -0
  49. package/src/byan-v2/generation/templates/default-agent.md +1 -1
  50. package/update-byan-agent/bin/update-byan-agent.js +67 -72
  51. package/update-byan-agent/lib/apply-update.js +202 -0
  52. package/update-byan-agent/package.json +1 -1
@@ -0,0 +1,280 @@
1
+ export const meta = {
2
+ name: 'check-implementation-readiness',
3
+ description: 'Adversarial readiness gate: validates PRD, Architecture, Epics & Stories, and UX for completeness and alignment before Phase 4 implementation. Mirrors the 6-step BYAN check-implementation-readiness pipeline and returns a structured verdict.',
4
+ phases: [
5
+ { title: 'DOCUMENT_DISCOVERY' },
6
+ { title: 'PRD_ANALYSIS' },
7
+ { title: 'EPIC_COVERAGE_VALIDATION' },
8
+ { title: 'UX_ALIGNMENT' },
9
+ { title: 'EPIC_QUALITY_REVIEW' },
10
+ { title: 'FINAL_ASSESSMENT' }
11
+ ]
12
+ }
13
+
14
+ // FD/STRICT CONTRACT (re-asserted): this script returns data only. It never
15
+ // imports lib/fd-state.js, never writes fd-state.json, and records no platform
16
+ // state. The orchestrating skill records FD/strict state via MCP at the human
17
+ // gate (duplicate resolution + the proceed-as-is / fix decision live OUTSIDE
18
+ // this script). No wall-clock, no randomness: any date/id is passed via args
19
+ // so the runtime can resume deterministically.
20
+
21
+ const planningArtifacts = (args && args.planningArtifacts) || '_bmad-output/planning-artifacts'
22
+ const reportDate = (args && args.date) || 'unspecified'
23
+ const role = 'an expert Product Manager and Scrum Master specialized in requirements traceability and spotting gaps in planning artifacts. Be adversarial: your job is to find the failures others missed, not to reassure.'
24
+
25
+ // ---------------------------------------------------------------------------
26
+ // STEP 1 - Document Discovery (mirrors step-01-document-discovery.md)
27
+ // Inventory PRD / Architecture / Epics / UX (whole + sharded), flag duplicates
28
+ // and missing docs. The human resolution gate stays out of the script: we
29
+ // surface duplicates/missing as data for the orchestrating skill to gate on.
30
+ // ---------------------------------------------------------------------------
31
+ phase('DOCUMENT_DISCOVERY')
32
+ const inventory = await agent(
33
+ `You are ${role}\n` +
34
+ `STEP 1 - Document Discovery. Inventory all planning documents under "${planningArtifacts}".\n` +
35
+ `For each of these four types, search BOTH whole and sharded forms:\n` +
36
+ `- PRD: ${planningArtifacts}/*prd*.md and ${planningArtifacts}/*prd*/index.md\n` +
37
+ `- Architecture: ${planningArtifacts}/*architecture*.md and ${planningArtifacts}/*architecture*/index.md\n` +
38
+ `- Epics & Stories: ${planningArtifacts}/*epic*.md and ${planningArtifacts}/*epic*/index.md\n` +
39
+ `- UX Design: ${planningArtifacts}/*ux*.md and ${planningArtifacts}/*ux*/index.md\n` +
40
+ `Group sharded files with their folder. Flag CRITICAL duplicates (a type existing as BOTH whole.md AND a sharded folder) and WARN on missing required docs. ` +
41
+ `Do NOT analyze contents yet - only locate and organize. Pick the version to use per type (or null if absent).`,
42
+ {
43
+ label: 'document-discovery',
44
+ phase: 'DOCUMENT_DISCOVERY',
45
+ schema: {
46
+ type: 'object',
47
+ required: ['documents', 'duplicates', 'missing'],
48
+ properties: {
49
+ documents: {
50
+ type: 'object',
51
+ properties: {
52
+ prd: { type: 'array', items: { type: 'string' } },
53
+ architecture: { type: 'array', items: { type: 'string' } },
54
+ epics: { type: 'array', items: { type: 'string' } },
55
+ ux: { type: 'array', items: { type: 'string' } }
56
+ }
57
+ },
58
+ chosen: { type: 'object' },
59
+ duplicates: { type: 'array', items: { type: 'string' } },
60
+ missing: { type: 'array', items: { type: 'string' } }
61
+ }
62
+ }
63
+ }
64
+ )
65
+ log(`Discovery: ${inventory.duplicates.length} duplicate conflict(s), ${inventory.missing.length} missing doc(s)`)
66
+
67
+ // ---------------------------------------------------------------------------
68
+ // STEP 2 - PRD Analysis (mirrors step-02-prd-analysis.md)
69
+ // Read the PRD completely (whole or all sharded files) and extract EVERY FR
70
+ // and NFR verbatim with numbering. No summarizing.
71
+ // ---------------------------------------------------------------------------
72
+ phase('PRD_ANALYSIS')
73
+ const prd = await agent(
74
+ `You are ${role}\n` +
75
+ `STEP 2 - PRD Analysis. Read the chosen PRD completely (if sharded, read ALL files in the folder). ` +
76
+ `Extract EVERY Functional Requirement (FR1, FR2, ...) and Non-Functional Requirement (NFR: performance, security, usability, reliability, scalability, compliance) with full text - do NOT summarize. ` +
77
+ `Also note constraints, assumptions, integration requirements not labeled FR/NFR. Give an initial PRD completeness/clarity assessment.\n` +
78
+ `PRD source(s): ${JSON.stringify(inventory.documents && inventory.documents.prd)}`,
79
+ {
80
+ label: 'prd-analysis',
81
+ phase: 'PRD_ANALYSIS',
82
+ schema: {
83
+ type: 'object',
84
+ required: ['functionalRequirements', 'nonFunctionalRequirements'],
85
+ properties: {
86
+ functionalRequirements: {
87
+ type: 'array',
88
+ items: {
89
+ type: 'object',
90
+ required: ['id', 'text'],
91
+ properties: { id: { type: 'string' }, text: { type: 'string' } }
92
+ }
93
+ },
94
+ nonFunctionalRequirements: {
95
+ type: 'array',
96
+ items: {
97
+ type: 'object',
98
+ required: ['id', 'text'],
99
+ properties: { id: { type: 'string' }, category: { type: 'string' }, text: { type: 'string' } }
100
+ }
101
+ },
102
+ additionalRequirements: { type: 'array', items: { type: 'string' } },
103
+ completenessAssessment: { type: 'string' }
104
+ }
105
+ }
106
+ }
107
+ )
108
+ log(`PRD: ${prd.functionalRequirements.length} FR, ${prd.nonFunctionalRequirements.length} NFR`)
109
+
110
+ // ---------------------------------------------------------------------------
111
+ // STEP 3 - Epic Coverage Validation (mirrors step-03-epic-coverage-validation.md)
112
+ // Compare every PRD FR against the epics' coverage. Build a traceability matrix.
113
+ // Every uncovered FR is a documented gap; flag epic-only FRs not in PRD too.
114
+ // ---------------------------------------------------------------------------
115
+ phase('EPIC_COVERAGE_VALIDATION')
116
+ const coverage = await agent(
117
+ `You are ${role}\n` +
118
+ `STEP 3 - Epic Coverage Validation. Read the epics & stories document completely. Extract its FR coverage map. ` +
119
+ `For EACH PRD FR below, determine whether it is covered (which epic/story) or MISSING. Also flag any FR present in epics but NOT in the PRD. Build a coverage matrix and compute coverage statistics.\n` +
120
+ `Epics source(s): ${JSON.stringify(inventory.documents && inventory.documents.epics)}\n` +
121
+ `PRD FRs to trace: ${JSON.stringify(prd.functionalRequirements)}`,
122
+ {
123
+ label: 'epic-coverage',
124
+ phase: 'EPIC_COVERAGE_VALIDATION',
125
+ schema: {
126
+ type: 'object',
127
+ required: ['matrix', 'missingFRs', 'totalFRs', 'coveredFRs', 'coveragePercent'],
128
+ properties: {
129
+ matrix: {
130
+ type: 'array',
131
+ items: {
132
+ type: 'object',
133
+ required: ['fr', 'status'],
134
+ properties: {
135
+ fr: { type: 'string' },
136
+ epicCoverage: { type: 'string' },
137
+ status: { type: 'string', enum: ['covered', 'missing'] }
138
+ }
139
+ }
140
+ },
141
+ missingFRs: { type: 'array', items: { type: 'string' } },
142
+ extraEpicFRs: { type: 'array', items: { type: 'string' } },
143
+ totalFRs: { type: 'integer' },
144
+ coveredFRs: { type: 'integer' },
145
+ coveragePercent: { type: 'number' }
146
+ }
147
+ }
148
+ }
149
+ )
150
+ log(`Coverage: ${coverage.coveredFRs}/${coverage.totalFRs} FRs covered (${coverage.coveragePercent}%), ${coverage.missingFRs.length} missing`)
151
+
152
+ // ---------------------------------------------------------------------------
153
+ // STEP 4 - UX Alignment (mirrors step-04-ux-alignment.md)
154
+ // If UX exists: check UX<->PRD and UX<->Architecture alignment. If absent:
155
+ // assess whether UX/UI is IMPLIED (user-facing app) and warn accordingly.
156
+ // ---------------------------------------------------------------------------
157
+ phase('UX_ALIGNMENT')
158
+ const ux = await agent(
159
+ `You are a UX VALIDATOR ensuring user experience is properly addressed.\n` +
160
+ `STEP 4 - UX Alignment. UX source(s): ${JSON.stringify(inventory.documents && inventory.documents.ux)}.\n` +
161
+ `If a UX document exists: validate (A) UX<->PRD alignment (user journeys match use cases; UX needs reflected in PRD) and (B) UX<->Architecture alignment (architecture supports UX, performance/responsiveness, all UI components backed). ` +
162
+ `If no UX document: assess whether UX/UI is IMPLIED (PRD mentions UI, web/mobile components, user-facing app) and issue a warning if implied-but-missing. Document every alignment gap.\n` +
163
+ `Architecture source(s): ${JSON.stringify(inventory.documents && inventory.documents.architecture)}`,
164
+ {
165
+ label: 'ux-alignment',
166
+ phase: 'UX_ALIGNMENT',
167
+ schema: {
168
+ type: 'object',
169
+ required: ['uxStatus', 'alignmentIssues', 'warnings'],
170
+ properties: {
171
+ uxStatus: { type: 'string', enum: ['found', 'not-found-implied', 'not-found-not-needed'] },
172
+ alignmentIssues: { type: 'array', items: { type: 'string' } },
173
+ warnings: { type: 'array', items: { type: 'string' } }
174
+ }
175
+ }
176
+ }
177
+ )
178
+ log(`UX: ${ux.uxStatus}, ${ux.alignmentIssues.length} alignment issue(s), ${ux.warnings.length} warning(s)`)
179
+
180
+ // ---------------------------------------------------------------------------
181
+ // STEP 5 - Epic Quality Review (mirrors step-05-epic-quality-review.md)
182
+ // Enforce create-epics-and-stories best practices: epics deliver USER value
183
+ // (not technical milestones), epic independence (no Epic N -> Epic N+1),
184
+ // no forward story dependencies, just-in-time DB/entity creation, BDD ACs,
185
+ // starter-template / greenfield-vs-brownfield checks. Classify by severity.
186
+ // ---------------------------------------------------------------------------
187
+ phase('EPIC_QUALITY_REVIEW')
188
+ const quality = await agent(
189
+ `You are an EPIC QUALITY ENFORCER. Validate the epics & stories against create-epics-and-stories best practices, rigorously and without compromise.\n` +
190
+ `STEP 5 - Epic Quality Review. Check, for every epic and story:\n` +
191
+ `- User value: epic title/goal is user-centric; reject technical milestones ("Setup Database", "API Development", "Infrastructure Setup").\n` +
192
+ `- Epic independence: Epic N must function on Epic 1..N-1 only; NEVER require Epic N+1; no circular deps.\n` +
193
+ `- Story dependencies: each story independently completable; NO forward references ("depends on Story 1.4").\n` +
194
+ `- DB/entity timing: tables created just-in-time per story, NOT all upfront in Epic 1 Story 1.\n` +
195
+ `- Acceptance criteria: Given/When/Then, testable, covers errors not just happy path, specific not vague.\n` +
196
+ `- Starter template: if Architecture specifies one, Epic 1 Story 1 must set up the project from it.\n` +
197
+ `- Greenfield vs brownfield: greenfield needs setup/env/CI-CD early; brownfield needs integration/migration stories.\n` +
198
+ `- Traceability to FRs maintained.\n` +
199
+ `Classify findings as critical / major / minor, each with a specific example and remediation.\n` +
200
+ `Epics source(s): ${JSON.stringify(inventory.documents && inventory.documents.epics)}\n` +
201
+ `Architecture source(s): ${JSON.stringify(inventory.documents && inventory.documents.architecture)}`,
202
+ {
203
+ label: 'epic-quality',
204
+ phase: 'EPIC_QUALITY_REVIEW',
205
+ schema: {
206
+ type: 'object',
207
+ required: ['critical', 'major', 'minor'],
208
+ properties: {
209
+ critical: { type: 'array', items: { type: 'string' } },
210
+ major: { type: 'array', items: { type: 'string' } },
211
+ minor: { type: 'array', items: { type: 'string' } },
212
+ recommendations: { type: 'array', items: { type: 'string' } }
213
+ }
214
+ }
215
+ }
216
+ )
217
+ log(`Quality: ${quality.critical.length} critical, ${quality.major.length} major, ${quality.minor.length} minor`)
218
+
219
+ // ---------------------------------------------------------------------------
220
+ // STEP 6 - Final Assessment (mirrors step-06-final-assessment.md)
221
+ // Compile all findings into one objective verdict: READY / NEEDS WORK /
222
+ // NOT READY, with the critical issues and concrete next steps. The script
223
+ // computes the verdict; it does NOT decide whether to proceed - that human
224
+ // "proceed as-is or fix" gate is owned by the orchestrating skill.
225
+ // ---------------------------------------------------------------------------
226
+ phase('FINAL_ASSESSMENT')
227
+ const final = await agent(
228
+ `You are ${role}\n` +
229
+ `STEP 6 - Final Assessment. Compile all findings into one objective readiness verdict. Be direct - do NOT soften the message. ` +
230
+ `Determine overall status: READY (no critical issues, full FR coverage), NEEDS WORK (gaps/major issues but fixable), or NOT READY (critical violations or missing core docs). ` +
231
+ `List the critical issues that must be addressed and concrete next-step action items. Do NOT decide whether to proceed - just report the state of readiness.\n` +
232
+ `Discovery: ${JSON.stringify({ duplicates: inventory.duplicates, missing: inventory.missing })}\n` +
233
+ `PRD: ${prd.functionalRequirements.length} FR / ${prd.nonFunctionalRequirements.length} NFR; completeness: ${prd.completenessAssessment || 'n/a'}\n` +
234
+ `Coverage: ${coverage.coveragePercent}% (${coverage.coveredFRs}/${coverage.totalFRs}); missing FRs: ${JSON.stringify(coverage.missingFRs)}\n` +
235
+ `UX: ${ux.uxStatus}; issues: ${JSON.stringify(ux.alignmentIssues)}; warnings: ${JSON.stringify(ux.warnings)}\n` +
236
+ `Epic quality: ${JSON.stringify({ critical: quality.critical, major: quality.major, minor: quality.minor })}`,
237
+ {
238
+ label: 'final-assessment',
239
+ phase: 'FINAL_ASSESSMENT',
240
+ schema: {
241
+ type: 'object',
242
+ required: ['readinessStatus', 'criticalIssues', 'nextSteps'],
243
+ properties: {
244
+ readinessStatus: { type: 'string', enum: ['READY', 'NEEDS WORK', 'NOT READY'] },
245
+ criticalIssues: { type: 'array', items: { type: 'string' } },
246
+ nextSteps: { type: 'array', items: { type: 'string' } },
247
+ finalNote: { type: 'string' }
248
+ }
249
+ }
250
+ }
251
+ )
252
+ log(`Readiness verdict: ${final.readinessStatus}`)
253
+
254
+ const totalIssues =
255
+ inventory.duplicates.length +
256
+ inventory.missing.length +
257
+ coverage.missingFRs.length +
258
+ ux.alignmentIssues.length +
259
+ ux.warnings.length +
260
+ quality.critical.length +
261
+ quality.major.length +
262
+ quality.minor.length
263
+
264
+ return {
265
+ workflow: 'check-implementation-readiness',
266
+ summary: `Implementation readiness: ${final.readinessStatus} - ${totalIssues} issue(s) across discovery, PRD coverage, UX, and epic quality.`,
267
+ steps: 6,
268
+ reportDate,
269
+ planningArtifacts,
270
+ needsHumanGate: true,
271
+ result: {
272
+ discovery: inventory,
273
+ prd: { frCount: prd.functionalRequirements.length, nfrCount: prd.nonFunctionalRequirements.length, completenessAssessment: prd.completenessAssessment },
274
+ coverage,
275
+ ux,
276
+ epicQuality: quality,
277
+ final
278
+ },
279
+ totalIssues
280
+ }
@@ -0,0 +1,179 @@
1
+ export const meta = {
2
+ name: 'code-review',
3
+ description: 'Native port of the BYAN code-review workflow: an ADVERSARIAL Senior Developer review that validates a story file against the actual implementation and git reality, hunts a minimum of 3-10 specific issues (AC validation, task audit, code quality, test quality), and returns a structured verdict. The fix/action-items human decision stays OUT of the script.',
4
+ phases: [
5
+ { title: 'LOAD', detail: 'load story + discover actual changes via git, cross-reference File List' },
6
+ { title: 'PLAN', detail: 'build the adversarial review attack plan' },
7
+ { title: 'REVIEW', detail: 'execute the review; enforce the >=3-issue floor with a bounded re-scan' },
8
+ { title: 'FINDINGS', detail: 'categorize HIGH/MEDIUM/LOW; return a verdict (no auto-fix here)' },
9
+ { title: 'VERDICT', detail: 'compute proposed story status + sprint-sync intent for the human gate' },
10
+ ],
11
+ }
12
+
13
+ // ---------------------------------------------------------------------------
14
+ // FD / STRICT STATE CONTRACT (re-asserted inline — enforcement-bridge).
15
+ //
16
+ // The in-CLI Workflow tool runs this script OUTSIDE the conversation turn, so
17
+ // BYAN's main-thread hooks (fd-phase-guard, strict-scope-guard, strict-stop-
18
+ // guard, mantra-validate) DO NOT fire here. This script therefore:
19
+ // - NEVER imports/requires _byan/.../lib/fd-state.js and NEVER writes
20
+ // fd-state.json directly (enforced by byan-lint-workflows.js).
21
+ // - uses NO wall-clock / NO randomness primitive (wall-clock, RNG,
22
+ // a wall-clock read break resume) — any date/id is passed via args.
23
+ // - returns DATA only. The orchestrating skill is the human-gated conductor;
24
+ // IT records FD/strict state via the byan_fd_* / byan_strict_* MCP tools
25
+ // AT the gate, and AT the gate it asks the human the fix/action-items
26
+ // decision (source step 4) and applies the chosen story-status update
27
+ // + sprint-status.yaml sync (source step 5).
28
+ // ---------------------------------------------------------------------------
29
+
30
+ // Issue-floor guard — turns the source's prose rule ("Find 3-10 issues; if
31
+ // total_issues_found < 3 -> NOT LOOKING HARD ENOUGH, re-examine") into a real
32
+ // JS counter the model cannot silently overrun. Bounded re-scan: one extra
33
+ // adversarial pass, never an unbounded loop.
34
+ const MIN_ISSUES = 3
35
+ const MAX_RESCANS = 1
36
+
37
+ const REVIEW_SCHEMA = {
38
+ type: 'object',
39
+ required: ['totalIssues', 'high', 'medium', 'low', 'findings'],
40
+ properties: {
41
+ totalIssues: { type: 'integer', description: 'total specific, actionable issues found' },
42
+ high: { type: 'integer', description: 'count of HIGH severity (must-fix) issues' },
43
+ medium: { type: 'integer', description: 'count of MEDIUM (should-fix) issues' },
44
+ low: { type: 'integer', description: 'count of LOW (nice-to-fix) issues' },
45
+ gitDiscrepancies: { type: 'integer', description: 'git-vs-story File List discrepancies' },
46
+ acMissing: { type: 'integer', description: 'Acceptance Criteria found MISSING or PARTIAL' },
47
+ tasksFalselyComplete: { type: 'integer', description: 'tasks marked [x] but NOT actually done (CRITICAL)' },
48
+ findings: {
49
+ type: 'array',
50
+ description: 'each: severity + description + file:line evidence',
51
+ items: {
52
+ type: 'object',
53
+ required: ['severity', 'description'],
54
+ properties: {
55
+ severity: { type: 'string', enum: ['HIGH', 'MEDIUM', 'LOW'] },
56
+ category: { type: 'string', description: 'ac|task|security|performance|error-handling|quality|test|git-discrepancy' },
57
+ description: { type: 'string' },
58
+ evidence: { type: 'string', description: 'file:line or git proof' },
59
+ },
60
+ },
61
+ },
62
+ },
63
+ }
64
+
65
+ const story = (args && args.story) || (args && args.story_path) || 'the story file under review'
66
+ const reviewer = (args && args.user_name) || 'reviewer'
67
+
68
+ // --- Step 1: Load story and discover changes -------------------------------
69
+ phase('LOAD')
70
+ const loaded = await agent(
71
+ `You are code-review (BYAN ADVERSARIAL Senior Developer reviewer). Target story: ${JSON.stringify(story)}.\n` +
72
+ `Read the COMPLETE story file. Set story_key from the filename (e.g. "1-2-user-auth.md" -> "1-2-user-auth") or metadata. ` +
73
+ `Parse: Story, Acceptance Criteria, Tasks/Subtasks (note [x] vs [ ]), Dev Agent Record -> File List, Change Log, Status.\n` +
74
+ `Then DISCOVER ACTUAL CHANGES via git (if a git repo is present): run "git status --porcelain", ` +
75
+ `"git diff --name-only", and "git diff --cached --name-only"; compile the list of actually changed files. ` +
76
+ `Cross-reference the story File List against git reality and note discrepancies: ` +
77
+ `(a) files in git but NOT in the story File List, (b) files in the File List with NO git change, ` +
78
+ `(c) undocumented uncommitted changes.\n` +
79
+ `Load project-context.md for coding standards if it exists. ` +
80
+ `EXCLUDE from review: _byan/, _byan-output/, and IDE/CLI config folders (.cursor/, .windsurf/, .claude/). ` +
81
+ `If the story cannot be found or read, say so explicitly — do not invent one.`,
82
+ { label: 'load-story', phase: 'LOAD' }
83
+ )
84
+
85
+ // --- Step 2: Build review attack plan --------------------------------------
86
+ phase('PLAN')
87
+ const plan = await agent(
88
+ `Build the adversarial review attack plan for story ${JSON.stringify(story)}.\n` +
89
+ `Context from load: ${loaded}\n` +
90
+ `Extract ALL Acceptance Criteria, ALL Tasks/Subtasks with completion status, and the claimed File List changes. ` +
91
+ `Produce the four-axis plan: (1) AC Validation — verify each AC is actually implemented; ` +
92
+ `(2) Task Audit — verify each [x] task is really done; (3) Code Quality — security, performance, maintainability; ` +
93
+ `(4) Test Quality — real assertions vs placeholder tests. ` +
94
+ `List the comprehensive review file set = story File List UNION git-discovered files.`,
95
+ { label: 'attack-plan', phase: 'PLAN' }
96
+ )
97
+
98
+ // --- Step 3: Execute adversarial review (with bounded >=3-issue floor) ------
99
+ phase('REVIEW')
100
+ let review = { totalIssues: 0, high: 0, medium: 0, low: 0, findings: [] }
101
+ let rescans = 0
102
+ while (true) {
103
+ const harder =
104
+ rescans === 0
105
+ ? ''
106
+ : `\nPREVIOUS PASS FOUND ONLY ${review.totalIssues} issue(s) — NOT LOOKING HARD ENOUGH. ` +
107
+ `Re-examine for: edge cases & null handling, architecture violations, documentation gaps, ` +
108
+ `integration issues, dependency problems, git commit message quality. Find at least 3 MORE.`
109
+ review = await agent(
110
+ `Execute the ADVERSARIAL review for story ${JSON.stringify(story)}. VALIDATE EVERY CLAIM against git reality.\n` +
111
+ `Plan: ${plan}\n` +
112
+ `Score git-vs-story discrepancies: files changed but not in File List -> MEDIUM; ` +
113
+ `story lists files but no git change -> HIGH (false claim); undocumented uncommitted changes -> MEDIUM.\n` +
114
+ `For EACH Acceptance Criterion: search the implementation for evidence -> IMPLEMENTED / PARTIAL / MISSING; ` +
115
+ `MISSING or PARTIAL = HIGH finding.\n` +
116
+ `For EACH task marked [x]: search files for proof it was actually done; if marked [x] but NOT done = CRITICAL finding ` +
117
+ `(record file:line proof).\n` +
118
+ `For EACH file in the comprehensive review set: check Security (injection, missing validation, auth), ` +
119
+ `Performance (N+1, inefficient loops, missing caching), Error Handling (missing try/catch, poor messages), ` +
120
+ `Code Quality (complex functions, magic numbers, poor naming), Test Quality (real assertions vs placeholders).\n` +
121
+ `Do NOT accept "looks good". Find a MINIMUM of ${MIN_ISSUES} specific, actionable issues; aim for 3-10. ` +
122
+ `Every finding needs file:line (or git) evidence.${harder}`,
123
+ { label: rescans === 0 ? 'adversarial-review' : `adversarial-rescan-${rescans}`, phase: 'REVIEW', schema: REVIEW_SCHEMA }
124
+ )
125
+ const enough = (review.totalIssues || 0) >= MIN_ISSUES
126
+ log(`review pass ${rescans + 1}: ${review.totalIssues} issues (H${review.high}/M${review.medium}/L${review.low}) -> ${enough ? 'floor met' : 'below floor'}`)
127
+ if (enough || rescans >= MAX_RESCANS) break
128
+ rescans += 1
129
+ }
130
+
131
+ // --- Step 4: Present findings (DECISION stays at the human gate) ------------
132
+ phase('FINDINGS')
133
+ // Source step 4 asks the human: 1) auto-fix, 2) create action items, 3) details.
134
+ // That branch is a human gate — kept OUT of the script. We only categorize and
135
+ // emit fix-ready action-item lines so the orchestrating skill can offer them.
136
+ const findings = await agent(
137
+ `Categorize and present the review findings for story ${JSON.stringify(story)} (reviewer: ${JSON.stringify(reviewer)}).\n` +
138
+ `Review result: ${JSON.stringify(review)}\n` +
139
+ `Group findings into HIGH (must fix), MEDIUM (should fix), LOW (nice to fix). ` +
140
+ `For each finding, also produce a ready-to-paste story action-item line in the form ` +
141
+ `"- [ ] [AI-Review][Severity] Description [file:line]". ` +
142
+ `Do NOT auto-fix anything and do NOT prompt the user — the fix/action-items/details decision belongs to the human gate. ` +
143
+ `Output a clear findings report plus the action-item lines.`,
144
+ { label: 'present-findings', phase: 'FINDINGS' }
145
+ )
146
+
147
+ // --- Step 5: Compute proposed status (the human gate applies it) ------------
148
+ phase('VERDICT')
149
+ // Source step 5: status = "done" iff all HIGH+MEDIUM fixed AND all ACs implemented,
150
+ // else "in-progress"; then sync sprint-status.yaml. No fixes have been applied in
151
+ // this autonomous pass, so unresolved HIGH/MEDIUM or missing ACs => proposed
152
+ // "in-progress". The skill writes the story Status + sprint sync at the gate.
153
+ const blockingIssues = (review.high || 0) + (review.medium || 0)
154
+ const acGap = (review.acMissing || 0) > 0 || (review.tasksFalselyComplete || 0) > 0
155
+ const cleanForDone = blockingIssues === 0 && !acGap
156
+ const proposedStatus = cleanForDone ? 'done' : 'in-progress'
157
+
158
+ // Return DATA only. The skill presents this at the human gate, asks the
159
+ // fix/action-items decision, applies the story-status update + sprint sync,
160
+ // and records FD/strict state via MCP.
161
+ return {
162
+ workflow: 'code-review',
163
+ story,
164
+ totalIssues: review.totalIssues || 0,
165
+ high: review.high || 0,
166
+ medium: review.medium || 0,
167
+ low: review.low || 0,
168
+ gitDiscrepancies: review.gitDiscrepancies || 0,
169
+ acMissing: review.acMissing || 0,
170
+ tasksFalselyComplete: review.tasksFalselyComplete || 0,
171
+ metMinimumIssueFloor: (review.totalIssues || 0) >= MIN_ISSUES,
172
+ rescans,
173
+ findings: review.findings || [],
174
+ presentation: findings,
175
+ proposedStatus,
176
+ needsHumanGate: true,
177
+ gateDecision: ['auto-fix', 'create-action-items', 'show-details'],
178
+ syncSprintStatusOnGate: true,
179
+ }