@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.
- package/CLAUDE.md +16 -13
- package/README.md +10 -10
- package/bin/morph-spec.js +10 -13
- package/bin/validate.js +379 -379
- package/claude-plugin.json +1 -1
- package/docs/CHEATSHEET.md +2 -4
- package/docs/QUICKSTART.md +6 -6
- package/framework/CLAUDE.md +6 -8
- package/framework/MORPH.md +39 -45
- package/framework/agents.json +8 -9
- package/framework/commands/morph-apply.md +1 -3
- package/framework/commands/morph-hotfix.md +1 -1
- package/framework/commands/morph-proposal.md +2 -2
- package/framework/docs/CLI.md +22 -17
- package/framework/evals/review-checklist.md +90 -0
- package/framework/evals/trace-schema.md +2 -12
- package/framework/hooks/README.md +2 -3
- package/framework/hooks/claude-code/core/heavy-gate.js +1 -1
- package/framework/hooks/claude-code/core/protect-spec-files.js +2 -2
- package/framework/hooks/claude-code/core/telemetry-log.js +2 -2
- package/framework/hooks/claude-code/core/trace-autogen.js +1 -22
- package/framework/hooks/claude-code/core/validate-completion.js +3 -56
- package/framework/hooks/claude-code/core/worktree-env-inject.js +1 -4
- package/framework/hooks/claude-code/statusline.sh +11 -11
- package/framework/hooks/git/commit-msg/conventional-commits.sh +33 -33
- package/framework/hooks/git/pre-commit/agents.sh +25 -25
- package/framework/hooks/git/pre-commit/orchestrator.sh +64 -64
- package/framework/hooks/git/pre-commit/specs.sh +50 -50
- package/framework/hooks/git/pre-push/run-tests.sh +44 -44
- package/framework/hooks/shared/build-check.js +1 -1
- package/framework/hooks/shared/comment-scanner.js +1 -1
- package/framework/hooks/shared/phase-utils.js +0 -5
- package/framework/hooks/shared/stdin-reader.js +26 -26
- package/framework/phases.json +4 -6
- package/framework/rubrics/backend.json +1 -1
- package/framework/rubrics/default.json +1 -1
- package/framework/rubrics/frontend.json +1 -1
- package/framework/rules/ai-agents-standards.md +1 -0
- package/framework/rules/morph-workflow.md +6 -6
- package/framework/schemas/feature.schema.json +2 -28
- package/framework/schemas/tasks.schema.json +6 -2
- package/framework/skills/README.md +1 -2
- package/framework/skills/core/create-umbraco-lp/SKILL.md +1 -1
- package/framework/skills/core/migrate-lp-to-umbraco/SKILL.md +1 -1
- package/framework/skills/core/morph-apply/SKILL.md +145 -246
- package/framework/skills/core/morph-brainstorming/SKILL.md +1 -1
- package/framework/skills/core/morph-hotfix/SKILL.md +5 -3
- package/framework/skills/core/morph-implement/SKILL.md +101 -201
- package/framework/skills/core/morph-machine/SKILL.md +3 -3
- package/framework/skills/core/morph-media/SKILL.md +1 -1
- package/framework/skills/core/morph-plan/SKILL.md +171 -287
- package/framework/skills/core/morph-proposal/SKILL.md +4 -5
- package/framework/skills/core/morph-review/SKILL.md +109 -430
- package/framework/skills/core/morph-stack-scan/SKILL.md +1 -1
- package/framework/skills/core/morph-standards/SKILL.md +2 -2
- package/framework/skills/core/morph-uiux/SKILL.md +2 -3
- package/framework/standards/STANDARDS.json +54 -10
- package/framework/standards/ai-agents/agent-archetypes.md +1 -1
- package/framework/standards/ai-agents/agent-session.md +1 -1
- package/framework/standards/ai-agents/agent-spec.md +1 -1
- package/framework/standards/ai-agents/batching.md +1 -1
- package/framework/standards/ai-agents/context-providers.md +1 -1
- package/framework/standards/ai-agents/conversational-agent-with-phases.md +1 -1
- package/framework/standards/ai-agents/cost-and-budget.md +1 -1
- package/framework/standards/ai-agents/durable-workflows-hitl.md +1 -1
- package/framework/standards/ai-agents/guardrails.md +1 -1
- package/framework/standards/ai-agents/llm-runtime-defaults.md +1 -1
- package/framework/standards/ai-agents/mcp-server.md +1 -1
- package/framework/standards/ai-agents/mcp-tools.md +1 -1
- package/framework/standards/ai-agents/media-pipeline.md +1 -1
- package/framework/standards/ai-agents/media-video.md +1 -1
- package/framework/standards/ai-agents/middleware-patterns.md +1 -1
- package/framework/standards/ai-agents/modalities-image-gen.md +1 -1
- package/framework/standards/ai-agents/modalities-speech-to-text.md +1 -1
- package/framework/standards/ai-agents/modalities-text-to-speech.md +1 -1
- package/framework/standards/ai-agents/modalities-vision.md +1 -1
- package/framework/standards/ai-agents/multi-agent-patterns.md +1 -1
- package/framework/standards/ai-agents/observability-patterns.md +3 -3
- package/framework/standards/ai-agents/production.md +2 -2
- package/framework/standards/ai-agents/prompt-sources.md +1 -1
- package/framework/standards/ai-agents/providers/model-registry.md +1 -1
- package/framework/standards/ai-agents/rag-custom-pgvector.md +1 -1
- package/framework/standards/ai-agents/service-tier-flex.md +1 -1
- package/framework/standards/ai-agents/setup.md +1 -1
- package/framework/standards/ai-agents/structured-output.md +1 -1
- package/framework/standards/ai-agents/sweet-spot.md +1 -1
- package/framework/standards/ai-agents/testing-ai.md +1 -1
- package/framework/standards/ai-agents/tool-adapters.md +226 -0
- package/framework/standards/ai-agents/vector-data-extensions.md +1 -1
- package/framework/standards/ai-agents/workflows.md +1 -1
- package/framework/standards/infrastructure/docker/local-compose-isolation.md +11 -1
- package/framework/templates/CLAUDE.md.core.template +1 -1
- package/framework/templates/IDE-SNIPPETS.md +262 -262
- package/framework/templates/README.md +1 -1
- package/framework/templates/REGISTRY.json +0 -81
- package/framework/templates/code/dotnet/abstractions/api-endpoint.cs +7 -7
- package/framework/templates/code/dotnet/feature/endpoint.cs.hbs +21 -21
- package/framework/templates/code/dotnet/feature/request.cs.hbs +4 -4
- package/framework/templates/code/dotnet/feature/response.cs.hbs +4 -4
- package/framework/templates/code/sql/ai-agents/pgvector-embeddings-migration.sql.template +91 -91
- package/framework/templates/docs/spec.md +19 -205
- package/framework/templates/docs/ui-components.md +52 -52
- package/framework/templates/docs/ui-design-system.md +76 -76
- package/framework/templates/docs/ui-flows.md +167 -167
- package/framework/templates/frontend/nextjs/client-component.tsx.hbs +26 -26
- package/framework/templates/frontend/nextjs/feature-form.tsx.hbs +56 -56
- package/framework/templates/frontend/nextjs/tsconfig.json.hbs +26 -26
- package/framework/templates/infrastructure/docker/Dockerfile.template +58 -58
- package/framework/templates/infrastructure/docker/dockerfile-api.dockerfile +38 -38
- package/framework/templates/infrastructure/docker/dockerfile-web.dockerfile +48 -48
- package/framework/templates/infrastructure/github/README.md +56 -56
- package/framework/templates/infrastructure/github/actions/docker-build-push/action.yml.hbs +45 -45
- package/framework/templates/infrastructure/github/actions/health-check/action.yml.hbs +27 -27
- package/framework/templates/infrastructure/github/workflows/docker-build-push.yml.hbs +59 -59
- package/framework/templates/infrastructure/github/workflows/dotnet-build.yml.hbs +39 -39
- package/framework/templates/meta-prompts/fusion/fusion-agent.md +76 -76
- package/framework/templates/meta-prompts/fusion/fusion-aggregator.md +100 -100
- package/framework/templates/meta-prompts/validators/pre-commit-validator.md +95 -95
- package/framework/templates/state.template.json +17 -17
- package/framework/templates/ui/design-system.css +226 -226
- package/package.json +2 -2
- package/src/commands/e2e/e2e.js +1 -1
- package/src/commands/project/heavy.js +1 -1
- package/src/commands/project/status.js +3 -3
- package/src/commands/project/worktree.js +34 -16
- package/src/commands/state/approve.js +9 -50
- package/src/commands/state/finish.js +4 -0
- package/src/commands/state/gate-check.js +18 -107
- package/src/commands/state/gate-decision.js +1 -1
- package/src/commands/state/report-check.js +42 -17
- package/src/commands/validation/mutate.js +1 -1
- package/src/commands/validation/scout-check.js +28 -0
- package/src/commands/validation/validate-feature.js +5 -32
- package/src/commands/validation/verify.js +16 -25
- package/src/core/paths/output-schema.js +0 -2
- package/src/core/state/state-manager.js +1 -2
- package/src/core/templates/template-renderer.js +477 -477
- package/src/dashboard/app/lib/format.js +5 -0
- package/src/dashboard/app/main.jsx +13 -13
- package/src/dashboard/app/pages/FeatureDetail.jsx +16 -22
- package/src/dashboard/app/pages/Features.jsx +7 -7
- package/src/dashboard/app/pages/PhasePipeline.jsx +1 -1
- package/src/dashboard/app/pages/Rubrics.jsx +7 -11
- package/src/dashboard/scanner/docs-scanner.js +1 -2
- package/src/dashboard/scanner/features-scanner.js +3 -4
- package/src/dashboard/scanner/rubrics-scanner.js +12 -12
- package/src/dashboard/vite.config.js +24 -24
- package/src/lib/agents/output-collector.js +0 -1
- package/src/lib/detectors/design-system-detector.js +188 -188
- package/src/lib/e2e/compose-env.js +5 -2
- package/src/lib/evaluator-report.js +52 -334
- package/src/lib/generators/design-system-generator.js +508 -508
- package/src/lib/generators/handoff-generator.js +4 -5
- package/src/lib/git/evidence-staleness.js +39 -0
- package/src/lib/installers/memory-installer.js +2 -2
- package/src/lib/mutation/manifest.js +8 -2
- package/src/lib/mutation/report.js +5 -3
- package/src/lib/mutation/runner.js +9 -7
- package/src/lib/risk-detector.js +63 -125
- package/src/lib/scout/scout-check.js +293 -0
- package/src/lib/tasks/eval-node.js +4 -34
- package/src/lib/tasks/task-classifier.js +30 -30
- package/src/lib/tasks/task-parser.js +209 -209
- package/src/lib/tasks/tasks-json-parser.js +7 -5
- package/src/lib/tasks/test-nodes.js +1 -1
- package/src/lib/tasks/test-runner.js +1 -1
- package/src/lib/validators/contracts/contract-compliance-validator.js +4 -42
- package/src/lib/validators/css/css-validator.js +340 -340
- package/src/lib/validators/reuse/reuse-validator.js +6 -8
- package/src/lib/validators/verify-runner.js +1 -1
- package/src/lib/worktree/env-allocator.js +35 -5
- package/src/scripts/setup-infra.js +1 -1
- package/src/utils/agent-id-mapper.js +11 -11
- package/src/utils/agents-installer.js +5 -9
- package/src/utils/claude-settings-manager.js +300 -300
- package/src/utils/hooks-installer.js +3 -10
- package/src/utils/skills-installer.js +1 -1
- package/framework/evals/proof-rubrics/README.md +0 -76
- package/framework/evals/proof-rubrics/eval-de-modelo.md +0 -80
- package/framework/evals/proof-rubrics/fiacao.md +0 -54
- package/framework/evals/proof-rubrics/guard-cego.md +0 -52
- package/framework/evals/proof-rubrics/media-claims.md +0 -109
- package/framework/evals/proof-rubrics/mutation-proof.md +0 -107
- package/framework/evals/proof-rubrics/observabilidade-genai.md +0 -119
- package/framework/evals/proof-rubrics/verde-nao-e-coberto.md +0 -48
- package/framework/evals/rubrics/README.md +0 -45
- package/framework/evals/rubrics/architecture.md +0 -103
- package/framework/evals/rubrics/code-quality.md +0 -98
- package/framework/evals/rubrics/condensed.md +0 -57
- package/framework/evals/rubrics/contracts.md +0 -67
- package/framework/evals/rubrics/test-coverage.md +0 -99
- package/framework/evals/scenarios/dotnet-crud.yaml +0 -42
- package/framework/evals/scenarios/nextjs-auth.yaml +0 -38
- package/framework/evals/suites/standard.yaml +0 -5
- package/framework/hooks/claude-code/core/post-edit-typecheck.js +0 -127
- package/framework/skills/core/morph-eval/SKILL.md +0 -64
- package/framework/templates/.idea/morph-templates.xml +0 -92
- package/framework/templates/.vscode/morph-templates.code-snippets +0 -186
- package/framework/templates/docs/clarifications.md +0 -253
- package/framework/templates/docs/onboarding.md +0 -122
- package/framework/templates/docs/schema-analysis.md +0 -119
- package/framework/templates/docs/user-stories.md +0 -34
- 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.
|
|
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
|
|
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.
|
|
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)
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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/
|
|
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-
|
|
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-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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/
|
|
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
|
|
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/
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|