@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
@@ -4,7 +4,7 @@ description: Localiza um standard específico via busca server-side (morph-spec
4
4
  version: core
5
5
  when-to-invoke: quando precisar consultar um standard específico durante a implementação
6
6
  user-invokable: true
7
- cliVersion: "8.43.0"
7
+ cliVersion: "8.45.0"
8
8
  ---
9
9
 
10
10
  # morph-standards
@@ -16,7 +16,7 @@ para aplicar o standard na maioria dos casos.
16
16
 
17
17
  ## Quando invocar
18
18
  Quando durante a implementação surgir uma dúvida de padrão arquitetural, de contrato, de qualidade
19
- ou de teste — e o mandate.md não for suficiente para resolver.
19
+ ou de teste — e o `spec.md` e os standards da task não bastarem para resolver.
20
20
 
21
21
  ## O que fazer
22
22
 
@@ -4,7 +4,7 @@ description: Conduz a fase opcional de UI/UX — design system, mockups, compone
4
4
  version: core
5
5
  when-to-invoke: ao tomar o ramo uiux (morph-spec advance --design), depois do Gate 1 e antes do morph-plan
6
6
  user-invokable: true
7
- cliVersion: "8.43.0"
7
+ cliVersion: "8.45.0"
8
8
  ---
9
9
 
10
10
  # morph-uiux
@@ -89,8 +89,7 @@ Ao tomar o ramo opcional uiux: feature/bug cuja mudança cria ou altera superfí
89
89
 
90
90
  Cada relatório contém: (1) o que foi feito em 2-3 frases, (2) o artefato produzido,
91
91
  (3) decisões de design e por quê (token reusado vs. novo, padrão de acessibilidade
92
- aplicado), (4) auto-score 0-10 com justificativa em uma linha. Relatório ausente, oco,
93
- ou sem os 4 itens, é falha de protocolo.
92
+ aplicado), (4) o que ficou em aberto. Relatório ausente ou oco é falha de protocolo.
94
93
  ```
95
94
 
96
95
  Após o retorno: **leia primeiro** `1-design/reports/*-report.md` — valor de retorno autoritativo, a mensagem de texto é atalho best-effort quando chega inteira. `design-system.md` é o único output obrigatório (`phases.json → uiux.requiredOutputs`); sem ele em disco, `morph-spec advance` recusa avançar — confirme que existe antes de rodar `advance` no passo 6.
@@ -33,7 +33,7 @@
33
33
  "visao": "#visão-com-structured-output",
34
34
  "historico": "#chat-com-histórico",
35
35
  "lastro": "#lastro-de-campo-por-arquétipo",
36
- "checklist": "#checklist-verifiable-by-morph-eval"
36
+ "checklist": "#checklist-verifiable-in-review"
37
37
  },
38
38
  "digest": "The four shapes an agent can take, and the plan-phase question that picks one: conversational-with-phases, one-shot batch, vision + structured output, chat with history. Field ballast is UNEVEN and the standard says so: batch has 3 exemplars, conversational has 1, vision+structured has ZERO (it is a projected shape, not a distilled one), and conversational and chat-with-history are two AXES OF THE SAME AGENT (phases x history ownership), not alternatives. Pairs with ai-agents-sweet-spot, which decides agent-vs-workflow before this file decides which shape.",
39
39
  "verifiedAgainst": "Microsoft.Agents.AI 1.20.0 + Microsoft.Extensions.AI 10.9.0 (ai-pin 2026-09-08); provado por `templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentFactory.cs` e `.../Conversation/ConversationStore.cs` (arquétipos **one-shot em batch** e **chat com histórico** — o conversacional com fases NÃO tem lastro no kit, e `ai-agents-conversational-agent-with-phases` declara isso no próprio cabeçalho). O arquétipo visão + structured output é **verificação documental** — o ai-kit não exercita multimodalidade.",
@@ -112,7 +112,7 @@
112
112
  "catalogo": "#agentcatalog",
113
113
  "defaults": "#defaults-fora-do-código",
114
114
  "higiene": "#higiene-de-publicação",
115
- "checklist": "#checklist-verifiable-by-morph-eval"
115
+ "checklist": "#checklist-verifiable-in-review"
116
116
  },
117
117
  "digest": "The agent as DATA: one immutable AgentSpec record per agent (Alias required, Instructions required, Api?, Tools, OutputSchema?, Options, Name?, Description?), a catalog that enumerates them, and defaults outside the code. The doctrine this standard freezes: a NULL property means \"do not send to the provider\", never \"send the framework default\" — and an empty list is NOT treated as null, it is sent as written. Precedence between the spec api and the alias api lives in ONE method on the record, never inside the factory. Blank Alias/Instructions are rejected at construction. A catalog entry with no runtime consumer is dead weight (measured: a seeded agent with a versioned prompt and zero C# callers).",
118
118
  "verifiedAgainst": "Microsoft.Agents.AI 1.20.0 + Microsoft.Extensions.AI 10.9.0 (ai-pin 2026-09-08); provado por `templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentSpec.cs`, `.../Agents/AgentSpecOptions.cs` e `.../Agents/AgentFactory.cs` — o record, o bag de opções e a materialização são exatamente o que o kit compila.",
@@ -228,7 +228,7 @@
228
228
  "requireany": "#exigir-tool-no-turno",
229
229
  "teto": "#teto-de-tool-calls-e-isenta",
230
230
  "auxiliar": "#agente-auxiliar-em-sequência",
231
- "checklist": "#checklist-verifiable-by-morph-eval"
231
+ "checklist": "#checklist-verifiable-in-review"
232
232
  },
233
233
  "digest": "ONE agent, phase as turn data — the deep dive on the first archetype, and it DECLARES a single field source in its own body. A deterministic turn composer (pure static class, no I/O) yields the turn plan; the prompt is born decomposed into NAMED BLOCKS and the text sent IS the concatenation, derived without cache ON PURPOSE, \"so telemetry cannot lie\" — the invariant that makes a prompt hash worth anything. Allow-list prunes in two stages (phase, then tenant capability), a tool absent from the map is AVAILABLE, and pruning preserves order. Tool-call ceiling with an exempt tool, at agent level (not ChatOptions). ChatToolMode.RequireAny exists (measured by reflection) and is the default when every action is a tool — but it ships with an EXIT CRITERION, not a blind prescription: the field alternative (a second pass) has 7 tests and a \"recovered\" outcome, so migrate when the recovered rate stops paying for the second paid call. An auxiliary agent runs in sequence, never nested inside a tool call.",
234
234
  "verifiedAgainst": "Microsoft.Extensions.AI 10.9.0 + Microsoft.Agents.AI 1.20.0 (ai-pin 2026-09-08). `ChatToolMode.RequireAny` foi **medido por reflexão sobre `Microsoft.Extensions.AI.Abstractions` 10.9.0** em 2026-09-08. O restante é **verificação documental**, sem cláusula `provado por` — o ai-kit ainda não traz um compositor de turno, e o padrão é destilado de um único repositório de campo (ver a nota de fonte única abaixo).",
@@ -267,7 +267,7 @@
267
267
  "teto": "#teto-de-orçamento",
268
268
  "total": "#medir-o-total-não-o-piso",
269
269
  "fronteira": "#fronteira-com-observability-patterns",
270
- "checklist": "#checklist-verifiable-by-morph-eval"
270
+ "checklist": "#checklist-verifiable-in-review"
271
271
  },
272
272
  "digest": "The only owner of COST as a subject. The SDK gives tokens and does not give money: UsageDetails (measured by reflection on Microsoft.Extensions.AI.Abstractions 10.9.0) exposes Input/Output/Total/Cached/Reasoning counts, the text-audio pairs, AdditionalCounts and Add() — and NO price property. So the tariff lives per alias in the registry, WITH a verification date, and an alias without a tariff must carry a written waiver. One middleware, above function-invocation in the pipeline (measured: above it, Usage already totals every tool round and one line is published per call). Three formula traps: reasoning tokens billed as output, CACHED input is a SUBSET of input (adding them double-counts), and hosted-operation flat fees never appear in UsageDetails. cost_usd is NEVER null: zero with an explicit state — Computed / Waived / UsageMissing. Budget UNIT is a parameter (lead, tenant, operation, day); the measured pain is one of PLACE — a ceiling living inside a tool does not govern the pipeline. Warn before blocking, and the block returns an actionable sentence to the model, never an exception. Two-way delegation with ai-agents-observability-patterns: span attributes stay there, tariff and ceiling live here.",
273
273
  "verifiedAgainst": "Microsoft.Extensions.AI 10.9.0 + Microsoft.Agents.AI 1.20.0 (ai-pin 2026-09-08); provado por `templates/dotnet/ai-kit/src/Morph.AiKit/Middleware/UsageCostMiddleware.cs`, `.../Middleware/UsageCostRecord.cs` e `.../Providers/ModelAlias.cs` — o middleware, o record de custo não-nulo e a conta de tarifa são o que o kit compila. A ausência de qualquer propriedade de preço em `UsageDetails` foi **medida por reflexão sobre `Microsoft.Extensions.AI.Abstractions` 10.9.0** em 2026-09-08. O teto de orçamento é **verificação documental** — o ai-kit não traz um middleware de orçamento.",
@@ -398,7 +398,7 @@
398
398
  "argumento": "#argumento-de-tool-é-input-não-confiável",
399
399
  "pertinencia": "#pertinência-não-presença",
400
400
  "failopen": "#quando-o-guard-não-consegue-decidir",
401
- "checklist": "#checklist-verifiable-by-morph-eval"
401
+ "checklist": "#checklist-verifiable-in-review"
402
402
  },
403
403
  "digest": "What the CODE guarantees once the prompt has already failed. A rule with real consequence leaves the prompt and becomes a C# condition — the measured reason, written in field code: the model obeys \"one entry per element of this list\" but errs badly when it must judge on its own which blocks have data (10 expected, 2 delivered). Three legitimate choke-points (before the turn in the composer; in the function-invocation middleware, with a CLOSED outcome vocabulary ok/error/invalid_args/limit/unavailable and required arguments read from the function JSON schema; after the run as backstop). Tool arguments are UNTRUSTED input: ids and money come from the turn closure, never from the model. Relevance, not presence: compare against something that did NOT come from the model — a deterministic rubric checked BY EQUALITY against the backend numbers, a provenance lock that demotes an unsupported \"found\" while PRESERVING the reasoning for audit, and a per-source confidence floor. When the guard cannot decide the answer is FAIL-OPEN, ratified with one hard condition: the escape is RECORDED (the anti-pattern is 81 of 83 catch blocks that never read the exception). Verdict is ternary — pass / reject / not_evaluated — because a boolean turns \"could not evaluate\" into \"approved\".",
404
404
  "verifiedAgainst": "Microsoft.Extensions.AI 10.9.0 + Microsoft.Agents.AI 1.20.0 (ai-pin 2026-09-08). **Verificação documental**, sem cláusula `provado por` — o ai-kit não traz um guard de exemplo; o padrão é destilado de dois repositórios em produção, com o local de cada evidência citado na seção correspondente.",
@@ -436,7 +436,7 @@
436
436
  "strict": "#strict-json-schema-por-alias",
437
437
  "temperature": "#temperature-e-reasoning",
438
438
  "pin": "#pin-de-sdk-e-compatibilidade-binária",
439
- "checklist": "#checklist-verifiable-by-morph-eval"
439
+ "checklist": "#checklist-verifiable-in-review"
440
440
  },
441
441
  "digest": "The runtime KNOBS of a model call, with the boundary against ai-agents-providers-model-registry (Layer 0, which owns the SCHEMA) written as the first section. Retry is INHERITED from the System.ClientModel pipeline — do not stack a loop on top (3 x 3 = 9 paid calls). Timeout is NOT inherited and must be created: ChatOptions has no timeout property (measured by reflection) and OpenAIClientOptions declares only Endpoint/OrganizationId/ProjectId/UserAgentApplicationId — the knob comes from the ClientPipelineOptions base. A CancellationToken is not a timeout. StrictJsonSchema DOES NOT EXIST: zero exported types containing \"Strict\" across the 14 pinned assemblies, and ChatResponseFormatJson has no strict field; the real mechanism is a key in ChatOptions.AdditionalProperties, so strict is per alias and NEVER a process-global flag. ReasoningEffort is a first-class enum (None/Low/Medium/High/ExtraHigh). Pin AI packages exactly — a floating 2.* range cost a MissingMethodException after the call was already paid for.",
442
442
  "verifiedAgainst": "Microsoft.Extensions.AI 10.9.0 + Microsoft.Agents.AI 1.20.0 + OpenAI 2.13.0 (ai-pin 2026-09-08); provado por `templates/dotnet/ai-kit/src/Morph.AiKit/Providers/ModelAlias.cs` e `.../Providers/ModelRegistry.cs` (alias, `api:`, e limite por alias com procedência obrigatória). A superfície do SDK citada aqui — `ChatOptions`, `ChatResponseFormatJson`, `ReasoningEffort`, `OpenAIClientOptions` — foi **medida por reflexão sobre as assemblies do pin** em 2026-09-08. O timeout é **provado por** `.../Agents/AgentSpecOptions.cs` e `.../Agents/AgentFactory.cs`, que o kit compila **por spec** (`TimeoutSeconds` vira um cliente de timeout no pipeline) — e **não** por alias: a allowlist de alias do registry não tem chave de timeout (medido). Os valores default do retry do `System.ClientModel` 1.15.0 são **verificação documental** — essa assembly está fora do conjunto que o probe carrega.",
@@ -866,7 +866,7 @@
866
866
  "rastreabilidade": "#rastreabilidade-do-que-foi-ao-provedor",
867
867
  "convencao": "#estabilidade-da-convenção-genai--a-ressalva-que-muda-como-ler-a-tabela-acima"
868
868
  },
869
- "digest": "Canonical treatment of OpenTelemetry for MAF agents: setup, enrichment, investigation. Two DIFFERENT ActivitySources must be registered — Experimental.Microsoft.Agents.AI (span invoke_agent) and Experimental.Microsoft.Extensions.AI (spans chat and execute_tool, metrics gen_ai.client.operation.duration and gen_ai.client.token.usage). AgentOpenTelemetryConsts and agent.WithOpenTelemetry() do NOT exist in 1.20.0; the API is builder.UseOpenTelemetry(sourceName, configure) and the sensitive-data switch is EnableSensitiveData (same name on OpenTelemetryAgent and OpenTelemetryChatClient). Duplication rule, measured: instrumenting the two LEVELS is normal and does not duplicate; instrumenting the same level twice does. With a custom pipeline (UseProvidedChatClientAsIs) the MAF guard does not reach it and chat instrumentation becomes mandatory. Issue 3637 (no GenAI ActivityEvents) is a known open limitation. TRACEABILITY (added 2026-09-08): the question the instrumentation exists to answer is whether the turn can be RECONSTRUCTED — raw prompt only in dev/harness with opt-in, HASH in production, and the invariant that makes the hash worth anything is that the text sent is derived from named blocks WITHOUT cache (a cache between assembly and send lets telemetry and request diverge in silence). Two closing assertions: the offered tool list came from the real turn list, and a CANCELLED turn writes nothing. CONVENTION STABILITY: the GenAI semantic conventions LEFT the main OpenTelemetry repo — semconv v1.42.0 (2026-06-12) deprecated and moved all of gen_ai.*, v1.43.0 carries none, the content lives in open-telemetry/semantic-conventions-genai where NOTHING GenAI is Stable (all Development; only error.type/server.address/server.port are stable, and those are common attributes), while OpenTelemetryChatClient declares v1.37 — behind the split. Instrument anyway, but do not build an alert whose only identifier is a gen_ai.* name without a rename plan. Cost delegation is two-way: tariff, cost formula and budget ceiling live in ai-agents-cost-and-budget; span attributes stay here. The Gate 3 ruler for this property is evals/proof-rubrics/observabilidade-genai.md.",
869
+ "digest": "Canonical treatment of OpenTelemetry for MAF agents: setup, enrichment, investigation. Two DIFFERENT ActivitySources must be registered — Experimental.Microsoft.Agents.AI (span invoke_agent) and Experimental.Microsoft.Extensions.AI (spans chat and execute_tool, metrics gen_ai.client.operation.duration and gen_ai.client.token.usage). AgentOpenTelemetryConsts and agent.WithOpenTelemetry() do NOT exist in 1.20.0; the API is builder.UseOpenTelemetry(sourceName, configure) and the sensitive-data switch is EnableSensitiveData (same name on OpenTelemetryAgent and OpenTelemetryChatClient). Duplication rule, measured: instrumenting the two LEVELS is normal and does not duplicate; instrumenting the same level twice does. With a custom pipeline (UseProvidedChatClientAsIs) the MAF guard does not reach it and chat instrumentation becomes mandatory. Issue 3637 (no GenAI ActivityEvents) is a known open limitation. TRACEABILITY (added 2026-09-08): the question the instrumentation exists to answer is whether the turn can be RECONSTRUCTED — raw prompt only in dev/harness with opt-in, HASH in production, and the invariant that makes the hash worth anything is that the text sent is derived from named blocks WITHOUT cache (a cache between assembly and send lets telemetry and request diverge in silence). Two closing assertions: the offered tool list came from the real turn list, and a CANCELLED turn writes nothing. CONVENTION STABILITY: the GenAI semantic conventions LEFT the main OpenTelemetry repo — semconv v1.42.0 (2026-06-12) deprecated and moved all of gen_ai.*, v1.43.0 carries none, the content lives in open-telemetry/semantic-conventions-genai where NOTHING GenAI is Stable (all Development; only error.type/server.address/server.port are stable, and those are common attributes), while OpenTelemetryChatClient declares v1.37 — behind the split. Instrument anyway, but do not build an alert whose only identifier is a gen_ai.* name without a rename plan. Cost delegation is two-way: tariff, cost formula and budget ceiling live in ai-agents-cost-and-budget; span attributes stay here. The Gate 3 ruler for this property is evals/review-checklist.md.",
870
870
  "verifiedAgainst": "Microsoft.Agents.AI 1.20.0 + Microsoft.Extensions.AI 10.9.0 (ai-pin 2026-09-08); `provado por templates/dotnet/ai-kit/src/Morph.AiKit/Observability/MorphOpenTelemetryExtensions.cs` — o guard de span duplicado, a regra de \"um nível, uma instrumentação\" e o default `EnableSensitiveData = false` são exatamente o que o kit compila, com os spans contados em `tests/Morph.AiKit.Tests/TelemetryTests.cs`. Nomes de símbolo, de span, de métrica e das duas `ActivitySource` foram **medidos por reflexão e por leitura dos literais das assemblies do pin** em 2026-09-08, e em 2026-09-09 **todos os treze nomes `gen_ai.*` desta página** foram remedidos, um a um, por **teste de exclusividade**: os quatro `SetTag` da seção *Enrichment* e os nove das seções de span, métrica e atributo de agente. **Os treze existem** — depois de uma correção: `gen_ai.response.finish_reason`, no **singular**, não existia, só aparecia como cabeça de `finish_reason`**s**, e sobreviveu a duas varreduras porque as duas usaram `includes` — e **`includes` de um prefixo não prova o literal autônomo**. Os treze estão tabelados, em **duas** tabelas com propósitos diferentes: a de *Enrichment* registra os **4** `SetTag` daquele bloco (mais os **cinco** nomes rejeitados: o `finish_reason` singular, `PromptTokens`, `CompletionTokens`, `prompt_tokens` e `completion_tokens`), e a de distribuição, na seção *Nomes de span, métricas e atributos — medidos*, registra os **13** por assembly. A conferência é reproduzível por `node scripts/api-probe/probe.mjs tags` sobre este arquivo. A **instabilidade da convenção** — o split do semconv **v1.42.0 (2026-06-12)**, que depreciou e moveu todo `gen_ai.*` para `open-telemetry/semantic-conventions-genai`, onde nada GenAI está `Stable`, contra a v1.37 que o `OpenTelemetryChatClient` declara implementar — é **verificação documental**, apurada em 2026-09-08.",
871
871
  "provedBy": [
872
872
  "templates/dotnet/ai-kit/src/Morph.AiKit/Observability/MorphOpenTelemetryExtensions.cs"
@@ -981,7 +981,7 @@
981
981
  "schema": "#schema-canonical",
982
982
  "providers": "#providers-first-class",
983
983
  "implementation": "#implementation-pattern",
984
- "checklist": "#checklist-verifiable-by-morph-eval"
984
+ "checklist": "#checklist-verifiable-in-review"
985
985
  },
986
986
  "digest": "Single JSON file (model-registry.json v2) maps aliases to { provider, model, api, options, constraints }. Agents reference aliases, never model strings. EVERY alias declares `api`: `responses` (default when omitted) or `chat` (explicit opt-in); Ollama/OpenAI-compatible providers ignore the field but never travel the Responses path. `temperature` and `reasoningEffort` are mutually exclusive per alias, with the two origins labelled separately: the documented one (Chat Completions rejects tool calling with reasoning_effort != none from GPT-5.4) and the field-measured one (temperature on reasoning models — no primary source, so it is a per-alias constraint with mandatory provenance). .NET path: ChatOptions.Reasoning = new ReasoningOptions { Effort = ReasoningEffort.* } is CONFIRMED in M.E.AI 10.9.0; RawRepresentationFactory is the escape hatch for values the enum lacks. OPENAI001 still applies to the Responses types. No floating PackageReference ranges.",
987
987
  "verifiedAgainst": "Microsoft.Agents.AI 1.20.0 + Microsoft.Extensions.AI 10.9.0 + OpenAI 2.13.0 (ai-pin 2026-09-08); provado por `templates/dotnet/ai-kit/src/Morph.AiKit/Providers/ModelRegistry.cs` e `.../Providers/ModelAlias.cs` e `.../Agents/AgentApi.cs`. Nomes de tipo do `Microsoft.Extensions.AI` e do `OpenAI` medidos por reflexão sobre as assemblies do pin em 2026-09-08.",
@@ -1208,7 +1208,7 @@
1208
1208
  "eval": "#eval-e-unit",
1209
1209
  "captura": "#captura-do-que-foi-ao-provedor",
1210
1210
  "golden": "#golden-com-parcimônia",
1211
- "checklist": "#checklist-verifiable-by-morph-eval"
1211
+ "checklist": "#checklist-verifiable-in-review"
1212
1212
  },
1213
1213
  "digest": "Only what is agent-specific — backend-dotnet-testing keeps xUnit, FakeTimeProvider and isolation. The single point where code touches a provider is an IChatClient, so everything follows from replacing it: a SCRIPTED and DUMB fake (a queue of hand-written responses, capture of messages/options/call count) that THROWS when the queue runs out — a silent empty response makes a test pass by accident. Two independent products converged on this shape; the kit compiles the third. Run the REAL function-invocation loop on top of the fake: tool choice, arguments, guard and ceiling are only observable through the loop. The seam keeps classes sealed (a one-operation interface, or an internal constructor taking alias -> IChatClient). ZERO real provider calls inside dotnet test, verified by a sweep of tests/ for API keys, environment reads and HTTP clients — and the standard records the price of leaving the real harness outside the suite: 11 scenarios that were never run end to end. Eval means DETERMINISTIC eval over the full real path with the model scripted; a hard gate only over deterministic properties. Raw prompt only in dev/harness with opt-in, hash in production. Golden proves FORM, not content (counter-example: 13.6 KB frozen to prove two lines of concatenation, deliberately deleted). A versioned prompt gets AT MOST ONE structural test (keys the consumer reads, absence of a revoked instruction); what the model answers is proven at runtime by evals-with-cache, never by Contains over the prompt source.",
1214
1214
  "verifiedAgainst": "Microsoft.Extensions.AI 10.9.0 + Microsoft.Agents.AI 1.20.0 (ai-pin 2026-09-08); provado por `templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeChatClient.cs` e `.../src/Morph.AiKit/Providers/IProviderClientFactory.cs` — o fake roteirizado e a costura que dispensa rede são o que o kit compila e exercita. Harness de turno completo e evals com cache de resposta são **verificação documental** — o ai-kit não os traz.",
@@ -2566,15 +2566,18 @@
2566
2566
  "POSTGRES_PORT",
2567
2567
  "COMPOSE_PROJECT_NAME",
2568
2568
  "port block",
2569
+ "PG_PORT",
2570
+ "portEnvNames",
2569
2571
  "local docker compose"
2570
2572
  ],
2571
2573
  "anchors": {
2572
2574
  "layout": "#port-layout-one-contract-everywhere",
2575
+ "portNames": "#project-named-port-variables",
2573
2576
  "rules": "#core-rules",
2574
2577
  "enforcement": "#what-the-harness-enforces",
2575
2578
  "skeleton": "#minimal-compose-skeleton"
2576
2579
  },
2577
- "digest": "Every worktree runs its OWN compose stack (project morph-{feature}, own postgres, own volumes). Ports come from the worktree block: PORT +0, API_PORT +1 (ASPNETCORE_URLS on .NET), POSTGRES_PORT +2, REDIS_PORT +3 — publish via ${VAR:-default}:container, never a fixed host port, never container_name (not prefixed by the project → collides). Stable POSTGRES_DB, healthcheck on every service, DATABASE_URL with an in-network default, playwright.config reads PLAYWRIGHT_BASE_URL. A non-isolable compose fails the verify e2e node inside a worktree. finish tears down with volumes (--keep-volumes opts out). Cloud DB credentials go in e2e.auth.envFile, never in .morph/worktree.env.",
2580
+ "digest": "Every worktree runs its OWN compose stack (project morph-{feature}, own postgres, own volumes). Ports come from the worktree block: PORT +0, API_PORT +1 (ASPNETCORE_URLS on .NET), POSTGRES_PORT +2, REDIS_PORT +3 — publish via ${VAR:-default}:container, never a fixed host port, never container_name (not prefixed by the project → collides). Stable POSTGRES_DB, healthcheck on every service, DATABASE_URL with an in-network default, playwright.config reads PLAYWRIGHT_BASE_URL. A non-isolable compose fails the verify e2e node inside a worktree. finish tears down with volumes (--keep-volumes opts out). Cloud DB credentials go in e2e.auth.envFile, never in .morph/worktree.env. A compose that reads a port by ANOTHER name (PG_PORT) is not fed by the block: declare it in config.json e2e.portEnvNames ({\"postgres\": \"PG_PORT\"}) and the harness exports it with the same value in worktree.env, the compose env and the hook.",
2578
2581
  "verifiedAgainst": "Docker Compose v2 + morph-spec 8.34 (dedicated stack per worktree).",
2579
2582
  "provedBy": []
2580
2583
  },
@@ -2851,6 +2854,47 @@
2851
2854
  "digest": "Default is NO comment: code explains itself through names, types and tests. Before commenting, rename, extract a function or named constant, encode the state in the type, or write a test; comment only what none of these can express: an invariant the type does not express, an order that matters, an external quirk (third-party API, library bug with its link), or the contract of a package published for consumers outside the repo. Never process history (task, UC, ADR, FR, Gate, evaluator, spec.md, mockup: commit message and decisions.md; in a test the link to the postcondition goes in the test NAME), never restate the code, no XML doc/JSDoc on application members that repeats the signature, no file headers, section banners, #region, commented-out code or loose TODOs, no claims about behavior (make them test assertions). One line is normal, ~3 is the ceiling; more than one comment line per ten code lines means the names are not doing the work. A heavily commented neighbour file is not a model. The comment-guard hook blocks an edit that ADDS process history, a banner/#region, a block over 3 lines or a doc-comment outside a published package; the verify validators node (code-budget) warns on added comments that cite process and on added comment density.",
2852
2855
  "verifiedAgainst": "C#, TypeScript e JavaScript (convenção de linguagem, sem pacote externo).",
2853
2856
  "provedBy": []
2857
+ },
2858
+ {
2859
+ "id": "ai-agents-tool-adapters",
2860
+ "name": "tool adapters",
2861
+ "path": "ai-agents/tool-adapters.md",
2862
+ "category": "ai-agents",
2863
+ "subcategory": null,
2864
+ "tags": [
2865
+ "ai-agents",
2866
+ "maf",
2867
+ "tools",
2868
+ "testing"
2869
+ ],
2870
+ "stacks": [
2871
+ "dotnet"
2872
+ ],
2873
+ "aliases": [
2874
+ "tool fina",
2875
+ "adaptador de tool",
2876
+ "Ops",
2877
+ "Desfecho",
2878
+ "Render",
2879
+ "regra de negocio em tool",
2880
+ "descricao da tool",
2881
+ "golden de tool",
2882
+ "refactor neutro",
2883
+ "migracao de teste"
2884
+ ],
2885
+ "anchors": {
2886
+ "fronteira": "#fronteira-com-os-outros-standards",
2887
+ "problema": "#o-problema",
2888
+ "padrao": "#o-padrão",
2889
+ "exemplo": "#exemplo-c-completo",
2890
+ "testes": "#os-testes-das-duas-camadas",
2891
+ "migracao": "#migrar-uma-tool-que-já-tem-a-regra-no-adaptador",
2892
+ "reais": "#exemplos-reais",
2893
+ "regras": "#regras"
2894
+ },
2895
+ "digest": "A tool that carries business rule keeps apart three things that change for different reasons: the RULE (sealed class XOps(...), primary constructor, explicit AddScoped; never *Service, which MORPH.md bans as a layer between handler and data), the sentence the MODEL reads, and the EFFECT a human sees. Each Ops method returns a typed outcome (abstract record XDesfecho, one sealed record per case); the model-facing text (description, refusal, self-correction, success, the ToolUnavailable decision) lives in the adapter, in public static object Render(XDesfecho), while human text delivered by code (task body, note, ack) stays in Ops because it is an effect. Checkable by grep: Ops names no tool and instructs no model. The adapter (AIFunctionFactory.Create) only builds the typed request, calls Ops and returns Render: zero rule, not a line count, and a long dynamic description stays byte for byte. Two test layers: Ops tests assert outcome, calls and order on the fake, never text; contract tests assert Render's exact literal and .Description, with a golden of name, description and schema per real tenant. A neutral refactor is proven before any test moves: a proof commit with the old suite untouched and green (offline evals included), then the migration, with mutation run only against the new tests. \"Already covered\" needs proof assertion by assertion (11 of 22 such claims had lost one); the tests left at the origin must be identical to the base; mutation on the new tests found rules the old suite never protected. The C# blocks were compiled against the pin and the three xunit tests run.",
2896
+ "verifiedAgainst": "Microsoft.Extensions.AI 10.9.0 + Microsoft.Agents.AI 1.20.0 (ai-pin 2026-09-08); os dois blocos C# abaixo foram extraídos com `scripts/extract-doc-csharp.mjs` e compilados contra o pin com `TreatWarningsAsErrors`, e os três testes do segundo bloco foram executados e passam. **A separação em si e a migração de teste são verificação documental:** vêm da feature `tools-finas` do MORPH_GHLBrain e o ai-kit não as traz.",
2897
+ "provedBy": []
2854
2898
  }
2855
2899
  ],
2856
2900
  "sharedAliases": {
@@ -132,7 +132,7 @@ não escolhe o histórico; escolher "chat com histórico" não escolhe as fases.
132
132
 
133
133
  ---
134
134
 
135
- ## Checklist (verifiable by morph-eval)
135
+ ## Checklist (verifiable in review)
136
136
 
137
137
  - [ ] O arquétipo escolhido está **nomeado** no `decisions.md` da feature, com a pergunta de
138
138
  `## Como escolher` que o decidiu
@@ -226,7 +226,7 @@ O histórico cresce a cada turno. Quando estoura o context window do modelo, as
226
226
 
227
227
  ---
228
228
 
229
- ## Checklist (verifiable by morph-eval)
229
+ ## Checklist (verifiable in review)
230
230
 
231
231
  - [ ] A escolha da fonte de histórico foi feita pela tabela de critério — e está escrita em `decisions.md` quando não foi a conversa própria
232
232
  - [ ] O provider de histórico é registrado como **uma** instância compartilhada
@@ -165,7 +165,7 @@ avisando para não commitar não é um mecanismo — é uma esperança.
165
165
 
166
166
  ---
167
167
 
168
- ## Checklist (verifiable by morph-eval)
168
+ ## Checklist (verifiable in review)
169
169
 
170
170
  - [ ] Existe exatamente **uma** `AgentSpec` por agente, e nenhum agente é construído inline
171
171
  - [ ] Nenhuma spec contém id de modelo — só `Alias`
@@ -192,7 +192,7 @@ if (batchDoc.TryGetProperty("error_file_id", out var errEl) && errEl.GetString()
192
192
 
193
193
  ---
194
194
 
195
- ## Checklist (verifiable by morph-eval)
195
+ ## Checklist (verifiable in review)
196
196
 
197
197
  - [ ] Batch é usado somente para prompts independentes, sem usuário aguardando resposta
198
198
  - [ ] O poll de status roda em background job (Worker/Hangfire), não em request HTTP
@@ -223,7 +223,7 @@ com `.UseAIContextProviders(...)` no `ChatClientBuilder` (`chatClient.AsBuilder(
223
223
 
224
224
  ---
225
225
 
226
- ## Checklist (verifiable by morph-eval)
226
+ ## Checklist (verifiable in review)
227
227
 
228
228
  - [ ] O provider herda da classe base abstrata `AIContextProvider` (não implementa uma interface genérica)
229
229
  - [ ] `ProvideAIContextAsync` é read-only — sem writes a banco ou estado global
@@ -202,7 +202,7 @@ A composição legítima — quando ela é mesmo necessária — é assunto de
202
202
 
203
203
  ---
204
204
 
205
- ## Checklist (verifiable by morph-eval)
205
+ ## Checklist (verifiable in review)
206
206
 
207
207
  - [ ] Existe **um** compositor de turno, puro e sem I/O, e nenhuma segunda montagem de prompt
208
208
  - [ ] O prompt é composto de blocos nomeados, e o texto enviado é derivado sem cache
@@ -225,7 +225,7 @@ mandado para lá. Nenhum dos dois duplica o outro.
225
225
 
226
226
  ---
227
227
 
228
- ## Checklist (verifiable by morph-eval)
228
+ ## Checklist (verifiable in review)
229
229
 
230
230
  - [ ] A conta de custo existe em **um** lugar; nenhum agente a repete
231
231
  - [ ] A tarifa mora por alias no registry, e a **data** dela está registrada FORA do objeto `pricing` (comentário JSONC, campo próprio na allowlist, ou arquivo de procedência) — a allowlist do exemplar tem exatamente 3 chaves e recusa uma quarta
@@ -246,7 +246,7 @@ This framework deploys to VPS/Coolify by default and does not adopt Azure as a d
246
246
 
247
247
  ---
248
248
 
249
- ## Checklist (verifiable by morph-eval)
249
+ ## Checklist (verifiable in review)
250
250
 
251
251
  - [ ] `ai-agents-workflows`' HITL or long-running criterion is documented in `decisions.md` before this standard is applied.
252
252
  - [ ] Every HITL wait point uses `RequestPort` + handles `RequestInfoEvent`.
@@ -186,7 +186,7 @@ primeira pergunta a fazer quando um guard "nunca reprova nada".
186
186
 
187
187
  ---
188
188
 
189
- ## Checklist (verifiable by morph-eval)
189
+ ## Checklist (verifiable in review)
190
190
 
191
191
  - [ ] Toda regra com consequência real existe como condição em código, não apenas no prompt
192
192
  - [ ] O choke-point escolhido está nomeado no `decisions.md`, com o que ele pega
@@ -197,7 +197,7 @@ explicando por quê.
197
197
 
198
198
  ---
199
199
 
200
- ## Checklist (verifiable by morph-eval)
200
+ ## Checklist (verifiable in review)
201
201
 
202
202
  - [ ] Nenhum loop de retry escrito à mão em volta de uma chamada de LLM
203
203
  - [ ] Há timeout explícito (por spec de agente, como o exemplar do kit, ou por alias se a allowlist foi aberta), e ele **não** é o `CancellationToken` do turno
@@ -318,7 +318,7 @@ prefira o tipo de instância resolvido por DI a métodos estáticos com estado g
318
318
 
319
319
  ---
320
320
 
321
- ## Checklist (verifiable by morph-eval)
321
+ ## Checklist (verifiable in review)
322
322
 
323
323
  - [ ] `ModelContextProtocol` e `Microsoft.Agents.AI` no `.csproj`; `ModelContextProtocol.AspNetCore` apenas se HTTP
324
324
  - [ ] Tools declaradas via `[McpServerToolType]` + `[McpServerTool]` (estáticas) ou `McpServerTool.Create(...)` (agente MAF / runtime)
@@ -220,7 +220,7 @@ AIAgent agent = _modelRegistry.GetChatClient("text-default")
220
220
 
221
221
  ---
222
222
 
223
- ## Checklist (verifiable by morph-eval)
223
+ ## Checklist (verifiable in review)
224
224
 
225
225
  - [ ] `ModelContextProtocol` presente no `.csproj` com versão exata (2.2.0 no pin) — sem faixa flutuante
226
226
  - [ ] `await using var mcpClient` — dispose correto do transporte
@@ -303,7 +303,7 @@ mais caro que um modelo com o dobro da tarifa e 90 %.
303
303
 
304
304
  ---
305
305
 
306
- ## Checklist (verifiable by morph-eval)
306
+ ## Checklist (verifiable in review)
307
307
 
308
308
  - [ ] Nenhum handler síncrono consegue nomear o tipo que produz bytes
309
309
  - [ ] Nenhum `await runner.RunAsync(...)` dentro de handler de turno — **o tipo não fecha esta
@@ -224,7 +224,7 @@ re-verificar diz qual página conferir. É falsificável em segundos, sem pesqui
224
224
 
225
225
  ---
226
226
 
227
- ## Checklist (verifiable by morph-eval)
227
+ ## Checklist (verifiable in review)
228
228
 
229
229
  - [ ] Nenhum código novo aponta para um alias de §Deprecações
230
230
  - [ ] O id da operação/tarefa é **persistido antes** do primeiro polling
@@ -215,7 +215,7 @@ Precisa de middleware no agent?
215
215
 
216
216
  ---
217
217
 
218
- ## Checklist (verifiable by morph-eval)
218
+ ## Checklist (verifiable in review)
219
219
 
220
220
  - [ ] Middleware registrado via `.AsBuilder().Use(...).Build()` — nunca depois de `Build()`
221
221
  - [ ] IChatClient middleware aplicado no `chatClient.AsBuilder()` antes de `.AsAIAgent()`
@@ -356,7 +356,7 @@ tem de cair **aqui**, no lugar que diz que ele morreu.
356
356
 
357
357
  ---
358
358
 
359
- ## Checklist (verifiable by morph-eval)
359
+ ## Checklist (verifiable in review)
360
360
 
361
361
  - [ ] O alias escolhido **não** está na tabela de §Deprecações
362
362
  - [ ] A chamada passa por `IImageGenerator` (ou adaptador próprio), sem acoplar o handler ao SDK
@@ -145,7 +145,7 @@ builder.Services.AddSingleton<TranscriptionService>();
145
145
 
146
146
  ---
147
147
 
148
- ## Checklist (verifiable by morph-eval)
148
+ ## Checklist (verifiable in review)
149
149
 
150
150
  - [ ] `AudioClient` injetado via DI — não instanciado inline
151
151
  - [ ] Áudio longo (>25MB) tratado com chunking antes de enviar ao provider
@@ -158,7 +158,7 @@ public class AudioController(TextToSpeechService tts) : ControllerBase
158
158
 
159
159
  ---
160
160
 
161
- ## Checklist (verifiable by morph-eval)
161
+ ## Checklist (verifiable in review)
162
162
 
163
163
  - [ ] `AudioClient` injetado via DI — não instanciado inline
164
164
  - [ ] Cache implementado para textos invariantes (não gera o mesmo áudio duas vezes)
@@ -166,7 +166,7 @@ string desc3 = await agent.AnalyzeImageBytesAsync(data, "image/png",
166
166
 
167
167
  ---
168
168
 
169
- ## Checklist (verifiable by morph-eval)
169
+ ## Checklist (verifiable in review)
170
170
 
171
171
  - [ ] Alias `"vision"` existe em `model-registry.json` e aponta para modelo com suporte a visão confirmado
172
172
  - [ ] `ChatMessage` usa `UriContent` para imagens por URL ou `DataContent` para bytes — nenhum encoding manual de base64 no código do agente
@@ -182,7 +182,7 @@ Tenho múltiplos agents — qual padrão usar?
182
182
 
183
183
  ---
184
184
 
185
- ## Checklist (verifiable by morph-eval)
185
+ ## Checklist (verifiable in review)
186
186
 
187
187
  - [ ] Foi verificado em `decisions.md` que single agent não resolve?
188
188
  - [ ] O padrão escolhido é o mais simples que atende ao requisito? (Tool < Sequential imperativo < Workflow)
@@ -298,7 +298,7 @@ auditável pela mesma via, são de `ai-agents-guardrails`.
298
298
  > requeridos — estão medidos na tabela **"Nomes de span, métricas e atributos — medidos"** acima, e
299
299
  > **não** são repetidos aqui: uma segunda lista dos mesmos nomes é a segunda verdade nascendo. A
300
300
  > régua de avaliação correspondente vive em
301
- > `.morph/framework/evals/proof-rubrics/observabilidade-genai.md`, e ela pergunta a **propriedade**
301
+ > `.morph/framework/evals/review-checklist.md` ("Feature que chama LLM"), e ela pergunta a **propriedade**
302
302
  > desta seção (dá para reconstruir o turno?), não a tecnologia — porque uma régua binária "tem span?"
303
303
  > daria a mesma nota a quem tem só a mensagem da exceção e a quem tem hash por bloco de prompt com
304
304
  > teste de fidelidade.
@@ -327,7 +327,7 @@ Workflow para diagnosticar um incidente relatado ("o agente X respondeu errado/l
327
327
 
328
328
  ---
329
329
 
330
- ## Checklist (verifiable by morph-eval)
330
+ ## Checklist (verifiable in review)
331
331
 
332
332
  - [ ] `AddSource` das **duas** fontes: `Experimental.Microsoft.Agents.AI` e `Experimental.Microsoft.Extensions.AI`
333
333
  - [ ] Nenhuma referência a `AgentOpenTelemetryConsts` ou `agent.WithOpenTelemetry()` (não existem no pin)
@@ -354,7 +354,7 @@ Workflow para diagnosticar um incidente relatado ("o agente X respondeu errado/l
354
354
  - `ai-agents-conversational-agent-with-phases` — o compositor de turno e a invariante "derivado sem cache" que torna o hash confiável
355
355
  - `ai-agents-testing-ai` — a metade de harness da rastreabilidade (captura do fake, prompt cru com opt-in)
356
356
  - `ai-agents-guardrails` — veredito ternário e escape registrado, auditáveis pela mesma telemetria
357
- - `.morph/framework/evals/proof-rubrics/observabilidade-genai.md` — a régua do Gate 3 para a propriedade desta seção
357
+ - `.morph/framework/evals/review-checklist.md` — a régua do Gate 3 para a propriedade desta seção
358
358
  - `infrastructure-docker-coolify-deploy` — Serilog/JSON console log para o pipeline de agregação em produção
359
359
  - Reference implementation (compila e conta spans contra o pin): `templates/dotnet/ai-kit/src/Morph.AiKit/Observability/MorphOpenTelemetryExtensions.cs` + `tests/Morph.AiKit.Tests/TelemetryTests.cs`
360
360
  - [OpenTelemetry Semantic Conventions for GenAI](https://opentelemetry.io/docs/specs/semconv/gen-ai/)
@@ -211,7 +211,7 @@ Na **1.18** (2026-08-18) essa superfície foi renomeada. Nomes atuais, medidos p
211
211
 
212
212
  ---
213
213
 
214
- ## Security Checklist (verifiable by morph-eval)
214
+ ## Security Checklist (verifiable in review)
215
215
 
216
216
  - [ ] API keys nunca em `appsettings.json` no repositório — bind de environment variables ou secret store
217
217
  - [ ] Variáveis de provider (`OpenAI__ApiKey`, `Google__ApiKey`, `Anthropic__ApiKey`) em env vars / Docker secrets
@@ -225,7 +225,7 @@ Na **1.18** (2026-08-18) essa superfície foi renomeada. Nomes atuais, medidos p
225
225
 
226
226
  ---
227
227
 
228
- ## Production Checklist (verifiable by morph-eval)
228
+ ## Production Checklist (verifiable in review)
229
229
 
230
230
  - [ ] `Microsoft.Agents.AI` **1.20.0** (versão exata, do `ai-pin.json`) no `.csproj`; nenhum pacote SK de orquestração
231
231
  - [ ] Nenhum `PackageReference` de SDK de IA com faixa flutuante; pacote fora do pin com versão exata + data de apuração
@@ -344,7 +344,7 @@ rastreabilidade (hash em span, prompt cru só em harness) está em `ai-agents-ob
344
344
 
345
345
  ---
346
346
 
347
- ## Checklist (verifiable by morph-eval)
347
+ ## Checklist (verifiable in review)
348
348
 
349
349
  - [ ] `agent_prompts` table exists with all required columns (`id`, `agent_key`, `version`, `content`, `is_active`, `created_at`)
350
350
  - [ ] Unique partial index `ix_agent_prompts_active` on `(agent_key) WHERE is_active` is present
@@ -265,7 +265,7 @@ When a task says "register the X agent" and the project has >1 model or >1 provi
265
265
 
266
266
  ---
267
267
 
268
- ## Checklist (verifiable by morph-eval)
268
+ ## Checklist (verifiable in review)
269
269
 
270
270
  - [ ] Project has `config/model-registry.json` (or declared equivalent), `version` `2.0`.
271
271
  - [ ] Project has a `ModelRegistry` class registered as singleton in DI.
@@ -281,7 +281,7 @@ ALTER TABLE kb_embeddings ENABLE ROW LEVEL SECURITY;
281
281
 
282
282
  ---
283
283
 
284
- ## Checklist (verifiable by morph-eval)
284
+ ## Checklist (verifiable in review)
285
285
 
286
286
  - [ ] EmbeddingService (concrete class) registered in DI; it injects IEmbeddingGenerator<string, Embedding<float>> for the project's chosen embedding model.
287
287
  - [ ] Embedding model declared in `model-registry.json` under the `embeddings` alias.
@@ -119,7 +119,7 @@ string responseText = result.Content[0].Text;
119
119
 
120
120
  ---
121
121
 
122
- ## Checklist (verifiable by morph-eval)
122
+ ## Checklist (verifiable in review)
123
123
 
124
124
  - [ ] Tier flex usado somente em jobs assíncronos (Worker Service / Hangfire), nunca em handlers de request HTTP síncrono
125
125
  - [ ] `ServiceTier` usa o valor tipado (`ChatServiceTier.Flex` / `ResponseServiceTier.Flex`), nunca uma string
@@ -346,7 +346,7 @@ AIAgent instrumented = agent.AsBuilder()
346
346
 
347
347
  ---
348
348
 
349
- ## 8. Checklist (verifiable by morph-eval)
349
+ ## 8. Checklist (verifiable in review)
350
350
 
351
351
  - [ ] `Microsoft.Agents.AI` package present in `.csproj`, com versão exata
352
352
  - [ ] No `Microsoft.SemanticKernel.*` orchestration references
@@ -254,7 +254,7 @@ public async Task<Result<ProposalDraft>> DraftValidatedAsync(string clientContex
254
254
 
255
255
  ---
256
256
 
257
- ## Checklist (verifiable by morph-eval)
257
+ ## Checklist (verifiable in review)
258
258
 
259
259
  - [ ] Todo agente que alimenta outro sistema (front-end, banco, pipeline, outro agente) usa `RunAsync<T>` ou `ResponseFormat` — nenhum retorna `response.Text` para parsing downstream.
260
260
  - [ ] O tipo de saída é um `sealed record` ou `sealed class` decorado com `[Description("...")]`.
@@ -103,7 +103,7 @@ You may need to step outside the sweet spot when:
103
103
 
104
104
  ---
105
105
 
106
- ## Checklist (verifiable by morph-eval)
106
+ ## Checklist (verifiable in review)
107
107
 
108
108
  - [ ] Was each agent designed as single-agent BEFORE reaching for multi-agent? (Check `decisions.md`.)
109
109
  - [ ] If a Workflow is used, is fan-in/out or HITL checkpointing genuinely present? Or could `foreach + LINQ` replace it?
@@ -201,7 +201,7 @@ mesmo padrão que este standard já contou como precedente ("treze arquivos, ~2.
201
201
 
202
202
  ---
203
203
 
204
- ## Checklist (verifiable by morph-eval)
204
+ ## Checklist (verifiable in review)
205
205
 
206
206
  - [ ] Existe um fake de `IChatClient` roteirizado, com captura de mensagens, opções e contagem
207
207
  - [ ] O fake **lança** quando a fila acaba