@polymorphism-tech/morph-spec 8.46.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 (304) hide show
  1. package/CLAUDE.md +53 -44
  2. package/README.md +3 -4
  3. package/bin/morph-spec.js +38 -55
  4. package/bin/validate.js +5 -134
  5. package/claude-plugin.json +1 -1
  6. package/docs/CHEATSHEET.md +2 -2
  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/create-umbraco-lp.md +2 -0
  12. package/framework/commands/migrate-lp-to-umbraco.md +2 -0
  13. package/framework/commands/morph-apply.md +5 -28
  14. package/framework/commands/morph-archive.md +2 -2
  15. package/framework/commands/morph-hotfix.md +8 -8
  16. package/framework/commands/morph-infra.md +17 -203
  17. package/framework/commands/morph-media.md +3 -0
  18. package/framework/commands/morph-preflight.md +7 -31
  19. package/framework/commands/morph-proposal.md +2 -50
  20. package/framework/commands/morph-status.md +3 -3
  21. package/framework/commands/morph-troubleshoot.md +2 -14
  22. package/framework/docs/CLI.md +585 -286
  23. package/framework/evals/review-checklist.md +82 -41
  24. package/framework/hooks/README.md +10 -11
  25. package/framework/hooks/claude-code/core/comment-guard.js +1 -1
  26. package/framework/hooks/claude-code/core/denylist.json +33 -3
  27. package/framework/hooks/claude-code/core/enforce-phase-writes.js +16 -20
  28. package/framework/hooks/claude-code/core/gate-guard.js +2 -11
  29. package/framework/hooks/claude-code/core/pre-bash-denylist.js +38 -0
  30. package/framework/hooks/claude-code/core/protect-spec-files.js +30 -242
  31. package/framework/hooks/claude-code/core/state-sync.js +17 -19
  32. package/framework/hooks/claude-code/core/telemetry-log.js +3 -3
  33. package/framework/hooks/claude-code/core/validate-completion.js +33 -97
  34. package/framework/hooks/claude-code/core/warn-bash-source-write.js +31 -0
  35. package/framework/hooks/claude-code/core/worktree-context.js +5 -4
  36. package/framework/hooks/claude-code/statusline.py +55 -41
  37. package/framework/hooks/package.json +3 -0
  38. package/framework/hooks/shared/activity-logger.js +1 -1
  39. package/framework/hooks/shared/build-check.js +10 -6
  40. package/framework/hooks/shared/command-tokens.js +169 -0
  41. package/framework/hooks/shared/comment-rules.js +1 -1
  42. package/framework/hooks/shared/comment-scanner.js +10 -23
  43. package/framework/hooks/shared/comment-stripper.js +1 -1
  44. package/framework/hooks/shared/e2e-check.js +67 -31
  45. package/framework/hooks/shared/errata.js +72 -0
  46. package/framework/hooks/shared/feature-locator.js +1 -1
  47. package/framework/hooks/shared/frontend-locations.js +6 -0
  48. package/framework/hooks/shared/gate-question.js +18 -0
  49. package/framework/hooks/shared/phase-utils.js +15 -32
  50. package/framework/hooks/shared/slice-progress.js +118 -0
  51. package/framework/hooks/shared/spawn-command.js +23 -0
  52. package/framework/hooks/shared/state-reader.js +61 -87
  53. package/framework/hooks/shared/state-writer.js +3 -3
  54. package/framework/mcp/registry.json +3 -4
  55. package/framework/phases.json +23 -39
  56. package/framework/rules/ai-agents-standards.md +18 -16
  57. package/framework/rules/asaas-standards.md +3 -1
  58. package/framework/rules/csharp-standards.md +10 -8
  59. package/framework/rules/data-standards.md +5 -5
  60. package/framework/rules/dotnet-templates.md +1 -1
  61. package/framework/rules/frontend-standards.md +4 -2
  62. package/framework/rules/gsap-standards.md +10 -5
  63. package/framework/rules/hangfire-standards.md +3 -1
  64. package/framework/rules/infrastructure-standards.md +4 -2
  65. package/framework/rules/neon-auth-standards.md +3 -1
  66. package/framework/rules/neon-standards.md +6 -4
  67. package/framework/rules/nextjs-standards.md +13 -11
  68. package/framework/rules/nextjs-templates.md +1 -1
  69. package/framework/rules/resend-standards.md +3 -1
  70. package/framework/schemas/config.schema.json +14 -9
  71. package/framework/schemas/feature.schema.json +15 -52
  72. package/framework/skills/README.md +4 -5
  73. package/framework/skills/core/create-umbraco-lp/SKILL.md +3 -3
  74. package/framework/skills/core/migrate-lp-to-umbraco/SKILL.md +3 -3
  75. package/framework/skills/core/morph-apply/SKILL.md +150 -223
  76. package/framework/skills/core/morph-hotfix/SKILL.md +34 -43
  77. package/framework/skills/core/morph-machine/SKILL.md +4 -4
  78. package/framework/skills/core/morph-media/SKILL.md +3 -3
  79. package/framework/skills/core/morph-plan/SKILL.md +138 -300
  80. package/framework/skills/core/morph-review/SKILL.md +112 -137
  81. package/framework/skills/core/morph-standards/SKILL.md +29 -41
  82. package/framework/skills/core/morph-uiux/SKILL.md +78 -153
  83. package/framework/standards/STANDARDS.json +90 -1219
  84. package/framework/standards/STANDARDS.meta.json +1305 -0
  85. package/framework/standards/ai-agents/evals-with-cache.md +2 -3
  86. package/framework/standards/ai-agents/llm-runtime-defaults.md +1 -1
  87. package/framework/standards/ai-agents/modalities-speech-to-text.md +36 -26
  88. package/framework/standards/ai-agents/prompt-sources.md +6 -4
  89. package/framework/standards/ai-agents/providers/model-registry.md +1 -1
  90. package/framework/standards/ai-agents/rag-custom-pgvector.md +67 -39
  91. package/framework/standards/ai-agents/setup.md +2 -2
  92. package/framework/standards/ai-agents/structured-output.md +1 -1
  93. package/framework/standards/ai-agents/sweet-spot.md +1 -1
  94. package/framework/standards/architecture/code-comments.md +8 -8
  95. package/framework/standards/architecture/vertical-slice/vertical-slice.md +18 -9
  96. package/framework/standards/backend/api/validation.md +135 -47
  97. package/framework/standards/backend/database/postgresql/database.md +11 -7
  98. package/framework/standards/backend/database/vector-search-rag.md +207 -324
  99. package/framework/standards/backend/dotnet/fluent-validation-vsa.md +14 -8
  100. package/framework/standards/backend/dotnet/result-pattern.md +40 -6
  101. package/framework/standards/backend/dotnet/scalar-ui.md +13 -7
  102. package/framework/standards/backend/dotnet/scrutor.md +1 -1
  103. package/framework/standards/backend/dotnet/testing.md +1 -1
  104. package/framework/standards/backend/dotnet/vsa-handler-patterns.md +7 -7
  105. package/framework/standards/backend/integrations/asaas/asaas-api.md +309 -165
  106. package/framework/standards/backend/integrations/hangfire/hangfire-jobs.md +134 -154
  107. package/framework/standards/data/nosql/cache/redis.md +120 -44
  108. package/framework/standards/data/nosql/cosmos-db.md +114 -71
  109. package/framework/standards/frontend/design-system/animations.md +1 -1
  110. package/framework/standards/frontend/design-system/naming.md +1 -1
  111. package/framework/standards/frontend/nextjs/motion-patterns.md +45 -29
  112. package/framework/standards/frontend/nextjs/naming-conventions.md +1 -1
  113. package/framework/standards/infrastructure/docker/coolify-deploy.md +8 -6
  114. package/framework/standards/infrastructure/neon/neon-pgvector.md +120 -75
  115. package/framework/standards/infrastructure/neon/neon-setup.md +53 -31
  116. package/framework/standards/integration/mcp/mcp-tools.md +7 -7
  117. package/framework/templates/README.md +2 -3
  118. package/framework/templates/REGISTRY.json +6 -170
  119. package/framework/templates/code/dotnet/contracts/contracts-vsa.cs +2 -2
  120. package/framework/templates/code/dotnet/extensions/database-extensions.cs +1 -1
  121. package/framework/templates/code/dotnet/extensions/result-extensions.cs +27 -0
  122. package/framework/templates/code/dotnet/feature/endpoint.cs.hbs +2 -2
  123. package/framework/templates/docs/plan.md +72 -0
  124. package/framework/templates/dotnet/ai-kit/README.md +1 -9
  125. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaDisclosureTests.cs +1 -1
  126. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Morph.AiKit.Tests.csproj +0 -10
  127. package/framework/templates/infrastructure/docker/coolify.template.json +3 -3
  128. package/framework/templates/infrastructure/github/README.md +2 -1
  129. package/framework/templates/infrastructure/github/workflows/deploy-coolify.yml.hbs +2 -1
  130. package/framework/templates/meta-prompts/squad-leaders/backend-squad.md +1 -1
  131. package/framework/templates/meta-prompts/squad-leaders/frontend-squad.md +1 -1
  132. package/framework/templates/meta-prompts/squad-leaders/squad-leader.md +1 -1
  133. package/framework/templates/meta-prompts/validators/pre-commit-validator.md +3 -4
  134. package/package.json +1 -1
  135. package/src/commands/e2e/e2e.js +2 -2
  136. package/src/commands/observability/cost.js +18 -60
  137. package/src/commands/observability/telemetry.js +3 -5
  138. package/src/commands/project/doctor-procs.js +1 -1
  139. package/src/commands/project/doctor.js +9 -9
  140. package/src/commands/project/fleet.js +4 -4
  141. package/src/commands/project/heavy.js +3 -3
  142. package/src/commands/project/init.js +6 -1
  143. package/src/commands/project/setup-infra-cmd.js +2 -1
  144. package/src/commands/project/stack-scan.js +58 -0
  145. package/src/commands/project/standards.js +79 -25
  146. package/src/commands/project/status.js +29 -69
  147. package/src/commands/project/update.js +33 -19
  148. package/src/commands/project/worktree.js +1 -1
  149. package/src/commands/state/advance.js +62 -46
  150. package/src/commands/state/approve.js +95 -138
  151. package/src/commands/state/archive.js +20 -84
  152. package/src/commands/state/auto-approval.js +68 -0
  153. package/src/commands/state/create.js +28 -1
  154. package/src/commands/state/delete.js +1 -1
  155. package/src/commands/state/finish.js +11 -23
  156. package/src/commands/state/gate-check.js +86 -95
  157. package/src/commands/state/gate-decision.js +6 -4
  158. package/src/commands/state/handoff.js +1 -1
  159. package/src/commands/state/list.js +9 -9
  160. package/src/commands/state/report-check.js +157 -311
  161. package/src/commands/state/retype.js +9 -3
  162. package/src/commands/validation/mutate.js +77 -14
  163. package/src/commands/validation/plan-check.js +81 -0
  164. package/src/commands/validation/validate-feature.js +60 -135
  165. package/src/commands/validation/verify.js +41 -82
  166. package/src/core/paths/output-schema.js +20 -67
  167. package/src/core/state/gate-order.js +5 -6
  168. package/src/core/state/lifecycle-audit.js +2 -2
  169. package/src/core/state/state-manager.js +17 -98
  170. package/src/core/templates/template-registry.js +2 -2
  171. package/src/core/templates/template-seed.js +22 -0
  172. package/src/core/work-types.js +10 -10
  173. package/src/dashboard/app/App.jsx +0 -2
  174. package/src/dashboard/app/components/ActivityFeed.jsx +2 -3
  175. package/src/dashboard/app/components/CommandPalette.jsx +7 -8
  176. package/src/dashboard/app/components/EntityLink.jsx +1 -2
  177. package/src/dashboard/app/components/Markdown.jsx +1 -1
  178. package/src/dashboard/app/components/Sidebar.jsx +1 -2
  179. package/src/dashboard/app/hooks/useMorphQuery.js +1 -1
  180. package/src/dashboard/app/lib/phases.js +2 -4
  181. package/src/dashboard/app/pages/Activity.jsx +1 -1
  182. package/src/dashboard/app/pages/FeatureDetail.jsx +139 -129
  183. package/src/dashboard/app/pages/Features.jsx +9 -9
  184. package/src/dashboard/app/pages/Guide.jsx +2 -2
  185. package/src/dashboard/app/pages/PhasePipeline.jsx +3 -4
  186. package/src/dashboard/app/pages/RulesMap.jsx +3 -3
  187. package/src/dashboard/app/pages/SkillsLibrary.jsx +3 -3
  188. package/src/dashboard/app/pages/Standards.jsx +1 -1
  189. package/src/dashboard/scanner/activity-scanner.js +6 -16
  190. package/src/dashboard/scanner/agents-scanner.js +1 -1
  191. package/src/dashboard/scanner/docs-scanner.js +5 -23
  192. package/src/dashboard/scanner/features-scanner.js +95 -60
  193. package/src/dashboard/scanner/index.js +0 -2
  194. package/src/dashboard/scanner/project-api.js +1 -1
  195. package/src/dashboard/scanner/rules-scanner.js +15 -10
  196. package/src/dashboard/scanner/skills-scanner.js +2 -3
  197. package/src/dashboard/scanner/standards-scanner.js +2 -1
  198. package/src/lib/ci/ci-verify.js +17 -1
  199. package/src/lib/ci/github-ci.js +1 -1
  200. package/src/lib/detectors/index.js +3 -8
  201. package/src/lib/generators/handoff-generator.js +34 -65
  202. package/src/lib/generators/settings-generator.js +11 -89
  203. package/src/lib/git/evidence-staleness.js +1 -1
  204. package/src/lib/git/tree-fingerprint.js +19 -7
  205. package/src/lib/git/tree-state.js +2 -2
  206. package/src/lib/heavy/cleanup.js +1 -5
  207. package/src/lib/installers/memory-installer.js +6 -8
  208. package/src/lib/mutation/commands.js +3 -2
  209. package/src/lib/{tasks/dotnet-test-introspection.js → mutation/dotnet-introspection.js} +17 -282
  210. package/src/lib/mutation/plan.js +14 -6
  211. package/src/lib/mutation/runner.js +1 -1
  212. package/src/lib/mutation/subset.js +46 -9
  213. package/src/lib/plan/artifact-vocabulary.js +60 -0
  214. package/src/lib/plan/checks.js +234 -0
  215. package/src/lib/plan/plan-parser.js +209 -0
  216. package/src/lib/plan/plan-template.js +18 -0
  217. package/src/lib/review-reports.js +222 -0
  218. package/src/lib/risk-detector.js +134 -135
  219. package/src/lib/specs/adr-index.js +50 -69
  220. package/src/lib/specs/design-seed.js +18 -0
  221. package/src/lib/specs/frontmatter.js +44 -0
  222. package/src/lib/specs/gfm-table.js +17 -0
  223. package/src/lib/specs/old-format.js +68 -0
  224. package/src/lib/specs/revocations.js +37 -95
  225. package/src/lib/specs/screen-checklist.js +18 -17
  226. package/src/lib/stack/dotnet-build-ignores.js +47 -0
  227. package/src/lib/stack/stack-profile.js +1 -1
  228. package/src/lib/stack/stack-scan.js +267 -0
  229. package/src/lib/standards/registry.js +43 -0
  230. package/src/lib/standards/sections.js +58 -0
  231. package/src/lib/tasks/eval-node.js +4 -12
  232. package/src/lib/tasks/test-nodes.js +1 -74
  233. package/src/lib/tasks/test-runner.js +75 -117
  234. package/src/lib/telemetry/metrics.js +8 -69
  235. package/src/lib/telemetry/telemetry-reader.js +5 -118
  236. package/src/lib/telemetry/verify-event.js +5 -7
  237. package/src/lib/validators/code-budget/code-budget-validator.js +1 -1
  238. package/src/lib/validators/contracts/contract-compliance-validator.js +2 -2
  239. package/src/lib/validators/reuse/reuse-validator.js +24 -48
  240. package/src/lib/validators/reuse/symbol-scanner.js +2 -4
  241. package/src/lib/validators/traceability-check.js +85 -129
  242. package/src/lib/validators/validation-runner.js +8 -88
  243. package/src/lib/validators/verify-runner.js +134 -301
  244. package/src/lib/worktree/docker-audit.js +1 -2
  245. package/src/lib/worktree/fleet-scanner.js +25 -38
  246. package/src/scripts/setup-infra.js +42 -22
  247. package/src/utils/agents-installer.js +92 -13
  248. package/src/utils/claude-settings-manager.js +0 -35
  249. package/src/utils/file-copier.js +34 -6
  250. package/src/utils/hooks-installer.js +16 -9
  251. package/src/utils/skills-installer.js +1 -2
  252. package/framework/commands/commit.md +0 -166
  253. package/framework/evals/trace-schema.md +0 -67
  254. package/framework/hooks/claude-code/core/tasks-json-guard.js +0 -83
  255. package/framework/hooks/claude-code/core/trace-autogen.js +0 -277
  256. package/framework/hooks/git/pre-commit/specs.sh +0 -50
  257. package/framework/hooks/shared/tasks-validator.js +0 -111
  258. package/framework/rubrics/backend.json +0 -41
  259. package/framework/rubrics/default.json +0 -36
  260. package/framework/rubrics/frontend.json +0 -36
  261. package/framework/rules/morph-task-tracking.md +0 -54
  262. package/framework/rules/morph-workflow.md +0 -244
  263. package/framework/schemas/tasks.schema.json +0 -79
  264. package/framework/skills/core/morph-brainstorming/SKILL.md +0 -161
  265. package/framework/skills/core/morph-implement/SKILL.md +0 -194
  266. package/framework/skills/core/morph-proposal/SKILL.md +0 -152
  267. package/framework/skills/core/morph-stack-scan/SKILL.md +0 -145
  268. package/framework/templates/docs/proposal.md +0 -192
  269. package/framework/templates/docs/spec.md +0 -57
  270. package/framework/templates/docs/ui-components.md +0 -52
  271. package/framework/templates/docs/ui-design-system.md +0 -76
  272. package/framework/templates/docs/ui-flows.md +0 -167
  273. package/framework/templates/examples/spec-examples.md +0 -91
  274. package/framework/templates/feature/decisions.md +0 -124
  275. package/framework/templates/feature/recap.md +0 -145
  276. package/framework/templates/project/validate.js +0 -97
  277. package/framework/templates/tasks.template.json +0 -17
  278. package/src/commands/state/usecase.js +0 -143
  279. package/src/commands/tasks/dag.js +0 -181
  280. package/src/dashboard/app/pages/Rubrics.jsx +0 -97
  281. package/src/dashboard/scanner/rubrics-scanner.js +0 -12
  282. package/src/lib/agents/output-collector.js +0 -76
  283. package/src/lib/evaluator-report.js +0 -91
  284. package/src/lib/specs/acervo-format.js +0 -70
  285. package/src/lib/specs/acervo-lifecycle.js +0 -264
  286. package/src/lib/specs/done-criteria-check.js +0 -200
  287. package/src/lib/specs/usecase-check.js +0 -301
  288. package/src/lib/specs/usecase-promoter.js +0 -301
  289. package/src/lib/specs/usecase-registry.js +0 -237
  290. package/src/lib/tasks/dispatch-planner.js +0 -319
  291. package/src/lib/tasks/mermaid-renderer.js +0 -132
  292. package/src/lib/tasks/task-classifier.js +0 -30
  293. package/src/lib/tasks/task-parser.js +0 -209
  294. package/src/lib/tasks/tasks-json-parser.js +0 -296
  295. package/src/lib/tasks/test-scope.js +0 -597
  296. package/src/lib/validators/architecture/architecture-validator.js +0 -270
  297. package/src/lib/validators/architecture/index.js +0 -7
  298. package/src/lib/validators/css/css-validator.js +0 -340
  299. package/src/lib/validators/css/index.js +0 -7
  300. package/src/lib/validators/design-system/design-system-validator.js +0 -237
  301. package/src/lib/validators/design-system/index.js +0 -7
  302. package/src/lib/validators/score-aggregator.js +0 -244
  303. package/src/lib/validators/ui/index.js +0 -7
  304. package/src/lib/validators/ui/ui-contrast-validator.js +0 -422
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')
@@ -366,17 +338,15 @@ graphCommand
366
338
  // ─── Validation ───────────────────────────────────────────────────────────
367
339
  program
368
340
  .command('validate [validator]')
369
- .description('Run project validations (all | packages | architecture | contrast)')
341
+ .description('Run project validations (all | packages | next-components | spec-tasks)')
370
342
  .option('-v, --verbose', 'Show detailed output')
371
343
  .option('--auto-fix, --fix', 'Auto-fix issues where possible')
372
344
  .option('--no-fail', 'Don\'t exit with error code')
373
- .option('--wcag-aaa', 'Use WCAG AAA standard (stricter)')
374
345
  .action((validator, options) => {
375
346
  const args = validator ? [validator] : ['all'];
376
347
  if (options.verbose) args.push('--verbose');
377
348
  if (options.autoFix) args.push('--auto-fix');
378
349
  if (options.noFail) args.push('--no-fail');
379
- if (options.wcagAaa) args.push('--wcag-aaa');
380
350
  validateCommand(args);
381
351
  });
382
352
 
@@ -390,25 +360,23 @@ program
390
360
  .action(validateFeatureCommand);
391
361
 
392
362
  program
393
- .command('verify <feature> [task]')
363
+ .command('verify <feature>')
394
364
  .description('Run the deterministic verification chain (build + tests + validators + e2e) — code before the LLM judge')
395
365
  .option('--json', 'Output as JSON')
396
- .option('--rubric <id>', 'Force a rubric (default: by task group → config → default)')
397
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))
398
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)')
399
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')
400
369
  .option('--linux-image <img>', 'Image used by --linux (default: mcr.microsoft.com/dotnet/sdk:10.0)')
401
- .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')
402
- .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)')
403
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')
404
- .option('--skip-tests', 'Skip the test node. At feature scope the run is partial, so the verification stamp is NOT written (reason "skip-tests")')
405
- .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")')
406
374
  .option('--skip-e2e', 'Skip the e2e node (Docker bring-up + Playwright)')
407
375
  .option('--fresh-e2e', 'Recreate the e2e stack from scratch: down -v (named volumes included), drop the freshness stamp, rebuild, re-seed auth')
408
376
  .option('--no-persist', 'Do not persist the result to feature.json')
409
- .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')
410
- .action((feature, task, options) =>
411
- 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 })
412
380
  );
413
381
 
414
382
  program
@@ -619,8 +587,9 @@ program
619
587
  // ─── Standards search (server-side, R2 token cut) ─────────────────────────
620
588
  program
621
589
  .command('standards')
622
- .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')
623
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')
624
593
  .option('--category <category>', 'Restrict --find to a single category')
625
594
  .option('--tags <tags>', 'Restrict --find to standards carrying any of these comma-separated tags')
626
595
  .option('--json', 'Output as JSON')
@@ -628,11 +597,11 @@ program
628
597
 
629
598
  // ─── Sub-agent report protocol ────────────────────────────────────────────
630
599
  program
631
- .command('report-check <feature> [tasks...]')
632
- .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')
633
- .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')
634
603
  .option('--json', 'Output as JSON')
635
- .action((feature, tasks, options) => reportCheckCommand(feature, tasks.length > 1 ? tasks : tasks[0], options));
604
+ .action((feature, slices, options) => reportCheckCommand(feature, slices, options));
636
605
 
637
606
  program
638
607
  .command('scout-check <map>')
@@ -641,6 +610,20 @@ program
641
610
  .option('--json', 'Output as JSON')
642
611
  .action((map, options) => scoutCheckCommand(map, options));
643
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
+
644
627
  // ─── Dashboard ────────────────────────────────────────────────────────────
645
628
  program
646
629
  .command('dashboard')
@@ -660,10 +643,10 @@ program
660
643
 
661
644
  program
662
645
  .command('cost [feature]')
663
- .description('Cost-facing view over .morph/logs/events.jsonl: task duration, bytes re-ingested by kind (proxy, not tokens), dispatch counts')
664
- .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)')
665
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')
666
- .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')
667
650
  .option('--top <n>', 'With --metrics: how many reread files to list (default 10)', (v) => Number.parseInt(v, 10))
668
651
  .option('--json', 'Output the aggregate as JSON')
669
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/Blazor stacks: packages, architecture, contrast, 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, architecture, contrast, 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
 
@@ -35,24 +29,12 @@ async function buildValidators(stack) {
35
29
 
36
30
  if (isDotnet) {
37
31
  const { validatePackages } = await import('../src/lib/validators/packages/package-validator.js');
38
- const { validateArchitecture } = await import('../src/lib/validators/architecture/architecture-validator.js');
39
- const { validateContrast } = await import('../src/lib/validators/ui/ui-contrast-validator.js');
40
32
 
41
33
  validators.packages = {
42
34
  name: 'Package Compatibility',
43
35
  description: 'Validates NuGet package versions against .NET compatibility matrix',
44
36
  run: validatePackages
45
37
  };
46
- validators.architecture = {
47
- name: 'Architecture Patterns',
48
- description: 'Detects DI anti-patterns, middleware issues, and configuration problems in .NET',
49
- run: validateArchitecture
50
- };
51
- validators.contrast = {
52
- name: 'UI Contrast (WCAG)',
53
- description: 'Validates color contrast ratios for accessibility',
54
- run: validateContrast
55
- };
56
38
  }
57
39
 
58
40
  if (isNextjs) {
@@ -64,111 +46,9 @@ async function buildValidators(stack) {
64
46
  };
65
47
  }
66
48
 
67
- validators['spec-tasks'] = {
68
- name: 'Spec vs Tasks Coverage',
69
- description: 'Validates that tasks.json covers all requirements from spec.md',
70
- run: validateSpecVsTasks
71
- };
72
-
73
49
  return validators;
74
50
  }
75
51
 
76
- /**
77
- * Validate spec.md requirements are covered by tasks
78
- */
79
- async function validateSpecVsTasks(projectPath, options = {}) {
80
- const path = await import('path');
81
- const fs = await import('fs');
82
- const { loadState } = await import('../src/core/state/state-manager.js');
83
-
84
- const results = [];
85
- let errors = 0;
86
- let warnings = 0;
87
-
88
- try {
89
- const state = loadState(false);
90
- if (!state || !state.features) {
91
- return { status: 'ok', errors: 0, warnings: 0, message: 'No features to validate' };
92
- }
93
-
94
- for (const [featureName, feature] of Object.entries(state.features)) {
95
- const outputsPath = path.join(projectPath, '.morph/features', featureName);
96
- const specPath = path.join(outputsPath, 'spec.md');
97
-
98
- if (!fs.existsSync(specPath)) {
99
- continue; // No spec to validate
100
- }
101
-
102
- // Read spec.md and extract requirements
103
- const specContent = fs.readFileSync(specPath, 'utf-8');
104
-
105
- // Extract requirement patterns (## Requisitos, - [ ], numbered lists, etc.)
106
- const requirementPatterns = [
107
- /^#+\s*Requisitos?\s*$/gim,
108
- /^-\s*\[.\]\s*(.+)$/gm,
109
- /^\d+\.\s+(.+)$/gm
110
- ];
111
-
112
- const requirements = [];
113
- for (const pattern of requirementPatterns) {
114
- const matches = specContent.matchAll(pattern);
115
- for (const match of matches) {
116
- if (match[1]) {
117
- requirements.push(match[1].trim());
118
- }
119
- }
120
- }
121
-
122
- // Check if feature has tasks
123
- if (!feature.tasks || (Array.isArray(feature.tasks) && feature.tasks.length === 0)) {
124
- if (requirements.length > 0) {
125
- warnings++;
126
- results.push({
127
- feature: featureName,
128
- level: 'warning',
129
- message: `Spec has ${requirements.length} requirements but no tasks defined`
130
- });
131
- }
132
- continue;
133
- }
134
-
135
- // Get task titles
136
- const taskTitles = Array.isArray(feature.tasks)
137
- ? feature.tasks.map(t => t.title?.toLowerCase() || '')
138
- : [];
139
-
140
- // Check each requirement has a matching task (fuzzy match)
141
- for (const req of requirements.slice(0, 20)) { // Limit to first 20
142
- const reqLower = req.toLowerCase();
143
- const hasMatch = taskTitles.some(title =>
144
- title.includes(reqLower.slice(0, 20)) ||
145
- reqLower.includes(title.slice(0, 20))
146
- );
147
-
148
- if (!hasMatch && options.verbose) {
149
- console.log(chalk.gray(` ? Requirement may not be covered: "${req.slice(0, 50)}..."`));
150
- }
151
- }
152
-
153
- if (options.verbose) {
154
- console.log(chalk.green(` ✓ ${featureName}: ${requirements.length} requirements, ${taskTitles.length} tasks`));
155
- }
156
- }
157
-
158
- } catch (error) {
159
- if (options.verbose) {
160
- console.log(chalk.yellow(` ⚠ Could not validate: ${error.message}`));
161
- }
162
- }
163
-
164
- return {
165
- status: errors > 0 ? 'error' : warnings > 0 ? 'warning' : 'ok',
166
- errors,
167
- warnings,
168
- results
169
- };
170
- }
171
-
172
52
  /**
173
53
  * Main validation command
174
54
  */
@@ -273,8 +153,7 @@ async function runValidator(VALIDATORS, name, options) {
273
153
  try {
274
154
  const result = await validator.run('.', {
275
155
  verbose: true, // Always verbose for single validator
276
- autoFix: options.autoFix,
277
- wcagLevel: options.wcagLevel
156
+ autoFix: options.autoFix
278
157
  });
279
158
 
280
159
  if (result.status === 'ok') {
@@ -302,8 +181,7 @@ function parseOptions(args) {
302
181
  const options = {
303
182
  verbose: false,
304
183
  autoFix: false,
305
- noFail: false,
306
- wcagLevel: 'AA'
184
+ noFail: false
307
185
  };
308
186
 
309
187
  for (const arg of args) {
@@ -313,8 +191,6 @@ function parseOptions(args) {
313
191
  options.autoFix = true;
314
192
  } else if (arg === '--no-fail') {
315
193
  options.noFail = true;
316
- } else if (arg === '--wcag-aaa') {
317
- options.wcagLevel = 'AAA';
318
194
  }
319
195
  }
320
196
 
@@ -334,20 +210,15 @@ ${chalk.bold('USAGE')}
334
210
  ${chalk.bold('VALIDATORS')}
335
211
  all Run all validators (default)
336
212
  packages Validate NuGet package compatibility (.NET 10)
337
- architecture Validate architecture patterns (DI, lifecycle)
338
- contrast Validate UI contrast ratios (WCAG 2.1)
339
213
 
340
214
  ${chalk.bold('OPTIONS')}
341
215
  --verbose, -v Show detailed output
342
216
  --auto-fix, --fix Auto-fix issues where possible
343
217
  --no-fail Don't exit with error code
344
- --wcag-aaa Use WCAG AAA standard (stricter)
345
218
 
346
219
  ${chalk.bold('EXAMPLES')}
347
220
  morph-spec validate # Run all validators
348
221
  morph-spec validate packages --fix # Validate packages and auto-fix
349
- morph-spec validate architecture -v # Verbose architecture validation
350
- morph-spec validate contrast --wcag-aaa # Stricter contrast validation
351
222
  morph-spec validate all # Run all validators
352
223
 
353
224
  ${chalk.bold('EXIT CODES')}
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "morph-spec",
3
- "version": "8.46.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",
@@ -94,7 +94,7 @@ Never hand-edit `gateDecisions`/`approvalGates` in `feature.json` — always go
94
94
  ## CLI — validation
95
95
 
96
96
  ```bash
97
- morph-spec validate [architecture|packages|contrast] [--wcag-aaa]
97
+ morph-spec validate [packages|next-components|spec-tasks]
98
98
  morph-spec validate-feature {feature} [--phase {phase}] [--json] # alias: vf
99
99
  morph-spec verify {feature} [task] [--json] [--skip-tests] [--skip-build] # deterministic build+test+validator chain, before the LLM judge
100
100
  ```
@@ -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.46.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.46.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
- - **Contrato do relatório final** em todo dispatch de sub-agent: (1) grava o relatório em arquivo canônico ANTES de encerrar — `.morph/features/{f}/3-implement/reports/{taskId}.md` (avaliador: `4-review/evaluator-report.md`) — com o quê / **Arquivos:** / **Critérios:** (cada doneCriteria com evidência) / problemas; é o retorno autoritativo, nunca chamar `SendMessage`; (2) não tocar `tasks.json`/`feature.json`/`state.json` nem o board de sessão; (3) testes pelo orçamento, só o próprio filtro uma vez, sem red→green (a prova é o `verify` do orquestrador); (8) nunca mutar produção. Racional completo: `MORPH.md` §6. Templates: `morph-implement` §4, `morph-apply` §3b. **O orquestrador lê o arquivo ao retomar controle** — nunca confia só na mensagem de retorno da tool.
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`.