@polymorphism-tech/morph-spec 8.47.0 → 9.0.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 (222) hide show
  1. package/CLAUDE.md +48 -39
  2. package/README.md +3 -4
  3. package/bin/morph-spec.js +37 -51
  4. package/bin/validate.js +3 -111
  5. package/claude-plugin.json +1 -1
  6. package/docs/CHEATSHEET.md +1 -1
  7. package/docs/QUICKSTART.md +1 -1
  8. package/framework/CLAUDE.md +41 -101
  9. package/framework/MORPH.md +95 -252
  10. package/framework/agents.json +75 -18
  11. package/framework/commands/morph-apply.md +5 -28
  12. package/framework/commands/morph-archive.md +1 -1
  13. package/framework/commands/morph-hotfix.md +8 -8
  14. package/framework/commands/morph-infra.md +1 -1
  15. package/framework/commands/morph-preflight.md +2 -3
  16. package/framework/commands/morph-proposal.md +2 -50
  17. package/framework/commands/morph-status.md +3 -3
  18. package/framework/docs/CLI.md +585 -286
  19. package/framework/evals/review-checklist.md +82 -41
  20. package/framework/hooks/README.md +10 -11
  21. package/framework/hooks/claude-code/core/comment-guard.js +1 -1
  22. package/framework/hooks/claude-code/core/denylist.json +33 -3
  23. package/framework/hooks/claude-code/core/enforce-phase-writes.js +16 -20
  24. package/framework/hooks/claude-code/core/gate-guard.js +2 -11
  25. package/framework/hooks/claude-code/core/pre-bash-denylist.js +38 -0
  26. package/framework/hooks/claude-code/core/protect-spec-files.js +30 -242
  27. package/framework/hooks/claude-code/core/state-sync.js +7 -21
  28. package/framework/hooks/claude-code/core/telemetry-log.js +3 -3
  29. package/framework/hooks/claude-code/core/validate-completion.js +33 -97
  30. package/framework/hooks/claude-code/core/warn-bash-source-write.js +31 -0
  31. package/framework/hooks/claude-code/core/worktree-context.js +5 -4
  32. package/framework/hooks/claude-code/statusline.py +55 -41
  33. package/framework/hooks/package.json +3 -0
  34. package/framework/hooks/shared/activity-logger.js +1 -1
  35. package/framework/hooks/shared/build-check.js +10 -6
  36. package/framework/hooks/shared/command-tokens.js +169 -0
  37. package/framework/hooks/shared/comment-rules.js +1 -1
  38. package/framework/hooks/shared/comment-scanner.js +10 -23
  39. package/framework/hooks/shared/comment-stripper.js +1 -1
  40. package/framework/hooks/shared/e2e-check.js +64 -27
  41. package/framework/hooks/shared/errata.js +72 -0
  42. package/framework/hooks/shared/feature-locator.js +1 -1
  43. package/framework/hooks/shared/frontend-locations.js +6 -0
  44. package/framework/hooks/shared/gate-question.js +18 -0
  45. package/framework/hooks/shared/phase-utils.js +15 -32
  46. package/framework/hooks/shared/slice-progress.js +118 -0
  47. package/framework/hooks/shared/spawn-command.js +23 -0
  48. package/framework/hooks/shared/state-reader.js +61 -87
  49. package/framework/hooks/shared/state-writer.js +2 -3
  50. package/framework/mcp/registry.json +3 -4
  51. package/framework/phases.json +23 -39
  52. package/framework/schemas/config.schema.json +14 -9
  53. package/framework/schemas/feature.schema.json +15 -50
  54. package/framework/skills/README.md +3 -4
  55. package/framework/skills/core/create-umbraco-lp/SKILL.md +1 -1
  56. package/framework/skills/core/migrate-lp-to-umbraco/SKILL.md +1 -1
  57. package/framework/skills/core/morph-apply/SKILL.md +149 -222
  58. package/framework/skills/core/morph-hotfix/SKILL.md +33 -42
  59. package/framework/skills/core/morph-machine/SKILL.md +2 -2
  60. package/framework/skills/core/morph-media/SKILL.md +1 -1
  61. package/framework/skills/core/morph-plan/SKILL.md +137 -299
  62. package/framework/skills/core/morph-review/SKILL.md +111 -136
  63. package/framework/skills/core/morph-standards/SKILL.md +27 -39
  64. package/framework/skills/core/morph-uiux/SKILL.md +77 -152
  65. package/framework/standards/STANDARDS.json +86 -1218
  66. package/framework/standards/STANDARDS.meta.json +1305 -0
  67. package/framework/standards/ai-agents/evals-with-cache.md +1 -2
  68. package/framework/standards/ai-agents/setup.md +1 -1
  69. package/framework/standards/architecture/code-comments.md +6 -6
  70. package/framework/standards/integration/mcp/mcp-tools.md +7 -7
  71. package/framework/templates/README.md +2 -3
  72. package/framework/templates/REGISTRY.json +6 -170
  73. package/framework/templates/docs/plan.md +72 -0
  74. package/framework/templates/dotnet/ai-kit/README.md +1 -9
  75. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Morph.AiKit.Tests.csproj +0 -10
  76. package/framework/templates/meta-prompts/squad-leaders/backend-squad.md +1 -1
  77. package/framework/templates/meta-prompts/squad-leaders/frontend-squad.md +1 -1
  78. package/framework/templates/meta-prompts/squad-leaders/squad-leader.md +1 -1
  79. package/framework/templates/meta-prompts/validators/pre-commit-validator.md +3 -4
  80. package/package.json +1 -1
  81. package/src/commands/e2e/e2e.js +2 -2
  82. package/src/commands/observability/cost.js +18 -60
  83. package/src/commands/project/doctor-procs.js +1 -1
  84. package/src/commands/project/doctor.js +9 -9
  85. package/src/commands/project/fleet.js +4 -4
  86. package/src/commands/project/heavy.js +3 -3
  87. package/src/commands/project/init.js +4 -0
  88. package/src/commands/project/setup-infra-cmd.js +2 -1
  89. package/src/commands/project/stack-scan.js +58 -0
  90. package/src/commands/project/standards.js +79 -25
  91. package/src/commands/project/status.js +29 -69
  92. package/src/commands/project/update.js +17 -1
  93. package/src/commands/project/worktree.js +1 -1
  94. package/src/commands/state/advance.js +62 -46
  95. package/src/commands/state/approve.js +81 -141
  96. package/src/commands/state/archive.js +20 -84
  97. package/src/commands/state/auto-approval.js +68 -0
  98. package/src/commands/state/create.js +28 -1
  99. package/src/commands/state/delete.js +1 -1
  100. package/src/commands/state/finish.js +11 -23
  101. package/src/commands/state/gate-check.js +85 -84
  102. package/src/commands/state/gate-decision.js +6 -4
  103. package/src/commands/state/handoff.js +1 -1
  104. package/src/commands/state/list.js +9 -9
  105. package/src/commands/state/report-check.js +157 -311
  106. package/src/commands/state/retype.js +9 -3
  107. package/src/commands/validation/mutate.js +77 -14
  108. package/src/commands/validation/plan-check.js +81 -0
  109. package/src/commands/validation/validate-feature.js +60 -135
  110. package/src/commands/validation/verify.js +40 -72
  111. package/src/core/paths/output-schema.js +19 -66
  112. package/src/core/state/gate-order.js +5 -6
  113. package/src/core/state/lifecycle-audit.js +2 -2
  114. package/src/core/state/state-manager.js +17 -98
  115. package/src/core/templates/template-registry.js +2 -2
  116. package/src/core/templates/template-seed.js +22 -0
  117. package/src/core/work-types.js +10 -10
  118. package/src/dashboard/app/components/ActivityFeed.jsx +2 -3
  119. package/src/dashboard/app/components/CommandPalette.jsx +5 -5
  120. package/src/dashboard/app/components/EntityLink.jsx +1 -1
  121. package/src/dashboard/app/hooks/useMorphQuery.js +1 -1
  122. package/src/dashboard/app/lib/phases.js +2 -4
  123. package/src/dashboard/app/pages/Activity.jsx +1 -1
  124. package/src/dashboard/app/pages/FeatureDetail.jsx +139 -129
  125. package/src/dashboard/app/pages/Features.jsx +9 -9
  126. package/src/dashboard/app/pages/Guide.jsx +2 -2
  127. package/src/dashboard/app/pages/PhasePipeline.jsx +3 -4
  128. package/src/dashboard/app/pages/Standards.jsx +1 -1
  129. package/src/dashboard/scanner/activity-scanner.js +5 -15
  130. package/src/dashboard/scanner/agents-scanner.js +1 -1
  131. package/src/dashboard/scanner/docs-scanner.js +2 -2
  132. package/src/dashboard/scanner/features-scanner.js +95 -60
  133. package/src/dashboard/scanner/project-api.js +1 -1
  134. package/src/dashboard/scanner/standards-scanner.js +2 -1
  135. package/src/lib/ci/ci-verify.js +17 -1
  136. package/src/lib/ci/github-ci.js +1 -1
  137. package/src/lib/detectors/index.js +3 -8
  138. package/src/lib/generators/handoff-generator.js +34 -65
  139. package/src/lib/generators/settings-generator.js +11 -89
  140. package/src/lib/git/evidence-staleness.js +1 -1
  141. package/src/lib/git/tree-fingerprint.js +19 -7
  142. package/src/lib/git/tree-state.js +2 -2
  143. package/src/lib/heavy/cleanup.js +1 -5
  144. package/src/lib/installers/memory-installer.js +6 -8
  145. package/src/lib/mutation/commands.js +3 -2
  146. package/src/lib/{tasks/dotnet-test-introspection.js → mutation/dotnet-introspection.js} +17 -282
  147. package/src/lib/mutation/plan.js +14 -6
  148. package/src/lib/mutation/runner.js +1 -1
  149. package/src/lib/mutation/subset.js +46 -9
  150. package/src/lib/plan/artifact-vocabulary.js +60 -0
  151. package/src/lib/plan/checks.js +234 -0
  152. package/src/lib/plan/plan-parser.js +209 -0
  153. package/src/lib/plan/plan-template.js +18 -0
  154. package/src/lib/review-reports.js +222 -0
  155. package/src/lib/risk-detector.js +131 -140
  156. package/src/lib/specs/adr-index.js +50 -69
  157. package/src/lib/specs/design-seed.js +18 -0
  158. package/src/lib/specs/frontmatter.js +44 -0
  159. package/src/lib/specs/gfm-table.js +17 -0
  160. package/src/lib/specs/old-format.js +68 -0
  161. package/src/lib/specs/revocations.js +37 -95
  162. package/src/lib/specs/screen-checklist.js +18 -17
  163. package/src/lib/stack/dotnet-build-ignores.js +47 -0
  164. package/src/lib/stack/stack-scan.js +267 -0
  165. package/src/lib/standards/registry.js +43 -0
  166. package/src/lib/standards/sections.js +58 -0
  167. package/src/lib/tasks/eval-node.js +4 -12
  168. package/src/lib/tasks/test-nodes.js +1 -74
  169. package/src/lib/tasks/test-runner.js +75 -117
  170. package/src/lib/telemetry/metrics.js +8 -69
  171. package/src/lib/telemetry/telemetry-reader.js +5 -118
  172. package/src/lib/telemetry/verify-event.js +5 -7
  173. package/src/lib/validators/code-budget/code-budget-validator.js +1 -1
  174. package/src/lib/validators/contracts/contract-compliance-validator.js +2 -2
  175. package/src/lib/validators/reuse/reuse-validator.js +22 -45
  176. package/src/lib/validators/traceability-check.js +85 -129
  177. package/src/lib/validators/verify-runner.js +118 -235
  178. package/src/lib/worktree/docker-audit.js +1 -2
  179. package/src/lib/worktree/fleet-scanner.js +25 -38
  180. package/src/scripts/setup-infra.js +9 -0
  181. package/src/utils/agents-installer.js +76 -9
  182. package/src/utils/claude-settings-manager.js +0 -35
  183. package/src/utils/file-copier.js +27 -1
  184. package/src/utils/hooks-installer.js +16 -9
  185. package/src/utils/skills-installer.js +1 -2
  186. package/framework/evals/trace-schema.md +0 -67
  187. package/framework/hooks/claude-code/core/tasks-json-guard.js +0 -83
  188. package/framework/hooks/claude-code/core/trace-autogen.js +0 -277
  189. package/framework/hooks/git/pre-commit/specs.sh +0 -50
  190. package/framework/hooks/shared/tasks-validator.js +0 -111
  191. package/framework/rules/morph-task-tracking.md +0 -54
  192. package/framework/rules/morph-workflow.md +0 -244
  193. package/framework/schemas/tasks.schema.json +0 -79
  194. package/framework/skills/core/morph-brainstorming/SKILL.md +0 -161
  195. package/framework/skills/core/morph-implement/SKILL.md +0 -194
  196. package/framework/skills/core/morph-proposal/SKILL.md +0 -152
  197. package/framework/skills/core/morph-stack-scan/SKILL.md +0 -145
  198. package/framework/templates/docs/proposal.md +0 -192
  199. package/framework/templates/docs/spec.md +0 -57
  200. package/framework/templates/docs/ui-components.md +0 -52
  201. package/framework/templates/docs/ui-design-system.md +0 -76
  202. package/framework/templates/docs/ui-flows.md +0 -167
  203. package/framework/templates/examples/spec-examples.md +0 -91
  204. package/framework/templates/feature/decisions.md +0 -124
  205. package/framework/templates/feature/recap.md +0 -145
  206. package/framework/templates/tasks.template.json +0 -17
  207. package/src/commands/state/usecase.js +0 -143
  208. package/src/commands/tasks/dag.js +0 -181
  209. package/src/lib/agents/output-collector.js +0 -76
  210. package/src/lib/evaluator-report.js +0 -104
  211. package/src/lib/specs/acervo-format.js +0 -70
  212. package/src/lib/specs/acervo-lifecycle.js +0 -264
  213. package/src/lib/specs/done-criteria-check.js +0 -200
  214. package/src/lib/specs/usecase-check.js +0 -301
  215. package/src/lib/specs/usecase-promoter.js +0 -301
  216. package/src/lib/specs/usecase-registry.js +0 -237
  217. package/src/lib/tasks/dispatch-planner.js +0 -319
  218. package/src/lib/tasks/mermaid-renderer.js +0 -132
  219. package/src/lib/tasks/task-classifier.js +0 -30
  220. package/src/lib/tasks/task-parser.js +0 -209
  221. package/src/lib/tasks/tasks-json-parser.js +0 -296
  222. package/src/lib/tasks/test-scope.js +0 -597
package/bin/morph-spec.js CHANGED
@@ -45,6 +45,8 @@ const claimCommand = lazy('../src/commands/project/claim.js', 'claimCommand');
45
45
  const standardsCommand = lazy('../src/commands/project/standards.js', 'standardsCommand');
46
46
  const reportCheckCommand = lazy('../src/commands/state/report-check.js', 'reportCheckCommand');
47
47
  const scoutCheckCommand = lazy('../src/commands/validation/scout-check.js', 'scoutCheckCommand');
48
+ const planCheckCommand = lazy('../src/commands/validation/plan-check.js', 'planCheckCommand');
49
+ const stackScanCommand = lazy('../src/commands/project/stack-scan.js', 'stackScanCommand');
48
50
 
49
51
  // === Approval gates (human-only) ===
50
52
  const approveCommand = lazy('../src/commands/state/approve.js', 'approveCommand');
@@ -60,11 +62,8 @@ const retypeCommand = lazy('../src/commands/state/retype.js', 'retypeCommand');
60
62
  const handoffCommand = lazy('../src/commands/state/handoff.js', 'handoffCommand');
61
63
  const listCommand = lazy('../src/commands/state/list.js', 'listCommand');
62
64
  const deleteCommand = lazy('../src/commands/state/delete.js', 'deleteCommand');
63
- const usecaseReserveCommand = lazy('../src/commands/state/usecase.js', 'usecaseReserveCommand');
64
- const usecaseCheckCommand = lazy('../src/commands/state/usecase.js', 'usecaseCheckCommand');
65
65
 
66
66
  // === Tasks ===
67
- const dagCommand = lazy('../src/commands/tasks/dag.js', 'dagCommand');
68
67
 
69
68
  // === Codebase graph ===
70
69
  const graphStatusCommand = lazy('../src/commands/graph/status.js', 'graphStatusCommand');
@@ -174,7 +173,7 @@ program
174
173
 
175
174
  program
176
175
  .command('list')
177
- .description('List every feature × status × gates (G1/G2/G3) × workType — the audit board')
176
+ .description('List every feature × status × gates (G1 plan / Gd uiux / G3 review) × workType — the audit board')
178
177
  .option('--all', 'Include archived features (.morph/archive)')
179
178
  .option('--archived', 'Include archived features (alias of --all)')
180
179
  .option('--no-branch', 'Skip reading morph/{feature} for truth — report only what is on disk in this tree')
@@ -184,12 +183,12 @@ program
184
183
  // ─── Approval gates (dev-only) ────────────────────────────────────────────
185
184
  program
186
185
  .command('approve <feature> <gate>')
187
- .description('Approve a phase gate (proposal, plan, review). Enforces gate order (N requires N-1)')
186
+ .description('Approve a phase gate (plan, uiux, review). Enforces gate order (uiux and review require plan)')
188
187
  .option('--approver <name>', 'Name of approver (default: current user when interactive, "auto" otherwise)')
189
188
  .option('--mode <mode>', 'Approval mode: "user" or "auto" (default: detected from TTY)')
190
189
  .option('--notes <notes>', 'Approval notes')
191
190
  .option('--force', 'Approve out of order (bypass the gate-monotonicity check)')
192
- .option('--self-assessed', 'Gate 3 only: approve without 4-review/evaluator-report.md, recording the degradation in feature.json')
191
+ .option('--self-assessed', 'Gate 3 only: approve without the review reports (verifier.md, reviewer.md, security.md), recording the degradation in feature.json')
193
192
  .action((feature, gate, options) => approveCommand(feature, gate, options));
194
193
 
195
194
  program
@@ -197,7 +196,7 @@ program
197
196
  .description('Approve the current phase gate and scaffold the next phase folder (one step)')
198
197
  .option('--approver <name>', 'Name of approver (default: current user when interactive, "auto" otherwise)')
199
198
  .option('--mode <mode>', 'Approval mode: "user" or "auto" (default: detected from TTY)')
200
- .option('--design', 'From proposal, advance into the optional design (uiux) phase instead of plan')
199
+ .option('--design', 'From plan, advance into the optional design (uiux) phase instead of implement')
201
200
  .option('--notes <notes>', 'Approval notes')
202
201
  .option('--force', 'Advance even if a prerequisite gate is unapproved (out-of-order recovery)')
203
202
  .action((feature, options) => advanceCommand(feature, options));
@@ -251,7 +250,7 @@ program
251
250
  program
252
251
  .command('gate-check <feature> <gate>')
253
252
  .description('Decide + record a gate\'s trust decision from disk-derived signals (shouldPauseGate) — the deterministic default; see gate-decision for the manual escape hatch')
254
- .option('--signals <json>', 'Override ONLY standardsViolations/designSystemDivergence (not derivable from disk) — everything else is read from feature.json/tasks.json/git and cannot be overridden here')
253
+ .option('--signals <json>', 'Override ONLY standardsViolations/designSystemDivergence (not derivable from disk) — everything else is read from feature.json/checks.json/git and cannot be overridden here')
255
254
  .option('--trust <mode>', 'Trust mode to decide with (default: config.json → trust, or "auto")')
256
255
  .option('--json', 'Output as JSON')
257
256
  .action((feature, gateArg, options) => gateCheckCommand(feature, gateArg, options));
@@ -294,33 +293,6 @@ program
294
293
  .option('--here', 'Force building/writing in the current directory, even if another tree owns this feature')
295
294
  .action((feature, options) => handoffCommand(feature, options));
296
295
 
297
- // ─── Use cases ────────────────────────────────────────────────────────────
298
- const usecaseCommand = program
299
- .command('usecase')
300
- .description('Project-wide use cases: UC-{nn} numbering (acervo + every worktree of this repo) and the acervo lifecycle check');
301
-
302
- usecaseCommand
303
- .command('reserve')
304
- .description('Atomically reserve the next N UC-{nn} numbers, shared across every worktree of this repo — replaces the old max+1 disk scan, which collides across worktrees')
305
- .option('--count <n>', 'How many numbers to reserve', '1')
306
- .option('--feature <name>', 'Feature to record as the reservation owner (defaults to the sole active feature, if unambiguous) — also what the promotion collision guard compares against')
307
- .option('--json', 'Output as JSON')
308
- .action((options) => usecaseReserveCommand(options));
309
-
310
- usecaseCommand
311
- .command('check <feature>')
312
- .description('Check a feature against the acervo lifecycle: tasks citing a superseded UC, malformed supersession frontmatter, spec.md revocation rows the finish could not apply (plus the task/use-case plumbing dag checks, when tasks.json exists)')
313
- .option('--json', 'Output as JSON')
314
- .action((feature, options) => usecaseCheckCommand(feature, options));
315
-
316
- // ─── Tasks ────────────────────────────────────────────────────────────────
317
- program
318
- .command('dag <feature>')
319
- .description('Analyze the tasks.json DAG and print the sequential vs parallel dispatch decision (effort-weighted)')
320
- .option('--json', 'Output as JSON')
321
- .option('--mermaid', 'Emit the tasks.json DAG as a Mermaid flowchart (flowchart TD)')
322
- .action((feature, options) => dagCommand(feature, options));
323
-
324
296
  // ─── Codebase graph ───────────────────────────────────────────────────────
325
297
  const graphCommand = program
326
298
  .command('graph')
@@ -388,24 +360,23 @@ program
388
360
  .action(validateFeatureCommand);
389
361
 
390
362
  program
391
- .command('verify <feature> [task]')
363
+ .command('verify <feature>')
392
364
  .description('Run the deterministic verification chain (build + tests + validators + e2e) — code before the LLM judge')
393
365
  .option('--json', 'Output as JSON')
394
366
  .option('--timeout <ms>', 'Timeout in ms for the build AND tests nodes (build default 120000; tests default 120000 per test project, or project.testTimeoutMs)', (v) => parseInt(v, 10))
395
367
  .option('--filter <ids>', 'Run only the test nodes whose id matches (comma-separated; exact or substring). Unmatched nodes are reported as skip; matching nothing is a usage error (exit 2)')
396
368
  .option('--linux', 'Run the test nodes inside a Linux container, on a COPY of the tree (the host tree is mounted read-only and copied in — a bind mount is case-insensitive and cannot reproduce case defects). No Docker = usage error, never a skip')
397
369
  .option('--linux-image <img>', 'Image used by --linux (default: mcr.microsoft.com/dotnet/sdk:10.0)')
398
- .option('--full', 'No escopo de task, desliga o recorte automático e roda todos os nós inteiros (o group da task não escolhe nós e os outputs não estreitam comandos). No escopo de feature não muda nada: ali nada é recortado')
399
- .option('--record-baseline', 'Measure every test node and write expectedCount back into .morph/config/config.json (only from an all-green run at FEATURE scope; with a task id it is a usage error; never creates config.json)')
370
+ .option('--record-baseline', 'Measure every test node and write expectedCount back into .morph/config/config.json (only from an all-green run; never creates config.json)')
400
371
  .option('--refresh-cache', 'Rewrite the response cache of every `runner: "evals"` node against the real provider. NEVER implicit: a cache rewrite is a paid call nobody asked for. Requires the declared envFile; no eval node declared, --skip-tests, or a --filter that excludes them all are usage errors (exit 2), refused BEFORE the cache is touched')
401
- .option('--skip-tests', 'Skip the test node. At feature scope the run is partial, so the verification stamp is NOT written (reason "skip-tests")')
402
- .option('--skip-build', 'Skip the build node. At feature scope the run is partial, so the verification stamp is NOT written (reason "skip-build")')
372
+ .option('--skip-tests', 'Skip the test node. The run is partial, so the verification stamp is NOT written (reason "skip-tests")')
373
+ .option('--skip-build', 'Skip the build node. The run is partial, so the verification stamp is NOT written (reason "skip-build")')
403
374
  .option('--skip-e2e', 'Skip the e2e node (Docker bring-up + Playwright)')
404
375
  .option('--fresh-e2e', 'Recreate the e2e stack from scratch: down -v (named volumes included), drop the freshness stamp, rebuild, re-seed auth')
405
376
  .option('--no-persist', 'Do not persist the result to feature.json')
406
- .option('--ci', 'Feature scope only: push morph/<feature> and take the proof from the project CI (creates .github/workflows/morph-verify.yml when no workflow runs verify). Same stamp, source "ci". No GitHub/gh/workflow = local verify with the reason; uncommitted code = exit 2; CI still running after 50 min = exit 3, no stamp')
407
- .action((feature, task, options) =>
408
- verifyCommand(feature, task, { ...options, noPersist: options.persist === false })
377
+ .option('--ci', 'Push morph/<feature> and take the proof from the project CI (creates .github/workflows/morph-verify.yml when no workflow runs verify). Same stamp, source "ci". No GitHub/gh/workflow = local verify with the reason; uncommitted code = exit 2; CI still running after 50 min = exit 3, no stamp')
378
+ .action((feature, options) =>
379
+ verifyCommand(feature, { ...options, noPersist: options.persist === false })
409
380
  );
410
381
 
411
382
  program
@@ -616,8 +587,9 @@ program
616
587
  // ─── Standards search (server-side, R2 token cut) ─────────────────────────
617
588
  program
618
589
  .command('standards')
619
- .description('Search STANDARDS.json server-side (top 3, full digest) instead of reading the whole registry. No --find: list categories + counts')
590
+ .description('Search STANDARDS.json server-side (top 3, digest + anchors) or print one section, instead of reading the whole registry. Bare: categories + counts')
620
591
  .option('--find <query>', 'Search query — matches name/id, tags/aliases, category, digest')
592
+ .option('--show <target>', '<id>: digest + anchors; <id>#<anchor>: only that section of the standard .md')
621
593
  .option('--category <category>', 'Restrict --find to a single category')
622
594
  .option('--tags <tags>', 'Restrict --find to standards carrying any of these comma-separated tags')
623
595
  .option('--json', 'Output as JSON')
@@ -625,11 +597,11 @@ program
625
597
 
626
598
  // ─── Sub-agent report protocol ────────────────────────────────────────────
627
599
  program
628
- .command('report-check <feature> [tasks...]')
629
- .description('Audit sub-agent report files against the work that actually landed. Answers "did the WORK land even though the REPORT did not" — exits 0 only when everything is intact. Several task ids audit a parallel batch in one call')
630
- .option('--before-eval', 'Save a snapshot of the tree before dispatching the evaluator; later runs report what changed since')
600
+ .command('report-check <feature> [slices...]')
601
+ .description('Audit slice report files (3-implement/reports/{slice}.md) against the work the dispatch actually wrote (telemetry, keyed by the agent that wrote the report). Exits 0 only when every audited slice is intact; naming slices audits only those')
602
+ .option('--before-eval', 'Save a snapshot of the tree before dispatching the review agents and print their models; later runs report what changed since')
631
603
  .option('--json', 'Output as JSON')
632
- .action((feature, tasks, options) => reportCheckCommand(feature, tasks.length > 1 ? tasks : tasks[0], options));
604
+ .action((feature, slices, options) => reportCheckCommand(feature, slices, options));
633
605
 
634
606
  program
635
607
  .command('scout-check <map>')
@@ -638,6 +610,20 @@ program
638
610
  .option('--json', 'Output as JSON')
639
611
  .action((map, options) => scoutCheckCommand(map, options));
640
612
 
613
+ program
614
+ .command('plan-check <feature>')
615
+ .description('Parse 2-plan/plan.md (scenarios, slices, decisions, reuse) and, with no error, write 2-plan/checks.json — the only writer of checks.json. Refuses to rewrite it once the plan gate is approved and the plan changed outside ## Errata. Exits 1 on errors, 2 when plan.md is missing')
616
+ .option('--json', 'Output as JSON')
617
+ .addHelpText('after', () => '\nGramática (framework/templates/docs/plan.md):\n\n' +
618
+ readFileSync(join(__dirname, '..', 'framework', 'templates', 'docs', 'plan.md'), 'utf8').replace(/\{\{FEATURE_NAME\}\}/g, '<feature>'))
619
+ .action((feature, options) => planCheckCommand(feature, options));
620
+
621
+ program
622
+ .command('stack-scan [feature]')
623
+ .description('Audit the code against config.project.stack, judging only the configured stacks (runtime, ORM, database, Guid.NewGuid, generic repository, service layer, raw SQL, sealed, router, UI library) by severity. With a feature, write .morph/features/<f>/2-plan/stack-scan.md; without, print the report')
624
+ .option('--json', 'Output as JSON')
625
+ .action((feature, options) => stackScanCommand(feature, options));
626
+
641
627
  // ─── Dashboard ────────────────────────────────────────────────────────────
642
628
  program
643
629
  .command('dashboard')
@@ -657,10 +643,10 @@ program
657
643
 
658
644
  program
659
645
  .command('cost [feature]')
660
- .description('Cost-facing view over .morph/logs/events.jsonl: task duration, bytes re-ingested by kind (proxy, not tokens), dispatch counts')
661
- .option('--by <mode>', 'Group by: task|phase (default: feature-wide summary; with --all-trees, applies to the combined aggregate)')
646
+ .description('Cost-facing view over .morph/logs/events.jsonl: bytes re-ingested by kind (proxy, not tokens), dispatch counts, real tokens when observed')
647
+ .option('--by <mode>', 'Group by: phase (default: feature-wide summary; with --all-trees, applies to the combined aggregate)')
662
648
  .option('--all-trees', 'Aggregate across every git worktree with a log plus the logs finish saved in .git/morph-spec/finish-backup — per-tree breakdown + combined total')
663
- .option('--metrics', 'Loop measurements: turns, tool calls (orchestrator x sub-agent), time per command class, identical reruns, rereads, feature verify count, git per task, reuse validator per tree')
649
+ .option('--metrics', 'Loop measurements: turns, tool calls (orchestrator x sub-agent), time per command class, identical reruns, rereads, verify count per feature, git calls, reuse validator per tree')
664
650
  .option('--top <n>', 'With --metrics: how many reread files to list (default 10)', (v) => Number.parseInt(v, 10))
665
651
  .option('--json', 'Output the aggregate as JSON')
666
652
  .action((feature, options) => costCommand(feature, options));
package/bin/validate.js CHANGED
@@ -5,9 +5,8 @@
5
5
  *
6
6
  * Runs validators for the current project stack (detected from .morph/config/config.json).
7
7
  *
8
- * .NET stacks: packages, spec-tasks
9
- * Next.js stack: next-components, spec-tasks
10
- * Other stacks: spec-tasks
8
+ * .NET stacks: packages
9
+ * Next.js stack: next-components
11
10
  *
12
11
  * Usage:
13
12
  * morph-spec validate [options]
@@ -21,12 +20,7 @@
21
20
  import chalk from 'chalk';
22
21
  import { getStackProfile } from '../src/lib/stack/stack-profile.js';
23
22
 
24
- /**
25
- * Build the VALIDATORS registry for the current stack.
26
- * .NET stacks → packages, spec-tasks
27
- * nextjs stack → next-components, spec-tasks
28
- * other stacks → spec-tasks only
29
- */
23
+ /** The validators of the current stack: .NET → packages, Next.js → next-components. */
30
24
  async function buildValidators(stack) {
31
25
  const validators = {};
32
26
 
@@ -52,111 +46,9 @@ async function buildValidators(stack) {
52
46
  };
53
47
  }
54
48
 
55
- validators['spec-tasks'] = {
56
- name: 'Spec vs Tasks Coverage',
57
- description: 'Validates that tasks.json covers all requirements from spec.md',
58
- run: validateSpecVsTasks
59
- };
60
-
61
49
  return validators;
62
50
  }
63
51
 
64
- /**
65
- * Validate spec.md requirements are covered by tasks
66
- */
67
- async function validateSpecVsTasks(projectPath, options = {}) {
68
- const path = await import('path');
69
- const fs = await import('fs');
70
- const { loadState } = await import('../src/core/state/state-manager.js');
71
-
72
- const results = [];
73
- let errors = 0;
74
- let warnings = 0;
75
-
76
- try {
77
- const state = loadState(false);
78
- if (!state || !state.features) {
79
- return { status: 'ok', errors: 0, warnings: 0, message: 'No features to validate' };
80
- }
81
-
82
- for (const [featureName, feature] of Object.entries(state.features)) {
83
- const outputsPath = path.join(projectPath, '.morph/features', featureName);
84
- const specPath = path.join(outputsPath, 'spec.md');
85
-
86
- if (!fs.existsSync(specPath)) {
87
- continue; // No spec to validate
88
- }
89
-
90
- // Read spec.md and extract requirements
91
- const specContent = fs.readFileSync(specPath, 'utf-8');
92
-
93
- // Extract requirement patterns (## Requisitos, - [ ], numbered lists, etc.)
94
- const requirementPatterns = [
95
- /^#+\s*Requisitos?\s*$/gim,
96
- /^-\s*\[.\]\s*(.+)$/gm,
97
- /^\d+\.\s+(.+)$/gm
98
- ];
99
-
100
- const requirements = [];
101
- for (const pattern of requirementPatterns) {
102
- const matches = specContent.matchAll(pattern);
103
- for (const match of matches) {
104
- if (match[1]) {
105
- requirements.push(match[1].trim());
106
- }
107
- }
108
- }
109
-
110
- // Check if feature has tasks
111
- if (!feature.tasks || (Array.isArray(feature.tasks) && feature.tasks.length === 0)) {
112
- if (requirements.length > 0) {
113
- warnings++;
114
- results.push({
115
- feature: featureName,
116
- level: 'warning',
117
- message: `Spec has ${requirements.length} requirements but no tasks defined`
118
- });
119
- }
120
- continue;
121
- }
122
-
123
- // Get task titles
124
- const taskTitles = Array.isArray(feature.tasks)
125
- ? feature.tasks.map(t => t.title?.toLowerCase() || '')
126
- : [];
127
-
128
- // Check each requirement has a matching task (fuzzy match)
129
- for (const req of requirements.slice(0, 20)) { // Limit to first 20
130
- const reqLower = req.toLowerCase();
131
- const hasMatch = taskTitles.some(title =>
132
- title.includes(reqLower.slice(0, 20)) ||
133
- reqLower.includes(title.slice(0, 20))
134
- );
135
-
136
- if (!hasMatch && options.verbose) {
137
- console.log(chalk.gray(` ? Requirement may not be covered: "${req.slice(0, 50)}..."`));
138
- }
139
- }
140
-
141
- if (options.verbose) {
142
- console.log(chalk.green(` ✓ ${featureName}: ${requirements.length} requirements, ${taskTitles.length} tasks`));
143
- }
144
- }
145
-
146
- } catch (error) {
147
- if (options.verbose) {
148
- console.log(chalk.yellow(` ⚠ Could not validate: ${error.message}`));
149
- }
150
- }
151
-
152
- return {
153
- status: errors > 0 ? 'error' : warnings > 0 ? 'warning' : 'ok',
154
- errors,
155
- warnings,
156
- results
157
- };
158
- }
159
-
160
52
  /**
161
53
  * Main validation command
162
54
  */
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "morph-spec",
3
- "version": "8.47.0",
3
+ "version": "9.0.0",
4
4
  "displayName": "MORPH-SPEC Framework",
5
5
  "description": "Spec-driven development with 38 agents and 8-phase workflow for .NET/Blazor/Next.js/Azure",
6
6
  "publisher": "polymorphism-tech",
@@ -185,4 +185,4 @@ Never edited directly — go through CLI commands or `morph-spec update` instead
185
185
 
186
186
  ---
187
187
 
188
- *morph-spec v8.47.0 by Polymorphism Tech*
188
+ *morph-spec v9.0.0 by Polymorphism Tech*
@@ -249,4 +249,4 @@ morph-spec doctor
249
249
 
250
250
  ---
251
251
 
252
- *morph-spec v8.47.0 by Polymorphism Tech*
252
+ *morph-spec v9.0.0 by Polymorphism Tech*
@@ -1,114 +1,54 @@
1
1
  # MORPH-SPEC Runtime Instructions
2
2
 
3
- > by Polymorphism Tech — Spec-driven development harness for Claude Code
4
-
5
- ## Como começar cada sessão
6
-
7
- 1. Leia `.morph/framework/MORPH.md` — o charter NLH com papéis, fases, gates e skills.
8
- 2. Leia `.morph/state.json` — índice fino e gitignored (status + updatedAt por feature), reconstruído a cada load. **Não o edite à mão.** Estado autoritativo e commitado de cada feature: `.morph/features/{feature}/feature.json`.
9
- 3. Se existir `.morph/features/{feature}/handoff.md` para a feature ativa, **leia-o antes de re-derivar contexto à mão** — documento de retomada comprimido (regenere com `morph-spec handoff <f>` se parecer velho).
10
- 4. Assuma o papel correspondente (Orchestrator/Specialist/Evaluator) e continue o trabalho. Não aguarde instrução do usuário se há trabalho pendente entre gates.
11
-
12
- Se não houver feature ativa, pergunte ao usuário qual feature trabalhar.
13
-
14
- ## Regras críticas
15
-
16
- **NUNCA:**
17
- - Pular para código sem proposal aprovado (Gate 1) e plano aprovado (Gate 2).
18
- - Modificar o contrato do plano depois do Gate 2 — `spec.md` e os campos `title`/`description`/`dependencies`/`effort`/`doneCriteria`/`group`/`agent`/`standards` de `tasks.json` ficam congelados (`protect-spec-files` bloqueia `Write`/`Edit`); mutáveis: `status`/`outputs`/`notes` (ver SEMPRE). **Fato errado sobre o código não exige revogar gate**: bloco `## Errata` append-only no fim, corpo intacto (MORPH.md §3). **Use cases (`2-plan/usecases/UC-*.md`) NÃO congelam** — editáveis por design.
19
- - Escrever critérios de aceite no `proposal.md` — pertencem aos use cases (pós-condição **observável em teste**, chega **literal** ao `doneCriteria`).
20
- - Editar `.morph/specs/usecases/` à mão — só o `finish` escreve lá. Mudar um UC existente (`bug`): copie para `2-plan/usecases/` da feature e corrija lá.
21
- - Listar perguntas em texto simples — sempre `AskUserQuestion` (1-4 perguntas por chamada).
22
- - Usar `Guid.NewGuid()`, classes não-sealed sem justificativa, exceptions como fluxo de controle, camada de Service/Manager entre handler e dados, repository genérico (`IRepository<T>`/`IUnitOfWork`), ou SQL cru sem justificativa.
23
- - Comentar o que nome, tipo ou teste já dizem: o padrão é nenhum comentário, mesmo ao lado de código comentado; o elo com a pós-condição vai no nome do teste (`architecture-code-comments`, hook `comment-guard`).
24
- - Editar `gateDecisions` ou gates de `feature.json` à mão — sempre via `morph-spec gate-check`/`approve` (timestamps server-side; Edit manual colide com o hook `state-sync`).
25
-
26
- **SEMPRE:**
27
- - Auto-advance entre tarefas durante a fase implement — não pause sem ambiguidade bloqueante.
28
- - Abrir toda feature `feature`/`bug` com a escolha de **modo de descoberta** (entrevista ou automático), depois de varrer o ambiente. **No modo entrevista, uma pergunta por chamada de `AskUserQuestion`** — o "1-4 por chamada" não é licença para agrupar a entrevista. O Gate 1 pausa sempre nesse modo.
29
- - Atualizar `tasks.json` ao concluir cada task gravando só os campos mutáveis `status`/`outputs`/`notes` — via `Write` OU `Edit`.
30
- - Apresentar gates com o template fixo (MORPH.md/morph-plan). **A pergunta PRECISA nomear a feature** ("Gate 2 — Plano de {feature} aprovado?") — é por esse nome que `state-sync` atribui a aprovação ao `feature.json` certo. Sem nome, com mais de uma feature na árvore, ele **recusa gravar** — aprove com `morph-spec approve <feature> <gate>`.
31
- - Registrar decisões não triviais em `decisions.md`.
32
- - Fechar cada task só com `verify {f} {T}` verde e cada `doneCriteria` com a evidência que o prova; vermelho ou critério sem prova dispara o loop de correção autônomo, sem escalar ao humano entre tarefas. No Gate 3, o veredito (`SHIP`/`FIX`) vem do **avaliador independente** despachado pela `morph-review` — nunca de quem implementou.
33
- - Em `hotfix`, o Gate 3 pausa **sempre** para um humano, mesmo em `trust: auto` — `approve ... review --mode auto` é recusado; aprove com `--approver`.
34
- - Confirmar antes de `finish`/`archive`/`delete` se o SessionStart avisar que outra sessão tem claim vivo na mesma feature.
35
- - **Ao retomar o controle depois de um dispatch, o orquestrador lê o arquivo de relatório, não a mensagem final** — a mensagem pode não chegar ou vir resumida. As cláusulas do prompt vivem só nos templates (`morph-implement` §4, `morph-apply` §3b).
3
+ > by Polymorphism Tech — harness spec-driven para Claude Code
4
+
5
+ ## Início de cada sessão
6
+
7
+ 1. Leia `.morph/framework/MORPH.md` uma vez (de novo após `/compact`): papéis, fases, gates, dispatch.
8
+ 2. `.morph/state.json` é índice gitignored, só para achar a feature ativa; o estado autoritativo é `.morph/features/{feature}/feature.json`.
9
+ 3. Existe `.morph/features/{feature}/handoff.md`? Leia antes de re-derivar contexto à mão.
10
+ 4. Feature em andamento → assuma o papel da fase e continue entre gates sem esperar instrução. Nenhuma ativa → pergunte qual trabalhar.
11
+
12
+ ## Regras
13
+
14
+ - Perguntas ao usuário só por `AskUserQuestion` (1-4 por chamada), nunca em texto solto. Na entrevista da `morph-plan`, **uma pergunta por chamada**: lote impede que uma resposta pode os ramos seguintes. Única exceção: ferramenta indisponível ou negada (headless) — texto numerado com a resposta recomendada e gate pausado (`morph-plan` §3).
15
+ - A pergunta de gate nomeia a feature ("Gate do plano — Plano de {feature} aprovado?"): é por esse nome que o hook `state-sync` grava a aprovação no `feature.json` certo; sem nome, com mais de uma feature, ele recusa e você aprova por `morph-spec approve <feature> <gate>`.
16
+ - Estado só pela CLI, nunca à mão: `feature.json`, `gateDecisions`, `checks.json` (escrito só por `plan-check`) e o corpo do `plan.md` depois do gate (fato errado → `## Errata` no fim; escopo mudou → `unapprove`).
17
+ - SessionStart avisou claim vivo de outra sessão na mesma feature → confirme com o usuário antes de `finish`/`archive`/`delete`.
18
+ - Depois de um dispatch, leia o arquivo de relatório da fatia, não a mensagem final, que pode não chegar.
19
+
20
+ ## CLI do loop
21
+
22
+ Prefixo `morph-spec`; flags e porquês em `.morph/framework/CLI.md` (um `###` por comando).
23
+
24
+ | Comando | Para quê |
25
+ |---|---|
26
+ | `create <f> --description "…" --type <t> [--worktree]` | nasce a feature; exit 2 = você escolhe o tipo |
27
+ | `stack-scan [f]` | desvios do código contra `project.stack` |
28
+ | `plan-check <f>` | valida `plan.md`, grava `checks.json`, imprime as ondas |
29
+ | `gate-check <f> <gate>` | decide a pausa pelos sinais do disco |
30
+ | `approve <f> <gate> --mode auto` / `advance <f>` | aprova (advance também abre a próxima fase) |
31
+ | `verify <f> [--ci]` | build + testes + validadores + e2e, sem filtro |
32
+ | `report-check <f> [F1 …]` | audita o relatório de cada fatia e diz a ação |
33
+ | `mutate <f>` | mutação dirigida do Gate 3 (até 3 mutantes) |
34
+ | `finish <f> --pr\|--merge` | encerra; só o `--merge` integra |
35
+ | `standards --find "<tema>"` / `--show <id>#<âncora>` | digest do standard / uma seção |
36
+ | `heavy status\|run -- <cmd>` | fila de build/teste; exit 3 = fila cheia |
37
+ | `worktree setup\|provision\|link\|remove\|list\|reap` | ciclo da worktree; `remove` é a única remoção segura |
38
+ | `graph affected\|explain <sym>` | blast radius; sem grafo, caia para grep |
36
39
 
37
40
  ## Slash commands
38
41
 
39
- | Comando | Propósito |
40
- |---------|-----------|
41
- | `/morph-proposal {feature}` | Entendimento de negócio + plano (Gates 1 e 2). Passo 0 roteia por tipo de trabalho (`feature`/`bug`/`chore`/`hotfix`) |
42
- | `/morph-hotfix {feature}` | ADW cirúrgico de hotfix (scout → fix → gate humano → ship) |
43
- | `/morph-apply {feature}` | Execução autônoma + review (Gate 3) |
44
- | `/morph-status [feature]` | Status da feature ativa (ou a especificada) |
45
- | `/morph-archive {feature}` | Arquiva-**sem-integrar** (legadas/faxina) — wrapper de `archive`. Fechamento normal = `finish --pr\|--merge` |
46
- | `/morph-preflight` | Validação pré-deploy (specs, contratos, testes, infra) |
47
- | `/morph-troubleshoot [erro]` | Diagnóstico de erros .NET/Next.js com root-cause analysis |
48
-
49
- **Comandos CLI de gate e de estado** (a LLM os usa em vez de editar o estado à mão):
50
-
51
- | Comando | Propósito |
52
- |---------|-----------|
53
- | `approve <f> <gate> --mode auto` | Aprova gate em `trust:auto`. Gate 3 exige `evaluator-report.md` (ou `--self-assessed`); `hotfix` nunca aceita `--mode auto` — use `--approver` |
54
- | `advance <f>` | Aprova o gate corrente + já cria a pasta da próxima fase |
55
- | `gate-check <f> <gate> [--json]` | Default: decide via sinais do disco (`shouldPauseGate`) |
56
- | `gate-decision <f> <gate> --pause <bool>` | Escape manual: risco que o disco não vê |
57
- | `create <f> --description "..." --type <t>` | Nasce a feature + `feature.json`; `--worktree` já isola |
58
- | `list [--all] [--json]` | Quadro de auditoria: feature × workType × status × gates |
59
- | `delete <f> [--archive] [--force]` | Remove feature; recusa se gate aprovado sem `--force` |
60
- | `retype <f> <tipo>` | Muda o workType mid-flight; bloqueado após o Gate 3 |
61
- | `finish <f> --pr\|--merge` | Encerramento único: arquiva, promove use cases, desmonta worktree. Integra só no `--merge`; `--pr` abre PR e fica `aguardando-merge` até alguém mergear |
62
- | `archive <f>` | Arquiva sem integrar (legadas/faxina) |
63
- | `worktree setup\|provision\|link\|remove\|list\|reap` | Ciclo do worktree; `provision` = isolamento de task; `remove` é a única remoção segura |
64
- | `branch prune [--dry-run]` | Apaga branch já integrada, inclusive squash-merge; nunca a com PR aberto |
65
- | `handoff <f>` | Regenera o documento de retomada da feature |
66
- | `fleet` | Visão agregada de toda feature ativa (raiz + worktrees) |
67
- | `claim [f] [--release] [--list]` | Posse advisory — confirme antes de `finish`/`archive`/`delete` se outra sessão tiver claim vivo |
68
- | `dag <f>` | DAG de `tasks.json`: sequencial/paralelo, recomenda isolamento |
69
- | `graph status\|build\|refresh` | Grafo de codebase. `status` reporta frescor e se há refresh em background |
70
- | `graph affected\|explain <sym>` | Blast radius e vizinhança saneados. Sem grafo, caia para grep — nunca é erro |
71
- | `verify <f> [task] [--ci]` | Build+testes+validadores+e2e — prova da task; a do Gate 3 com `--ci` (no CI) |
72
- | `e2e up\|status\|down <f>` | Stack de verificação (docker compose) |
73
- | `doctor --worktrees [--prune]` | Reconcilia git × disco × features; só `--prune` remove algo |
74
- | `report-check <f> [task...] [--json]` | Audita relatório de sub-agent vs. trabalho entregue |
75
- | `telemetry [--feature] [--limit]` | Caminho de execução da sessão a partir de `events.jsonl` |
76
- | `cost [f] [--by task\|phase] [--metrics]` | Custo (bytes/duração) e medições do loop (turnos, rerun, releitura) do mesmo log |
77
-
78
- Prefixo de todo comando: `morph-spec`. Flags/exemplos: `.morph/framework/CLI.md`.
79
-
80
- ## Skills core (em `.claude/skills/`)
81
-
82
- | Skill | Quando usar |
83
- |-------|-------------|
84
- | `morph-brainstorming` | Entender negócio, escanear stack, produzir proposal.md |
85
- | `morph-stack-scan` | Desvios de stack em projeto brownfield |
86
- | `morph-uiux` | Ramo opcional de UI/UX — design system e mockups |
87
- | `morph-plan` | Destilar use cases e produzir spec.md + tasks.json |
88
- | `morph-implement` | Executar uma tarefa com auto-advance entre tasks |
89
- | `morph-review` | Produzir review-report.md (Gate 3) |
90
- | `morph-hotfix` | Hotfix cirúrgico (`/morph-hotfix`) |
91
- | `morph-standards` | Localizar standard sob demanda |
92
- | `morph-machine` | RAM/CPU: fila pesada, órfãos, worktrees sobrando |
93
-
94
- ## Roteamento por tipo de trabalho
95
-
96
- `workType` (`create --type <tipo>` ou classificado de `--request`) dimensiona o pipeline: `feature` completo (+ ramo uiux quando há superfície de UI), `bug` enxuto, `chore` fast-track (Gates 1/2 por política), `hotfix` scout→fix→gate humano→ship. Canônico: `MORPH.md` §2.1/§5.
97
-
98
- Features independentes rodam em paralelo, uma por git worktree (`create --worktree`/`worktree setup`), bloco de portas próprio + handoff.md. Fechamento: `finish <f> --pr|--merge`; agregado: `fleet`. Canônico: `MORPH.md` §2.2.
42
+ `/morph-proposal {f}` (plano), `/morph-apply {f}` (execução + Gate 3), `/morph-hotfix {f}`, `/morph-status [f]`.
99
43
 
100
44
  ## Personas (em `.claude/agents/`)
101
45
 
102
- Despache tasks de domínio com `subagent_type: "morph-{id}"` — a persona é o **system prompt** do subagent registrado (gerado de `agents.json`, a fonte única). Tipo não registrado (stack não instalado): fallback `general-purpose` + campo `persona` colado no prompt, **registrando nas `notes` da task** (detalhe: `morph-apply` §3b).
46
+ Despache fatias com `subagent_type: "morph-{id}"` — a persona, gerada de `agents.json`, é o system prompt. Tipo não registrado: `general-purpose` com o `persona` colado, registrado no relatório da fatia. Nunca edite `.claude/agents/morph-*.md` à mão (`morph-spec doctor` acusa o drift).
103
47
 
104
48
  <!-- morph-agents:start -->
105
- _Lista derivada na instalação (`morph-spec setup-infra`). Se este bloco está vazio, rode `morph-spec setup-infra --reinstall`._
49
+ _Lista derivada na instalação. Bloco vazio → `morph-spec setup-infra --reinstall`._
106
50
  <!-- morph-agents:end -->
107
51
 
108
- Drift entre `agents.json` e os `.md` gerados é detectado por `morph-spec doctor` — nunca edite `.claude/agents/morph-*.md` à mão.
109
-
110
- ## Regra de precedência de skills
111
-
112
- Com o plugin superpowers ativo, `morph-*` vence o equivalente genérico (aplica Gates e paths de `.morph/`), e `using-git-worktrees`→`morph-spec worktree setup|provision`.
52
+ ## Precedência de skills
113
53
 
114
- *MORPH-SPEC v5 by Polymorphism Tech*
54
+ Com o plugin superpowers ativo, `morph-*` vence o equivalente genérico (aplica os gates e os paths de `.morph/`), e `using-git-worktrees`→`morph-spec worktree setup|provision`.