@polymorphism-tech/morph-spec 8.43.0 → 8.45.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 (203) hide show
  1. package/CLAUDE.md +16 -13
  2. package/README.md +10 -10
  3. package/bin/morph-spec.js +10 -13
  4. package/bin/validate.js +379 -379
  5. package/claude-plugin.json +1 -1
  6. package/docs/CHEATSHEET.md +2 -4
  7. package/docs/QUICKSTART.md +6 -6
  8. package/framework/CLAUDE.md +6 -8
  9. package/framework/MORPH.md +39 -45
  10. package/framework/agents.json +8 -9
  11. package/framework/commands/morph-apply.md +1 -3
  12. package/framework/commands/morph-hotfix.md +1 -1
  13. package/framework/commands/morph-proposal.md +2 -2
  14. package/framework/docs/CLI.md +22 -17
  15. package/framework/evals/review-checklist.md +90 -0
  16. package/framework/evals/trace-schema.md +2 -12
  17. package/framework/hooks/README.md +2 -3
  18. package/framework/hooks/claude-code/core/heavy-gate.js +1 -1
  19. package/framework/hooks/claude-code/core/protect-spec-files.js +2 -2
  20. package/framework/hooks/claude-code/core/telemetry-log.js +2 -2
  21. package/framework/hooks/claude-code/core/trace-autogen.js +1 -22
  22. package/framework/hooks/claude-code/core/validate-completion.js +3 -56
  23. package/framework/hooks/claude-code/core/worktree-env-inject.js +1 -4
  24. package/framework/hooks/claude-code/statusline.sh +11 -11
  25. package/framework/hooks/git/commit-msg/conventional-commits.sh +33 -33
  26. package/framework/hooks/git/pre-commit/agents.sh +25 -25
  27. package/framework/hooks/git/pre-commit/orchestrator.sh +64 -64
  28. package/framework/hooks/git/pre-commit/specs.sh +50 -50
  29. package/framework/hooks/git/pre-push/run-tests.sh +44 -44
  30. package/framework/hooks/shared/build-check.js +1 -1
  31. package/framework/hooks/shared/comment-scanner.js +1 -1
  32. package/framework/hooks/shared/phase-utils.js +0 -5
  33. package/framework/hooks/shared/stdin-reader.js +26 -26
  34. package/framework/phases.json +4 -6
  35. package/framework/rubrics/backend.json +1 -1
  36. package/framework/rubrics/default.json +1 -1
  37. package/framework/rubrics/frontend.json +1 -1
  38. package/framework/rules/ai-agents-standards.md +1 -0
  39. package/framework/rules/morph-workflow.md +6 -6
  40. package/framework/schemas/feature.schema.json +2 -28
  41. package/framework/schemas/tasks.schema.json +6 -2
  42. package/framework/skills/README.md +1 -2
  43. package/framework/skills/core/create-umbraco-lp/SKILL.md +1 -1
  44. package/framework/skills/core/migrate-lp-to-umbraco/SKILL.md +1 -1
  45. package/framework/skills/core/morph-apply/SKILL.md +145 -246
  46. package/framework/skills/core/morph-brainstorming/SKILL.md +1 -1
  47. package/framework/skills/core/morph-hotfix/SKILL.md +5 -3
  48. package/framework/skills/core/morph-implement/SKILL.md +101 -201
  49. package/framework/skills/core/morph-machine/SKILL.md +3 -3
  50. package/framework/skills/core/morph-media/SKILL.md +1 -1
  51. package/framework/skills/core/morph-plan/SKILL.md +171 -287
  52. package/framework/skills/core/morph-proposal/SKILL.md +4 -5
  53. package/framework/skills/core/morph-review/SKILL.md +109 -430
  54. package/framework/skills/core/morph-stack-scan/SKILL.md +1 -1
  55. package/framework/skills/core/morph-standards/SKILL.md +2 -2
  56. package/framework/skills/core/morph-uiux/SKILL.md +2 -3
  57. package/framework/standards/STANDARDS.json +54 -10
  58. package/framework/standards/ai-agents/agent-archetypes.md +1 -1
  59. package/framework/standards/ai-agents/agent-session.md +1 -1
  60. package/framework/standards/ai-agents/agent-spec.md +1 -1
  61. package/framework/standards/ai-agents/batching.md +1 -1
  62. package/framework/standards/ai-agents/context-providers.md +1 -1
  63. package/framework/standards/ai-agents/conversational-agent-with-phases.md +1 -1
  64. package/framework/standards/ai-agents/cost-and-budget.md +1 -1
  65. package/framework/standards/ai-agents/durable-workflows-hitl.md +1 -1
  66. package/framework/standards/ai-agents/guardrails.md +1 -1
  67. package/framework/standards/ai-agents/llm-runtime-defaults.md +1 -1
  68. package/framework/standards/ai-agents/mcp-server.md +1 -1
  69. package/framework/standards/ai-agents/mcp-tools.md +1 -1
  70. package/framework/standards/ai-agents/media-pipeline.md +1 -1
  71. package/framework/standards/ai-agents/media-video.md +1 -1
  72. package/framework/standards/ai-agents/middleware-patterns.md +1 -1
  73. package/framework/standards/ai-agents/modalities-image-gen.md +1 -1
  74. package/framework/standards/ai-agents/modalities-speech-to-text.md +1 -1
  75. package/framework/standards/ai-agents/modalities-text-to-speech.md +1 -1
  76. package/framework/standards/ai-agents/modalities-vision.md +1 -1
  77. package/framework/standards/ai-agents/multi-agent-patterns.md +1 -1
  78. package/framework/standards/ai-agents/observability-patterns.md +3 -3
  79. package/framework/standards/ai-agents/production.md +2 -2
  80. package/framework/standards/ai-agents/prompt-sources.md +1 -1
  81. package/framework/standards/ai-agents/providers/model-registry.md +1 -1
  82. package/framework/standards/ai-agents/rag-custom-pgvector.md +1 -1
  83. package/framework/standards/ai-agents/service-tier-flex.md +1 -1
  84. package/framework/standards/ai-agents/setup.md +1 -1
  85. package/framework/standards/ai-agents/structured-output.md +1 -1
  86. package/framework/standards/ai-agents/sweet-spot.md +1 -1
  87. package/framework/standards/ai-agents/testing-ai.md +1 -1
  88. package/framework/standards/ai-agents/tool-adapters.md +226 -0
  89. package/framework/standards/ai-agents/vector-data-extensions.md +1 -1
  90. package/framework/standards/ai-agents/workflows.md +1 -1
  91. package/framework/standards/infrastructure/docker/local-compose-isolation.md +11 -1
  92. package/framework/templates/CLAUDE.md.core.template +1 -1
  93. package/framework/templates/IDE-SNIPPETS.md +262 -262
  94. package/framework/templates/README.md +1 -1
  95. package/framework/templates/REGISTRY.json +0 -81
  96. package/framework/templates/code/dotnet/abstractions/api-endpoint.cs +7 -7
  97. package/framework/templates/code/dotnet/feature/endpoint.cs.hbs +21 -21
  98. package/framework/templates/code/dotnet/feature/request.cs.hbs +4 -4
  99. package/framework/templates/code/dotnet/feature/response.cs.hbs +4 -4
  100. package/framework/templates/code/sql/ai-agents/pgvector-embeddings-migration.sql.template +91 -91
  101. package/framework/templates/docs/spec.md +19 -205
  102. package/framework/templates/docs/ui-components.md +52 -52
  103. package/framework/templates/docs/ui-design-system.md +76 -76
  104. package/framework/templates/docs/ui-flows.md +167 -167
  105. package/framework/templates/frontend/nextjs/client-component.tsx.hbs +26 -26
  106. package/framework/templates/frontend/nextjs/feature-form.tsx.hbs +56 -56
  107. package/framework/templates/frontend/nextjs/tsconfig.json.hbs +26 -26
  108. package/framework/templates/infrastructure/docker/Dockerfile.template +58 -58
  109. package/framework/templates/infrastructure/docker/dockerfile-api.dockerfile +38 -38
  110. package/framework/templates/infrastructure/docker/dockerfile-web.dockerfile +48 -48
  111. package/framework/templates/infrastructure/github/README.md +56 -56
  112. package/framework/templates/infrastructure/github/actions/docker-build-push/action.yml.hbs +45 -45
  113. package/framework/templates/infrastructure/github/actions/health-check/action.yml.hbs +27 -27
  114. package/framework/templates/infrastructure/github/workflows/docker-build-push.yml.hbs +59 -59
  115. package/framework/templates/infrastructure/github/workflows/dotnet-build.yml.hbs +39 -39
  116. package/framework/templates/meta-prompts/fusion/fusion-agent.md +76 -76
  117. package/framework/templates/meta-prompts/fusion/fusion-aggregator.md +100 -100
  118. package/framework/templates/meta-prompts/validators/pre-commit-validator.md +95 -95
  119. package/framework/templates/state.template.json +17 -17
  120. package/framework/templates/ui/design-system.css +226 -226
  121. package/package.json +2 -2
  122. package/src/commands/e2e/e2e.js +1 -1
  123. package/src/commands/project/heavy.js +1 -1
  124. package/src/commands/project/status.js +3 -3
  125. package/src/commands/project/worktree.js +34 -16
  126. package/src/commands/state/approve.js +9 -50
  127. package/src/commands/state/finish.js +4 -0
  128. package/src/commands/state/gate-check.js +18 -107
  129. package/src/commands/state/gate-decision.js +1 -1
  130. package/src/commands/state/report-check.js +42 -17
  131. package/src/commands/validation/mutate.js +1 -1
  132. package/src/commands/validation/scout-check.js +28 -0
  133. package/src/commands/validation/validate-feature.js +5 -32
  134. package/src/commands/validation/verify.js +16 -25
  135. package/src/core/paths/output-schema.js +0 -2
  136. package/src/core/state/state-manager.js +1 -2
  137. package/src/core/templates/template-renderer.js +477 -477
  138. package/src/dashboard/app/lib/format.js +5 -0
  139. package/src/dashboard/app/main.jsx +13 -13
  140. package/src/dashboard/app/pages/FeatureDetail.jsx +16 -22
  141. package/src/dashboard/app/pages/Features.jsx +7 -7
  142. package/src/dashboard/app/pages/PhasePipeline.jsx +1 -1
  143. package/src/dashboard/app/pages/Rubrics.jsx +7 -11
  144. package/src/dashboard/scanner/docs-scanner.js +1 -2
  145. package/src/dashboard/scanner/features-scanner.js +3 -4
  146. package/src/dashboard/scanner/rubrics-scanner.js +12 -12
  147. package/src/dashboard/vite.config.js +24 -24
  148. package/src/lib/agents/output-collector.js +0 -1
  149. package/src/lib/detectors/design-system-detector.js +188 -188
  150. package/src/lib/e2e/compose-env.js +5 -2
  151. package/src/lib/evaluator-report.js +52 -334
  152. package/src/lib/generators/design-system-generator.js +508 -508
  153. package/src/lib/generators/handoff-generator.js +4 -5
  154. package/src/lib/git/evidence-staleness.js +39 -0
  155. package/src/lib/installers/memory-installer.js +2 -2
  156. package/src/lib/mutation/manifest.js +8 -2
  157. package/src/lib/mutation/report.js +5 -3
  158. package/src/lib/mutation/runner.js +9 -7
  159. package/src/lib/risk-detector.js +63 -125
  160. package/src/lib/scout/scout-check.js +293 -0
  161. package/src/lib/tasks/eval-node.js +4 -34
  162. package/src/lib/tasks/task-classifier.js +30 -30
  163. package/src/lib/tasks/task-parser.js +209 -209
  164. package/src/lib/tasks/tasks-json-parser.js +7 -5
  165. package/src/lib/tasks/test-nodes.js +1 -1
  166. package/src/lib/tasks/test-runner.js +1 -1
  167. package/src/lib/validators/contracts/contract-compliance-validator.js +4 -42
  168. package/src/lib/validators/css/css-validator.js +340 -340
  169. package/src/lib/validators/reuse/reuse-validator.js +6 -8
  170. package/src/lib/validators/verify-runner.js +1 -1
  171. package/src/lib/worktree/env-allocator.js +35 -5
  172. package/src/scripts/setup-infra.js +1 -1
  173. package/src/utils/agent-id-mapper.js +11 -11
  174. package/src/utils/agents-installer.js +5 -9
  175. package/src/utils/claude-settings-manager.js +300 -300
  176. package/src/utils/hooks-installer.js +3 -10
  177. package/src/utils/skills-installer.js +1 -1
  178. package/framework/evals/proof-rubrics/README.md +0 -76
  179. package/framework/evals/proof-rubrics/eval-de-modelo.md +0 -80
  180. package/framework/evals/proof-rubrics/fiacao.md +0 -54
  181. package/framework/evals/proof-rubrics/guard-cego.md +0 -52
  182. package/framework/evals/proof-rubrics/media-claims.md +0 -109
  183. package/framework/evals/proof-rubrics/mutation-proof.md +0 -107
  184. package/framework/evals/proof-rubrics/observabilidade-genai.md +0 -119
  185. package/framework/evals/proof-rubrics/verde-nao-e-coberto.md +0 -48
  186. package/framework/evals/rubrics/README.md +0 -45
  187. package/framework/evals/rubrics/architecture.md +0 -103
  188. package/framework/evals/rubrics/code-quality.md +0 -98
  189. package/framework/evals/rubrics/condensed.md +0 -57
  190. package/framework/evals/rubrics/contracts.md +0 -67
  191. package/framework/evals/rubrics/test-coverage.md +0 -99
  192. package/framework/evals/scenarios/dotnet-crud.yaml +0 -42
  193. package/framework/evals/scenarios/nextjs-auth.yaml +0 -38
  194. package/framework/evals/suites/standard.yaml +0 -5
  195. package/framework/hooks/claude-code/core/post-edit-typecheck.js +0 -127
  196. package/framework/skills/core/morph-eval/SKILL.md +0 -64
  197. package/framework/templates/.idea/morph-templates.xml +0 -92
  198. package/framework/templates/.vscode/morph-templates.code-snippets +0 -186
  199. package/framework/templates/docs/clarifications.md +0 -253
  200. package/framework/templates/docs/onboarding.md +0 -122
  201. package/framework/templates/docs/schema-analysis.md +0 -119
  202. package/framework/templates/docs/user-stories.md +0 -34
  203. package/src/commands/state/score.js +0 -147
@@ -176,7 +176,7 @@ export async function mutateCommand(feature, options = {}) {
176
176
  merged.method.jobs = Math.max(merged.method.jobs ?? 1, result.method.jobs);
177
177
  }
178
178
  } catch (err) {
179
- if (err instanceof HeavyBusyError) return fail(`suíte não rodou: ${err.message}. Tente de novo quando liberar (morph-spec heavy status).`, EXIT.busy);
179
+ if (err instanceof HeavyBusyError) return fail(`suíte não rodou: ${err.message}. A fila já esperou o prazo dela: não repita em laço — registre a mutação como não executada (morph-spec heavy status).`, EXIT.busy);
180
180
  if (err.code === 'baseline-build-failed') return fail(`${err.message}\n${String(err.output ?? '').split('\n').slice(-12).join('\n')}`, EXIT.failed);
181
181
  throw err;
182
182
  }
@@ -0,0 +1,28 @@
1
+ import chalk from 'chalk';
2
+ import { existsSync, readFileSync } from 'fs';
3
+ import { resolve } from 'path';
4
+ import { checkScoutMap, resolveScoutRoot } from '../../lib/scout/scout-check.js';
5
+
6
+ export function scoutCheckCommand(mapPath, options = {}) {
7
+ const file = resolve(mapPath);
8
+ if (!existsSync(file)) {
9
+ if (options.json) console.log(JSON.stringify({ ok: false, error: 'map-not-found', map: file }));
10
+ else console.error(chalk.red(`scout-check: mapa não encontrado: ${file}`));
11
+ process.exit(2);
12
+ }
13
+ const result = { map: file, ...checkScoutMap(readFileSync(file, 'utf8'), { root: resolveScoutRoot(options.root) }) };
14
+
15
+ if (options.json) {
16
+ console.log(JSON.stringify(result, null, 2));
17
+ } else if (result.ok) {
18
+ console.log(chalk.green(`✓ scout-check: ${result.citations.length} citações conferidas contra ${result.root}`));
19
+ } else {
20
+ console.log(chalk.red(`✗ scout-check: ${result.failures.length} falha(s) em ${file} (raiz ${result.root})`));
21
+ for (const f of result.failures) {
22
+ const where = f.line ? `L${f.line}` : '—';
23
+ console.log(` ${where} ${chalk.yellow(f.kind)} ${f.citation ?? ''} ${f.detail}`);
24
+ }
25
+ console.log(chalk.gray(' Mapa reprovado: descarte e re-despache o scout UMA vez com estas falhas no prompt (MORPH.md §6).'));
26
+ }
27
+ process.exit(result.ok ? 0 : 1);
28
+ }
@@ -84,28 +84,6 @@ const OUTPUT_SECTIONS = {
84
84
  ['Performance', 'Desempenho'],
85
85
  ],
86
86
  },
87
- // morph-plan (mandate.md) emits: Stack, Standards obrigatórios,
88
- // Patterns proibidos, Verificação de runtime, Checklist de done.
89
- 'mandate.md': {
90
- required: [
91
- 'Stack',
92
- ['Standards', 'Padrões', 'Padroes'],
93
- ['Done', 'Pronto', 'Checklist', 'Critérios de done', 'Definition of Done'],
94
- ],
95
- recommended: [
96
- ['Patterns proibidos', 'Padrões proibidos', 'Padroes proibidos', 'Forbidden Patterns', 'Forbidden', 'Proibido'],
97
- // Recommended rather than required on purpose: mandate.md freezes after
98
- // Gate 2 (protect-spec-files blocks Write AND Edit), so promoting this to
99
- // `required` would fail every in-flight feature with no way to fix it.
100
- // New mandates get the section from morph-plan §4; the enforcement that
101
- // actually matters is verify's e2e node, not this heading check.
102
- ['Verificação de runtime', 'Verificacao de runtime', 'Runtime', 'E2E'],
103
- ],
104
- optional: [
105
- ['Riscos', 'Risks'],
106
- ['Acesso a dados', 'Data Access', 'Repository', 'Repositório'],
107
- ],
108
- },
109
87
  // decisions.md follows the ADR convention: an `### ADR-NNN` heading with
110
88
  // `**Status:** / **Context:** / **Decision:**` line-start bold labels.
111
89
  'decisions.md': {
@@ -123,19 +101,14 @@ const OUTPUT_SECTIONS = {
123
101
  ['Custos', 'Costs'],
124
102
  ],
125
103
  },
126
- // morph-review emits: Scores por dimensão, Bloqueantes, Melhorias,
127
- // Recomendação final.
128
104
  'review-report.md': {
129
105
  required: [
130
- ['Scores', 'Score', 'Pontuação', 'Pontuacao', 'Scoring'],
131
- ['Recomendação', 'Recomendacao', 'Recommendation'],
106
+ ['Veredito', 'Verdict'],
132
107
  ],
133
108
  recommended: [
134
- ['Bloqueantes', 'Bloqueante', 'Blockers'],
135
- ],
136
- optional: [
137
- ['Melhorias', 'Improvements', 'Recomendadas'],
109
+ ['Bloqueadores', 'Bloqueantes', 'Blockers'],
138
110
  ],
111
+ optional: [],
139
112
  },
140
113
  };
141
114
 
@@ -145,13 +118,13 @@ const OUTPUT_SECTIONS = {
145
118
  const PHASE_OUTPUTS = {
146
119
  proposal: ['proposal.md'],
147
120
  uiux: ['design-system.md', 'mockups.md', 'components.md', 'flows.md'],
148
- plan: ['spec.md', 'mandate.md', 'tasks.json'],
121
+ plan: ['spec.md', 'tasks.json'],
149
122
  implement: ['recap.md'],
150
123
  review: ['review-report.md'],
151
124
  };
152
125
 
153
126
  // Work types whose plan phase (see src/core/work-types.js) skips proposal.md/
154
- // spec.md/mandate.md — chore and hotfix stamp proposal+plan gates at birth
127
+ // spec.md — chore and hotfix stamp proposal+plan gates at birth
155
128
  // (policy-approved, no human deliberation over those docs) and go straight to
156
129
  // tasks.json. Validating the full plan doc set against a feature that was
157
130
  // never asked to write those docs would be a false failure, not a real gap.
@@ -129,6 +129,13 @@ function decidePersistence({ cwd, featureName, noPersist }) {
129
129
  return { persist: false, reason: samePath(root, cwd) ? 'owner-tree-elsewhere' : 'unregistered-worktree' };
130
130
  }
131
131
 
132
+ function baselineStampBlock(baseline) {
133
+ if (!baseline?.recorded) return baseline?.reason ? `record-baseline: ${baseline.reason}` : 'record-baseline';
134
+ const fell = baseline.updates.filter((u) => u.from !== null && u.to < u.from);
135
+ if (fell.length === 0) return null;
136
+ return `record-baseline: a contagem caiu em ${fell.map((u) => `${u.id} (${u.from} → ${u.to})`).join(', ')}`;
137
+ }
138
+
132
139
  /**
133
140
  * The per-node status map, in the shape `feature.schema.json` fixes for BOTH
134
141
  * writers of it — the per-scope history entry (`verifications.*`) and the
@@ -196,8 +203,7 @@ const PARTIAL_RUN_FLAGS = [['filter', 'filtered'], ['skipTests', 'skip-tests'],
196
203
  * paths to it — never a verdict, because a verdict about nothing is worse
197
204
  * than a refusal:
198
205
  * - unknown feature, or unknown task id (the task's `group` decides the
199
- * rubric, so it is a hard usage error here, unlike the advisory warning
200
- * `morph-spec score` gives for the same situation);
206
+ * rubric, so it is a hard usage error here);
201
207
  * - `--filter` that matches no declared node (a filtered-to-empty run is
202
208
  * green and proves nothing);
203
209
  * - `--record-baseline` with nowhere to write (no `config.json`), or with a
@@ -256,7 +262,7 @@ export async function verifyCommand(featureName, taskId, options = {}) {
256
262
  process.exit(2);
257
263
  }
258
264
  // Ocupado não é veredito: nada foi verificado, então não há stamp nem
259
- // evento, e o exit 3 diz "tente de novo", nunca "vermelho".
265
+ // evento, e o exit 3 nunca é "vermelho".
260
266
  if (err instanceof HeavyBusyError) {
261
267
  if (options.json) {
262
268
  const holders = err.holders.map(({ pid, label, feature, node, since }) => ({ pid, label, feature, node, since }));
@@ -264,7 +270,7 @@ export async function verifyCommand(featureName, taskId, options = {}) {
264
270
  status: 'busy', persisted: false, busy: { reason: err.reason, holders, freeGb: err.freeGb, waitedMs: err.waitedMs },
265
271
  }, null, 2));
266
272
  }
267
- console.error(chalk.yellow(`\n⏳ verify não rodou: ${err.message}. Não é vermelho — tente de novo quando liberar (\`morph-spec heavy status\`).\n`));
273
+ console.error(chalk.yellow(`\n⏳ verify não rodou: ${err.message}. Não é vermelho — a fila já esperou o prazo dela: não repita em laço — siga sem esta rodada e avise o usuário (\`morph-spec heavy status\` mostra quem segura os slots).\n`));
268
274
  process.exit(3);
269
275
  }
270
276
  throw err;
@@ -277,30 +283,15 @@ export async function verifyCommand(featureName, taskId, options = {}) {
277
283
  });
278
284
 
279
285
  const scopeKey = taskId ? `taskVerifications.${taskId}` : 'verifications.feature';
280
- // `--record-baseline` is config maintenance, not gate evidence: it measures
281
- // the suite in order to write `expectedCount`. Persisting a `verification`
282
- // stamp from it would let a maintenance run stand in for the proof a gate
283
- // asks for — the same class of confusion as a hand-typed baseline.
284
- //
285
- // `--filter` at FEATURE scope is the other side of the same hole (#87): the
286
- // run is narrowed to a subset of nodes, but the stamp it would write carries
287
- // `scope: 'feature'` — the one scope risk-detector.js trusts unconditionally.
288
- // A partial run must not stand in for the proof a gate asks for, same as
289
- // `--record-baseline` above. `--skip-tests` and `--skip-build` are the same
290
- // partial run through another door (#113): a skipped node never reddens the
291
- // rollup, so the stamp said `pass` over a suite (or a build) that never ran,
292
- // and no gate rule reads a skipped `tests`/`build`. Task scope is unaffected:
293
- // that stamp already says `scope: 'task:{id}'` (which pauses the ship gate on
294
- // its own), and `taskVerifications` never claimed to cover more than the
295
- // task. Checked AFTER `--no-persist` (via the `!options.noPersist` guard) so
296
- // an explicit `--no-persist` keeps its own reason instead of being reported
297
- // as one of these — the flags are all "don't write", but decidePersistence()
298
- // already owns the former's reason.
286
+ // A run that measured only part of the suite must not stand in for the proof a gate asks for:
287
+ // --filter and --skip-* at feature scope, or a --record-baseline that recorded nothing. Task scope
288
+ // is unaffected (its stamp already says scope 'task:{id}'); --no-persist keeps its own reason.
299
289
  const partialFeatureRun = (!options.noPersist && !taskId)
300
290
  ? PARTIAL_RUN_FLAGS.find(([flag]) => options[flag])?.[1] ?? null
301
291
  : null;
302
- const { persist, reason } = options.recordBaseline
303
- ? { persist: false, reason: 'record-baseline' }
292
+ const baselineBlock = options.recordBaseline ? baselineStampBlock(result.baseline) : null;
293
+ const { persist, reason } = baselineBlock
294
+ ? { persist: false, reason: baselineBlock }
304
295
  : partialFeatureRun
305
296
  ? { persist: false, reason: partialFeatureRun }
306
297
  : decidePersistence({ cwd: process.cwd(), featureName, noPersist: options.noPersist });
@@ -46,7 +46,6 @@ export const OUTPUT_SCHEMA = {
46
46
 
47
47
  // 2-plan/
48
48
  spec: { filename: 'spec.md', phaseDir: '2-plan', phase: 'plan', protected: true, approvalGate: 'plan' },
49
- mandate: { filename: 'mandate.md', phaseDir: '2-plan', phase: 'plan', protected: true, approvalGate: 'plan' },
50
49
  tasks: { filename: 'tasks.json', phaseDir: '2-plan', phase: 'plan', protected: true, approvalGate: 'plan', mutableFields: ['status', 'outputs', 'notes'] },
51
50
  decisions: { filename: 'decisions.md', phaseDir: '2-plan', phase: 'plan', protected: false },
52
51
  // Veredito REUSAR/ESTENDER/CRIAR por conceito que a feature introduz, com a
@@ -55,7 +54,6 @@ export const OUTPUT_SCHEMA = {
55
54
  // como decisions.md: é registro vivo — o implementador que descobre um alvo
56
55
  // melhor no meio da task precisa poder anotar, e congelá-lo transformaria a
57
56
  // correção num bloqueio de gate.
58
- reuseMap: { filename: 'reuse-map.md', phaseDir: '2-plan', phase: 'plan', protected: false },
59
57
  // N files, one per system use case — the behaviour layer the plan distils
60
58
  // BEFORE spec.md/tasks.json. Deliberately NOT protected: editing a use case
61
59
  // after Gate 2 is the supported way to change behaviour and re-run implement;
@@ -581,7 +581,6 @@ export async function createFeature(featureName, options = {}) {
581
581
  review: { approved: false, timestamp: null, approvedBy: null }
582
582
  },
583
583
  gateDecisions: {},
584
- taskScores: {},
585
584
  tasks: {
586
585
  total: 0,
587
586
  completed: 0,
@@ -782,7 +781,7 @@ function findClosestMatch(inputType, validTypes) {
782
781
  /**
783
782
  * Mark output as created
784
783
  * @param {string} featureName - Feature name
785
- * @param {string} outputType - Output type (proposal, spec, mandate, etc.)
784
+ * @param {string} outputType - Output type (proposal, spec, tasks, etc.)
786
785
  */
787
786
  export async function markOutput(featureName, outputType) {
788
787
  await ensureFeature(featureName);