@polymorphism-tech/morph-spec 9.0.0 → 9.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (304) hide show
  1. package/CLAUDE.md +8 -9
  2. package/README.md +38 -36
  3. package/bin/morph-spec.js +4 -62
  4. package/bin/validate.js +1 -39
  5. package/claude-plugin.json +1 -1
  6. package/docs/CHEATSHEET.md +1 -1
  7. package/docs/QUICKSTART.md +1 -1
  8. package/framework/CLAUDE.md +1 -1
  9. package/framework/MORPH.md +1 -1
  10. package/framework/agents.json +12 -4
  11. package/framework/commands/morph-apply.md +1 -1
  12. package/framework/commands/morph-status.md +1 -1
  13. package/framework/docs/CLI.md +6 -17
  14. package/framework/hooks/claude-code/core/block-destructive-worktree-removal.js +6 -49
  15. package/framework/hooks/claude-code/core/block-raw-worktree-add.js +2 -35
  16. package/framework/hooks/claude-code/core/chain.js +4 -65
  17. package/framework/hooks/claude-code/core/comment-guard.js +2 -16
  18. package/framework/hooks/claude-code/core/enforce-phase-writes.js +6 -50
  19. package/framework/hooks/claude-code/core/gate-guard.js +7 -67
  20. package/framework/hooks/claude-code/core/graph-refresh-kick.js +3 -24
  21. package/framework/hooks/claude-code/core/heavy-gate.js +3 -21
  22. package/framework/hooks/claude-code/core/heavy-release.js +2 -13
  23. package/framework/hooks/claude-code/core/loop-detect.js +2 -31
  24. package/framework/hooks/claude-code/core/pre-bash-denylist.js +0 -4
  25. package/framework/hooks/claude-code/core/protect-spec-files.js +7 -67
  26. package/framework/hooks/claude-code/core/state-sync.js +11 -67
  27. package/framework/hooks/claude-code/core/telemetry-log.js +12 -93
  28. package/framework/hooks/claude-code/core/validate-completion.js +11 -57
  29. package/framework/hooks/claude-code/core/warn-bash-source-write.js +1 -9
  30. package/framework/hooks/claude-code/core/worktree-context.js +10 -110
  31. package/framework/hooks/claude-code/core/worktree-create.js +6 -70
  32. package/framework/hooks/claude-code/core/worktree-env-inject.js +5 -56
  33. package/framework/hooks/claude-code/core/worktree-remove.js +5 -31
  34. package/framework/hooks/shared/activity-logger.js +9 -89
  35. package/framework/hooks/shared/agent-reap.js +2 -17
  36. package/framework/hooks/shared/build-check.js +6 -75
  37. package/framework/hooks/shared/claim-registry.js +9 -119
  38. package/framework/hooks/shared/command-tokens.js +6 -51
  39. package/framework/hooks/shared/comment-rules.js +5 -20
  40. package/framework/hooks/shared/comment-scanner.js +6 -25
  41. package/framework/hooks/shared/comment-stripper.js +11 -85
  42. package/framework/hooks/shared/e2e-check.js +0 -0
  43. package/framework/hooks/shared/errata.js +2 -15
  44. package/framework/hooks/shared/feature-locator.js +11 -95
  45. package/framework/hooks/shared/frontend-locations.js +1 -3
  46. package/framework/hooks/shared/gate-question.js +1 -7
  47. package/framework/hooks/shared/git-exclude.js +3 -20
  48. package/framework/hooks/shared/git-paths.js +8 -104
  49. package/framework/hooks/shared/graph-freshness.js +22 -166
  50. package/framework/hooks/shared/graph-refresh.js +21 -149
  51. package/framework/hooks/shared/heavy-command.js +4 -12
  52. package/framework/hooks/shared/hook-response.js +8 -83
  53. package/framework/hooks/shared/morph-cli.js +8 -52
  54. package/framework/hooks/shared/payload-utils.js +10 -132
  55. package/framework/hooks/shared/phase-utils.js +1 -42
  56. package/framework/hooks/shared/redact-secrets.js +4 -15
  57. package/framework/hooks/shared/reparse-scan.js +6 -66
  58. package/framework/hooks/shared/slice-progress.js +4 -23
  59. package/framework/hooks/shared/source-files.js +4 -17
  60. package/framework/hooks/shared/state-reader.js +13 -183
  61. package/framework/hooks/shared/state-writer.js +8 -52
  62. package/framework/hooks/shared/stdin-reader.js +1 -11
  63. package/framework/hooks/shared/telemetry-logger.js +7 -67
  64. package/framework/hooks/shared/transcript-usage.js +7 -29
  65. package/framework/hooks/shared/worktree-root.js +7 -29
  66. package/framework/rules/csharp-standards.md +1 -1
  67. package/framework/rules/frontend-standards.md +1 -0
  68. package/framework/rules/hangfire-standards.md +1 -1
  69. package/framework/rules/neon-standards.md +1 -1
  70. package/framework/skills/core/create-umbraco-lp/SKILL.md +1 -1
  71. package/framework/skills/core/migrate-lp-to-umbraco/SKILL.md +1 -1
  72. package/framework/skills/core/morph-apply/SKILL.md +2 -2
  73. package/framework/skills/core/morph-hotfix/SKILL.md +1 -1
  74. package/framework/skills/core/morph-machine/SKILL.md +1 -1
  75. package/framework/skills/core/morph-media/SKILL.md +1 -1
  76. package/framework/skills/core/morph-plan/SKILL.md +2 -2
  77. package/framework/skills/core/morph-review/SKILL.md +1 -1
  78. package/framework/skills/core/morph-standards/SKILL.md +1 -1
  79. package/framework/skills/core/morph-uiux/SKILL.md +29 -12
  80. package/framework/standards/STANDARDS.json +34 -12
  81. package/framework/standards/STANDARDS.meta.json +16 -2
  82. package/framework/standards/ai-agents/agent-archetypes.md +2 -2
  83. package/framework/standards/ai-agents/agent-session.md +1 -1
  84. package/framework/standards/ai-agents/conversational-agent-with-phases.md +4 -4
  85. package/framework/standards/ai-agents/durable-workflows-hitl.md +3 -3
  86. package/framework/standards/ai-agents/guardrails.md +1 -1
  87. package/framework/standards/ai-agents/multi-agent-patterns.md +2 -2
  88. package/framework/standards/ai-agents/observability-patterns.md +1 -1
  89. package/framework/standards/ai-agents/production.md +1 -1
  90. package/framework/standards/ai-agents/prompt-sources.md +2 -2
  91. package/framework/standards/ai-agents/providers/model-registry.md +1 -1
  92. package/framework/standards/ai-agents/rag-custom-pgvector.md +2 -2
  93. package/framework/standards/ai-agents/setup.md +2 -2
  94. package/framework/standards/ai-agents/sweet-spot.md +2 -2
  95. package/framework/standards/ai-agents/tool-adapters.md +0 -2
  96. package/framework/standards/ai-agents/vector-data-extensions.md +4 -4
  97. package/framework/standards/ai-agents/workflows.md +1 -1
  98. package/framework/standards/architecture/code-comments.md +1 -1
  99. package/framework/standards/architecture/vertical-slice/vertical-slice.md +1 -1
  100. package/framework/standards/backend/api/validation.md +1 -1
  101. package/framework/standards/backend/dotnet/vsa-handler-patterns.md +5 -5
  102. package/framework/standards/backend/integrations/hangfire/hangfire-jobs.md +1 -1
  103. package/framework/standards/backend/integrations/neon-auth/neon-auth.md +2 -2
  104. package/framework/standards/data/nosql/cache/redis.md +1 -1
  105. package/framework/standards/data/nosql/cosmos-db.md +3 -3
  106. package/framework/standards/frontend/admin-app/forms.md +1 -1
  107. package/framework/standards/frontend/design-system/art-direction.md +88 -0
  108. package/framework/standards/frontend/design-system/premium-finish.md +77 -2
  109. package/framework/standards/infrastructure/neon/neon-pgvector.md +5 -5
  110. package/framework/templates/CLAUDE.md.core.template +3 -3
  111. package/framework/templates/REGISTRY.json +9 -9
  112. package/framework/templates/docs/ui-mockups.md +4 -0
  113. package/package.json +1 -1
  114. package/src/commands/context/context-refresh.js +0 -16
  115. package/src/commands/dashboard/dashboard.js +2 -8
  116. package/src/commands/e2e/e2e.js +17 -104
  117. package/src/commands/graph/affected.js +0 -14
  118. package/src/commands/graph/build.js +11 -50
  119. package/src/commands/graph/explain.js +0 -16
  120. package/src/commands/graph/status.js +1 -12
  121. package/src/commands/mcp/mcp-setup.js +4 -62
  122. package/src/commands/observability/cost.js +5 -57
  123. package/src/commands/observability/telemetry.js +1 -14
  124. package/src/commands/project/branch.js +4 -45
  125. package/src/commands/project/claim.js +4 -48
  126. package/src/commands/project/doctor.js +48 -302
  127. package/src/commands/project/env.js +1 -27
  128. package/src/commands/project/fleet.js +3 -32
  129. package/src/commands/project/init.js +4 -68
  130. package/src/commands/project/install-plugin-cmd.js +0 -1
  131. package/src/commands/project/standards.js +1 -62
  132. package/src/commands/project/status.js +0 -53
  133. package/src/commands/project/update.js +31 -239
  134. package/src/commands/project/worktree.js +108 -882
  135. package/src/commands/scaffold/scaffold.js +0 -25
  136. package/src/commands/state/advance.js +14 -85
  137. package/src/commands/state/approve.js +14 -96
  138. package/src/commands/state/archive.js +12 -64
  139. package/src/commands/state/auto-approval.js +2 -5
  140. package/src/commands/state/create.js +22 -109
  141. package/src/commands/state/delete.js +11 -63
  142. package/src/commands/state/finish.js +98 -475
  143. package/src/commands/state/gate-check.js +22 -132
  144. package/src/commands/state/gate-decision.js +3 -39
  145. package/src/commands/state/handoff.js +3 -30
  146. package/src/commands/state/list.js +14 -84
  147. package/src/commands/state/report-check.js +8 -58
  148. package/src/commands/state/retype.js +4 -26
  149. package/src/commands/validation/index.js +0 -3
  150. package/src/commands/validation/mutate.js +2 -5
  151. package/src/commands/validation/validate-feature.js +5 -94
  152. package/src/commands/validation/verify.js +15 -98
  153. package/src/core/paths/output-schema.js +2 -101
  154. package/src/core/state/feature-identity.js +1 -25
  155. package/src/core/state/gate-order.js +0 -27
  156. package/src/core/state/lifecycle-audit.js +8 -100
  157. package/src/core/state/state-manager.js +22 -304
  158. package/src/core/templates/template-registry.js +2 -97
  159. package/src/core/templates/template-renderer.js +13 -93
  160. package/src/core/templates/template-seed.js +0 -1
  161. package/src/core/work-types.js +1 -36
  162. package/src/dashboard/app/App.jsx +1 -8
  163. package/src/dashboard/app/components/ActivityFeed.jsx +0 -5
  164. package/src/dashboard/app/components/CommandPalette.jsx +0 -7
  165. package/src/dashboard/app/components/DetailPanel.jsx +1 -5
  166. package/src/dashboard/app/components/EntityLink.jsx +0 -12
  167. package/src/dashboard/app/components/ErrorBoundary.jsx +1 -8
  168. package/src/dashboard/app/components/KnowledgeMarkdown.jsx +0 -11
  169. package/src/dashboard/app/components/Markdown.jsx +0 -9
  170. package/src/dashboard/app/components/PhaseRail.jsx +0 -11
  171. package/src/dashboard/app/components/SearchFilter.jsx +0 -4
  172. package/src/dashboard/app/components/Sidebar.jsx +0 -5
  173. package/src/dashboard/app/hooks/useMorphQuery.js +1 -11
  174. package/src/dashboard/app/hooks/usePref.js +1 -5
  175. package/src/dashboard/app/lib/format.js +0 -2
  176. package/src/dashboard/app/lib/phases.js +1 -5
  177. package/src/dashboard/app/lib/project.js +0 -12
  178. package/src/dashboard/app/pages/AgentMap.jsx +1 -8
  179. package/src/dashboard/app/pages/FeatureDetail.jsx +1 -5
  180. package/src/dashboard/app/pages/Features.jsx +1 -8
  181. package/src/dashboard/app/pages/Guide.jsx +0 -1
  182. package/src/dashboard/app/pages/HookInspector.jsx +2 -23
  183. package/src/dashboard/app/pages/PhasePipeline.jsx +0 -3
  184. package/src/dashboard/app/pages/Portfolio.jsx +0 -1
  185. package/src/dashboard/app/pages/RulesMap.jsx +1 -16
  186. package/src/dashboard/app/pages/SkillsLibrary.jsx +1 -16
  187. package/src/dashboard/app/pages/Standards.jsx +2 -17
  188. package/src/dashboard/scanner/activity-scanner.js +10 -69
  189. package/src/dashboard/scanner/agents-scanner.js +1 -23
  190. package/src/dashboard/scanner/docs-scanner.js +0 -6
  191. package/src/dashboard/scanner/feature-status.js +2 -5
  192. package/src/dashboard/scanner/features-scanner.js +10 -66
  193. package/src/dashboard/scanner/hooks-scanner.js +5 -28
  194. package/src/dashboard/scanner/index.js +0 -4
  195. package/src/dashboard/scanner/portfolio.js +5 -29
  196. package/src/dashboard/scanner/project-api.js +8 -54
  197. package/src/dashboard/scanner/rules-scanner.js +1 -2
  198. package/src/dashboard/scanner/skills-scanner.js +2 -12
  199. package/src/dashboard/scanner/standards-scanner.js +2 -6
  200. package/src/dashboard/vite-plugin-morph-data.js +5 -19
  201. package/src/lib/ai/ai-checks.js +7 -52
  202. package/src/lib/ai/ai-project-scan.js +14 -108
  203. package/src/lib/ai/code-audit.js +7 -63
  204. package/src/lib/ai/pin-drift.js +8 -51
  205. package/src/lib/ai/registry-audit.js +11 -90
  206. package/src/lib/ci/ci-verify.js +4 -19
  207. package/src/lib/ci/github-ci.js +9 -37
  208. package/src/lib/ci/workflow-scaffold.js +2 -10
  209. package/src/lib/detectors/claude-config-detector.js +13 -74
  210. package/src/lib/detectors/index.js +4 -50
  211. package/src/lib/e2e/compose-env.js +5 -66
  212. package/src/lib/e2e/stack-teardown.js +6 -40
  213. package/src/lib/generators/architecture-scanner.js +18 -156
  214. package/src/lib/generators/handoff-generator.js +9 -53
  215. package/src/lib/generators/scaffold-generator.js +5 -101
  216. package/src/lib/generators/settings-generator.js +4 -37
  217. package/src/lib/git/branch-classifier.js +11 -84
  218. package/src/lib/git/default-branch.js +14 -169
  219. package/src/lib/git/evidence-staleness.js +1 -0
  220. package/src/lib/git/gh.js +2 -17
  221. package/src/lib/git/pending-prs.js +6 -37
  222. package/src/lib/git/pr-files.js +3 -28
  223. package/src/lib/git/pr-index.js +3 -34
  224. package/src/lib/git/tree-fingerprint.js +3 -15
  225. package/src/lib/git/tree-state.js +6 -33
  226. package/src/lib/graph/god-nodes.js +2 -22
  227. package/src/lib/graph/graph-health.js +3 -24
  228. package/src/lib/graph/graph-loader.js +5 -56
  229. package/src/lib/graph/graphify-runtime.js +7 -37
  230. package/src/lib/graph/graphifyignore.js +8 -74
  231. package/src/lib/graph/sanitize.js +16 -136
  232. package/src/lib/heavy/cleanup.js +1 -1
  233. package/src/lib/installers/effects.js +8 -93
  234. package/src/lib/installers/mcp-installer.js +9 -169
  235. package/src/lib/installers/memory-installer.js +4 -27
  236. package/src/lib/installers/templates-reconcile.js +5 -60
  237. package/src/lib/mutation/dotnet-introspection.js +20 -106
  238. package/src/lib/mutation/subset.js +1 -4
  239. package/src/lib/plan/artifact-vocabulary.js +5 -25
  240. package/src/lib/plan/checks.js +5 -31
  241. package/src/lib/plan/plan-parser.js +1 -6
  242. package/src/lib/projects/registry.js +7 -44
  243. package/src/lib/review-reports.js +5 -23
  244. package/src/lib/risk-detector.js +39 -173
  245. package/src/lib/specs/adr-index.js +6 -34
  246. package/src/lib/specs/frontmatter.js +2 -15
  247. package/src/lib/specs/gfm-table.js +1 -7
  248. package/src/lib/specs/revocations.js +1 -14
  249. package/src/lib/specs/screen-checklist.js +47 -124
  250. package/src/lib/stack/dotnet-build-ignores.js +2 -6
  251. package/src/lib/stack/stack-profile.js +1 -28
  252. package/src/lib/stack/stack-scan.js +1 -8
  253. package/src/lib/stack-filter.js +4 -27
  254. package/src/lib/standards/registry.js +1 -7
  255. package/src/lib/standards/sections.js +2 -13
  256. package/src/lib/standards/verified-against.js +19 -191
  257. package/src/lib/tasks/eval-node.js +21 -169
  258. package/src/lib/tasks/linux-runner.js +18 -142
  259. package/src/lib/tasks/test-nodes.js +43 -240
  260. package/src/lib/tasks/test-runner.js +43 -341
  261. package/src/lib/telemetry/metrics.js +7 -36
  262. package/src/lib/telemetry/telemetry-reader.js +13 -125
  263. package/src/lib/telemetry/verify-event.js +2 -30
  264. package/src/lib/validators/code-budget/code-budget-validator.js +3 -43
  265. package/src/lib/validators/code-budget/index.js +0 -7
  266. package/src/lib/validators/contracts/contract-compliance-validator.js +2 -24
  267. package/src/lib/validators/contracts/index.js +0 -6
  268. package/src/lib/validators/nextjs/index.js +0 -5
  269. package/src/lib/validators/nextjs/next-component-validator.js +4 -81
  270. package/src/lib/validators/packages/index.js +0 -6
  271. package/src/lib/validators/packages/package-validator.js +6 -56
  272. package/src/lib/validators/reuse/index.js +0 -8
  273. package/src/lib/validators/reuse/reuse-validator.js +11 -101
  274. package/src/lib/validators/reuse/symbol-scanner.js +6 -62
  275. package/src/lib/validators/traceability-check.js +5 -63
  276. package/src/lib/validators/validation-runner.js +20 -125
  277. package/src/lib/validators/verify-runner.js +52 -358
  278. package/src/lib/work-type-detector.js +5 -67
  279. package/src/lib/worktree/docker-audit.js +17 -136
  280. package/src/lib/worktree/env-allocator.js +10 -98
  281. package/src/lib/worktree/feature-truth.js +12 -115
  282. package/src/lib/worktree/finish-backup.js +32 -242
  283. package/src/lib/worktree/fleet-scanner.js +13 -95
  284. package/src/lib/worktree/ignored-triage.js +15 -91
  285. package/src/lib/worktree/vscode-settings.js +2 -3
  286. package/src/lib/worktree/worktree-audit.js +21 -213
  287. package/src/lib/worktree/worktree-include.js +3 -5
  288. package/src/scripts/global-install.js +3 -9
  289. package/src/scripts/install-plugin.js +1 -13
  290. package/src/scripts/setup-infra.js +17 -147
  291. package/src/utils/agents-installer.js +28 -275
  292. package/src/utils/banner.js +4 -25
  293. package/src/utils/claude-md-injector.js +1 -37
  294. package/src/utils/claude-settings-manager.js +1 -52
  295. package/src/utils/file-copier.js +11 -95
  296. package/src/utils/hooks-installer.js +21 -298
  297. package/src/utils/skills-installer.js +4 -101
  298. package/src/utils/version-checker.js +4 -83
  299. package/framework/commands/morph-proposal.md +0 -9
  300. package/src/commands/utils/index.js +0 -3
  301. package/src/lib/detectors/design-system-detector.js +0 -188
  302. package/src/lib/generators/design-system-generator.js +0 -508
  303. package/src/lib/specs/old-format.js +0 -68
  304. package/src/utils/agent-id-mapper.js +0 -11
@@ -226,7 +226,7 @@ public sealed class PostgresCheckpointStore(NpgsqlDataSource dataSource) : IChec
226
226
 
227
227
  `Microsoft.Agents.AI.DurableTask` (prerelease) adds durability backed by the **Azure Durable Task Scheduler**, including cost-efficient multi-day HITL waits with zero compute cost while paused. Even its "bring-your-own-compute / self-hosted" mode still requires a Durable Task Scheduler backend (`Microsoft.DurableTask.*.AzureManaged` packages) — self-hosted means your own worker process, not an Azure-free backend.
228
228
 
229
- This framework deploys to VPS/Coolify by default and does not adopt Azure as a default dependency (see `ai-agents-setup` §3.4 on Azure OpenAI). For that reason, `Microsoft.Agents.AI.DurableTask` is **not adopted as default** here. The `CheckpointManager` + custom `ICheckpointStore` pattern above covers the same durability need without an Azure dependency. Only reach for the Durable Task extension when a specific client already runs on Azure and needs multi-day/serverless HITL waits — record that decision in `decisions.md`.
229
+ This framework deploys to VPS/Coolify by default and does not adopt Azure as a default dependency (see `ai-agents-setup` §3.4 on Azure OpenAI). For that reason, `Microsoft.Agents.AI.DurableTask` is **not adopted as default** here. The `CheckpointManager` + custom `ICheckpointStore` pattern above covers the same durability need without an Azure dependency. Only reach for the Durable Task extension when a specific client already runs on Azure and needs multi-day/serverless HITL waits — record that decision in `plan.md` (`## Decisões`).
230
230
 
231
231
  ---
232
232
 
@@ -248,12 +248,12 @@ This framework deploys to VPS/Coolify by default and does not adopt Azure as a d
248
248
 
249
249
  ## Checklist (verifiable in review)
250
250
 
251
- - [ ] `ai-agents-workflows`' HITL or long-running criterion is documented in `decisions.md` before this standard is applied.
251
+ - [ ] `ai-agents-workflows`' HITL or long-running criterion is documented in `plan.md` (`## Decisões`) before this standard is applied.
252
252
  - [ ] Every HITL wait point uses `RequestPort` + handles `RequestInfoEvent`.
253
253
  - [ ] A `CheckpointManager` is wired whenever the workflow can pause across a process restart — `CreateInMemory()` is acceptable only for tests/demos.
254
254
  - [ ] If a custom `ICheckpointStore` was implemented, it persists to infrastructure already owned by the project (e.g., Neon Postgres), not a new ad hoc store.
255
255
  - [ ] Executors with instance state implement `OnCheckpointingAsync` and `OnCheckpointRestoredAsync`.
256
- - [ ] `Microsoft.Agents.AI.DurableTask` is present only if the project already runs on Azure and the choice is recorded in `decisions.md` — ciente de que, desde a 1.17, o pacote vive em repositório separado e ficou para trás do framework.
256
+ - [ ] `Microsoft.Agents.AI.DurableTask` is present only if the project already runs on Azure and the choice is recorded in `plan.md` (`## Decisões`) — ciente de que, desde a 1.17, o pacote vive em repositório separado e ficou para trás do framework.
257
257
  - [ ] Toda tool com efeito irreversível está embrulhada em `ApprovalRequiredAIFunction` **ou** tem um guard determinístico documentado — e a escolha entre os dois está escrita.
258
258
  - [ ] A resposta de aprovação é enviada na **mesma** `AgentSession`, num laço que checa pendências depois de cada run.
259
259
  - [ ] Nenhum `Workflow` foi criado apenas para pausar uma tool de um agente único.
@@ -189,7 +189,7 @@ primeira pergunta a fazer quando um guard "nunca reprova nada".
189
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
- - [ ] O choke-point escolhido está nomeado no `decisions.md`, com o que ele pega
192
+ - [ ] O choke-point escolhido está nomeado no `plan.md` (`## Decisões`), com o que ele pega
193
193
  - [ ] O middleware de tool devolve **vocabulário fechado** de desfecho
194
194
  - [ ] Argumento obrigatório ausente é barrado **sem** executar a tool, lendo o schema da própria função
195
195
  - [ ] Nenhum identificador com efeito vem do modelo — todos vêm da closure do turno
@@ -178,13 +178,13 @@ Tenho múltiplos agents — qual padrão usar?
178
178
  | Handoff sem `turnLimit` nem condição de término | Dois agentes devolvem a conversa um ao outro indefinidamente | `.WithAutonomousMode(turnLimit:)` ou `.WithTerminationCondition(...)` |
179
179
  | `Id` de agente gerado a cada boot num workflow de handoff | O destino do handoff deixa de existir entre reinícios | `Id` estável, vindo de configuração |
180
180
  | Group chat com 5+ agentes | O gerente gasta os turnos escolhendo quem fala | ≤ 3 agentes; acima disso, repense a decomposição |
181
- | Agents com responsabilidades sobrepostas | Nenhum dos dois sabe quando agir; o LLM fica confuso | Fronteiras claras de responsabilidade; documente em `decisions.md`. |
181
+ | Agents com responsabilidades sobrepostas | Nenhum dos dois sabe quando agir; o LLM fica confuso | Fronteiras claras de responsabilidade; documente em `plan.md` (`## Decisões`). |
182
182
 
183
183
  ---
184
184
 
185
185
  ## Checklist (verifiable in review)
186
186
 
187
- - [ ] Foi verificado em `decisions.md` que single agent não resolve?
187
+ - [ ] Foi verificado em `plan.md` (`## Decisões`) que single agent não resolve?
188
188
  - [ ] O padrão escolhido é o mais simples que atende ao requisito? (Tool < Sequential imperativo < Workflow)
189
189
  - [ ] `agent.AsAIFunction()` usado para composição local (não `AIFunctionFactory.Create` desnecessariamente)?
190
190
  - [ ] Agents usando alias do Model Registry — nenhum model string hardcoded?
@@ -313,7 +313,7 @@ Workflow para diagnosticar um incidente relatado ("o agente X respondeu errado/l
313
313
  2. **Suba do trace raiz para os spans filhos.** O span raiz mostra a duração total; os filhos (`Function Calling`, `IChatClient`) mostram onde o tempo/erro realmente está. Não assuma — meça. Um "agente lento" é quase sempre UM tool call específico (chamada de API externa, query sem índice), não o LLM.
314
314
  3. **Correlacione com métricas antes de teorizar.** Confira a tabela "What to Monitor" abaixo pelo período do incidente — um pico de `tool call failure rate` ou `token usage` aponta a causa mais rápido que ler traces individuais um a um.
315
315
  4. **Reproduza com Debug ligado, nunca em produção.** Se a causa não estiver clara nos atributos estruturados, habilite `Debug` (com dados sensíveis, se necessário) num ambiente de staging com o mesmo input — nunca habilite log de prompt/response completo em produção para investigar.
316
- 5. **Documente a causa raiz em `decisions.md`** se a investigação levar a uma mudança de arquitetura (novo middleware de retry, novo timeout, novo cache) — não só no commit message.
316
+ 5. **Documente a causa raiz em `plan.md` (`## Decisões`)** se a investigação levar a uma mudança de arquitetura (novo middleware de retry, novo timeout, novo cache) — não só no commit message.
317
317
 
318
318
  ### What to Monitor
319
319
 
@@ -202,7 +202,7 @@ Na **1.18** (2026-08-18) essa superfície foi renomeada. Nomes atuais, medidos p
202
202
 
203
203
  **Duas advertências que valem mais que os nomes:**
204
204
 
205
- 1. **O pacote é prerelease.** `Microsoft.Agents.AI.Hosting` não tem versão estável (apurado 2026-09-08). Isolamento multi-tenant por esse caminho é adoção de preview — registre em `decisions.md`.
205
+ 1. **O pacote é prerelease.** `Microsoft.Agents.AI.Hosting` não tem versão estável (apurado 2026-09-08). Isolamento multi-tenant por esse caminho é adoção de preview — registre em `plan.md` (`## Decisões`).
206
206
  2. **A chave vem da credencial, nunca do payload.** Uma chave derivada de algo que o cliente envia é uma chave que o cliente escolhe. `UseClaimsBasedAgentIsolation()` existe exatamente para não deixar essa decisão passar pelo corpo do request.
207
207
 
208
208
  ### Invocação concorrente de tools é opt-in desde 1.18
@@ -5,7 +5,7 @@
5
5
  > **Keywords:** prompt sources, prompts in db, agent prompts, prompt versioning, prompt hot-reload, editable instructions, prompt management, prompt por tenant, spec publicado, reconciliação de prompt
6
6
  > **Read by Claude in:** implement (quando as instruções de um agente precisam viver fora do código) e troubleshoot (quando a versão que rodou não é a que se esperava)
7
7
 
8
- **Verified against:** Microsoft.Agents.AI 1.20.0 + Microsoft.Extensions.AI 10.9.0 (ai-pin 2026-09-08). **Verificação documental**, sem cláusula `provado por` — o ai-kit não traz loader de prompt, e os dois mecanismos descritos aqui são destilados de três produtos em produção. As **quatro** superfícies de API que este standard cita foram medidas por reflexão, e vivem em **três assemblies diferentes** — o carimbo diz onde remedir, então o nome importa: `IChatClient.AsAIAgent(instructions:, name:)` é `Microsoft.Extensions.AI.ChatClientExtensions`, em **`Microsoft.Agents.AI` 1.20.0** (medida em 2026-09-08); `AIAgent.RunAsync` (as oito sobrecargas) e `AIAgent.CreateSessionAsync` são de `Microsoft.Agents.AI.AIAgent`, na assembly **`Microsoft.Agents.AI.Abstractions` 1.20.0** — **remedidas** em 2026-09-09, porque a leitura de 2026-09-08 estava errada no *quê*, e a de 2026-09-09 estava errada no *onde* (as duas retificações estão no callout abaixo); e `builder.AddAIAgent` (§Keyed singleton) é `Microsoft.Agents.AI.Hosting.HostApplicationBuilderAgentExtensions` — cinco sobrecargas, na assembly **`Microsoft.Agents.AI.Hosting` 1.20.0.0**, que vem do pacote **`Microsoft.Agents.AI.Hosting` `1.20.0-preview.260831.1`**: ele é **prerelease** e está **FORA do `ai-pin.json`** (apurado em `scripts/api-probe/companions.json`, 2026-09-08) — quem adotar esta seção registra a dependência prerelease em `decisions.md`, como manda `ai-agents-production`. **Duas ressalvas de escopo**, porque um carimbo que não as diz promete mais do que mediu: `Microsoft.Agents.AI.Abstractions` e `Microsoft.Extensions.AI.Abstractions` são nomes de **assembly** (elas viajam dentro dos pacotes `Microsoft.Agents.AI` e `Microsoft.Extensions.AI`), não ids de pacote; e `IMemoryCache`/`DbContext`, usados no padrão de cache e na §Keyed singleton, são superfícies de ASP.NET Core e EF Core — **fora do pin, não medidas aqui, verificação documental**. Last-verified: 2026-09-08.
8
+ **Verified against:** Microsoft.Agents.AI 1.20.0 + Microsoft.Extensions.AI 10.9.0 (ai-pin 2026-09-08). **Verificação documental**, sem cláusula `provado por` — o ai-kit não traz loader de prompt, e os dois mecanismos descritos aqui são destilados de três produtos em produção. As **quatro** superfícies de API que este standard cita foram medidas por reflexão, e vivem em **três assemblies diferentes** — o carimbo diz onde remedir, então o nome importa: `IChatClient.AsAIAgent(instructions:, name:)` é `Microsoft.Extensions.AI.ChatClientExtensions`, em **`Microsoft.Agents.AI` 1.20.0** (medida em 2026-09-08); `AIAgent.RunAsync` (as oito sobrecargas) e `AIAgent.CreateSessionAsync` são de `Microsoft.Agents.AI.AIAgent`, na assembly **`Microsoft.Agents.AI.Abstractions` 1.20.0** — **remedidas** em 2026-09-09, porque a leitura de 2026-09-08 estava errada no *quê*, e a de 2026-09-09 estava errada no *onde* (as duas retificações estão no callout abaixo); e `builder.AddAIAgent` (§Keyed singleton) é `Microsoft.Agents.AI.Hosting.HostApplicationBuilderAgentExtensions` — cinco sobrecargas, na assembly **`Microsoft.Agents.AI.Hosting` 1.20.0.0**, que vem do pacote **`Microsoft.Agents.AI.Hosting` `1.20.0-preview.260831.1`**: ele é **prerelease** e está **FORA do `ai-pin.json`** (apurado em `scripts/api-probe/companions.json`, 2026-09-08) — quem adotar esta seção registra a dependência prerelease em `plan.md` (`## Decisões`), como manda `ai-agents-production`. **Duas ressalvas de escopo**, porque um carimbo que não as diz promete mais do que mediu: `Microsoft.Agents.AI.Abstractions` e `Microsoft.Extensions.AI.Abstractions` são nomes de **assembly** (elas viajam dentro dos pacotes `Microsoft.Agents.AI` e `Microsoft.Extensions.AI`), não ids de pacote; e `IMemoryCache`/`DbContext`, usados no padrão de cache e na §Keyed singleton, são superfícies de ASP.NET Core e EF Core — **fora do pin, não medidas aqui, verificação documental**. Last-verified: 2026-09-08.
9
9
 
10
10
  ---
11
11
 
@@ -356,7 +356,7 @@ rastreabilidade (hash em span, prompt cru só em harness) está em `ai-agents-ob
356
356
  - [ ] `GetActivePromptAsync` throws `InvalidOperationException` (not returns null) when no active prompt found
357
357
  - [ ] Versionamento pattern followed: INSERT + flip, never UPDATE content
358
358
  - [ ] At least one seed row per `agent_key` in migrations or seed script
359
- - [ ] A fonte escolhida (banco versionado × composição por tenant) está nomeada no `decisions.md`,
359
+ - [ ] A fonte escolhida (banco versionado × composição por tenant) está nomeada no `plan.md` (`## Decisões`),
360
360
  com a pergunta "o texto varia por cliente?" respondida
361
361
  - [ ] No caminho composto: a moldura e o YAML estão versionados no repo, e o blob publicado **não** é
362
362
  editado à mão
@@ -185,7 +185,7 @@ Going through `Microsoft.Extensions.AI` (`IChatClient`) or the MAF (`AIAgent`) k
185
185
  | **Anthropic Claude** | `anthropic` | Confirm current SDK on NuGet before use | ignora o campo | Adapt provider client to `IChatClient` |
186
186
  | **Azure OpenAI** (opt-in, not default) | `azure-openai` | `Azure.AI.OpenAI` + `Azure.Identity` — confirm exact versions on NuGet before use | segue o OpenAI | Add only when a client requires data residency |
187
187
 
188
- > **Restore trap, measured 2026-09-08:** `Microsoft.Extensions.AI.OpenAI` 10.9.0 declares `OpenAI (>= 2.12.0 && < 2.13.0)`. Pairing it with the pinned `OpenAI` 2.13.0 emits **NU1608** on restore. Either pin `OpenAI` to 2.12.x alongside the bridge, or accept the warning knowingly and write the decision in `decisions.md`. Do not discover this in CI.
188
+ > **Restore trap, measured 2026-09-08:** `Microsoft.Extensions.AI.OpenAI` 10.9.0 declares `OpenAI (>= 2.12.0 && < 2.13.0)`. Pairing it with the pinned `OpenAI` 2.13.0 emits **NU1608** on restore. Either pin `OpenAI` to 2.12.x alongside the bridge, or accept the warning knowingly and write the decision in `plan.md` (`## Decisões`). Do not discover this in CI.
189
189
 
190
190
  **No floating ranges.** Every `PackageReference` above is an exact version. A floating `2.*` on a weekly-cadence SDK is how ProspectPRO bought a `MissingMethodException` on the Responses API **after paying for the call** (`docs/specs/elevacao-9/brutos/scan-prospectpro.md:55`).
191
191
 
@@ -179,7 +179,7 @@ Registered on the agent with `tools: [AIFunctionFactory.Create(tool.SearchAsync)
179
179
 
180
180
  The `tenant_id` filter is **never a tool parameter** (that would allow the LLM to cross tenant boundaries). It is injected via a constructor dependency — e.g., a scoped `ITenantContext` or a `Guid currentTenantId` resolved from the authenticated request. See §Multi-tenant below.
181
181
 
182
- Note on raw Npgsql vs EF Core: the EF Core LINQ form above is the default (`ApplicationDbContext` in the slice, no raw SQL). A raw `NpgsqlDataSource` query is acceptable only with a `decisions.md` justification (e.g. a project with no EF Core model for this table). The legacy `VectorSearchTool.cs.template` still uses raw SQL and `EmbeddingService`; prefer the block above.
182
+ Note on raw Npgsql vs EF Core: the EF Core LINQ form above is the default (`ApplicationDbContext` in the slice, no raw SQL). A raw `NpgsqlDataSource` query is acceptable only with a `plan.md` (`## Decisões`) justification (e.g. a project with no EF Core model for this table). The legacy `VectorSearchTool.cs.template` still uses raw SQL and `EmbeddingService`; prefer the block above.
183
183
 
184
184
  ---
185
185
 
@@ -319,7 +319,7 @@ ALTER TABLE kb_embeddings ENABLE ROW LEVEL SECURITY;
319
319
  - [ ] `VectorSearchTool` registered on the agent via `AIFunctionFactory.Create(tool.SearchAsync)`.
320
320
  - [ ] No `Microsoft.SemanticKernel` references in the project.
321
321
  - [ ] Vector dimensions consistent between embedding model and `vector(N)` column definition.
322
- - [ ] RLS enabled on `kb_embeddings` (or equivalent app-level guard documented in `decisions.md`).
322
+ - [ ] RLS enabled on `kb_embeddings` (or equivalent app-level guard documented in `plan.md` (`## Decisões`)).
323
323
  - [ ] Ingestion follows §*Ingestão delta por lookup-key*: a pure `Plan(...)` produces `Added`/`Updated`/`Removed`/`Unchanged`, and `Unchanged` is never re-embedded.
324
324
  - [ ] No `DELETE`-everything-then-reinsert: `Removed` is applied **after** `Added`/`Updated`, in the same transaction — there is no window where the search returns empty.
325
325
  - [ ] `Updated` is an **upsert** on a deterministic id, never delete+insert.
@@ -62,7 +62,7 @@ Está adicionando um agente AI a um projeto .NET?
62
62
  <!-- Azure OpenAI (somente se data residency exigir) — confira Azure.AI.OpenAI + Azure.Identity no NuGet -->
63
63
  ```
64
64
 
65
- > **Armadilha de restore, medida em 2026-09-08:** `Microsoft.Extensions.AI.OpenAI` 10.9.0 declara a dependência `OpenAI (>= 2.12.0 && < 2.13.0)`. Com o `OpenAI` **2.13.0** do pin, o `dotnet restore` emite **NU1608** (*"Versão detectada do pacote fora da restrição de dependência"*). Duas saídas honestas: fixar `OpenAI` em 2.12.x ao lado da ponte, **ou** aceitar o aviso conscientemente e registrar a decisão em `decisions.md`. Não descubra isso no CI.
65
+ > **Armadilha de restore, medida em 2026-09-08:** `Microsoft.Extensions.AI.OpenAI` 10.9.0 declara a dependência `OpenAI (>= 2.12.0 && < 2.13.0)`. Com o `OpenAI` **2.13.0** do pin, o `dotnet restore` emite **NU1608** (*"Versão detectada do pacote fora da restrição de dependência"*). Duas saídas honestas: fixar `OpenAI` em 2.12.x ao lado da ponte, **ou** aceitar o aviso conscientemente e registrar a decisão em `plan.md` (`## Decisões`). Não descubra isso no CI.
66
66
 
67
67
  > **De onde vem cada extensão** (medido por reflexão sobre as assemblies do pin, 2026-09-08):
68
68
  > | Extensão | Assembly que a publica | Namespace do `using` |
@@ -155,7 +155,7 @@ Fontes, ambas lidas em 2026-09-08:
155
155
 
156
156
  A Responses API **armazena por padrão**. OpenAI, mesmo guia, verbatim: *"Responses are stored by default. Chat completions are stored by default for new accounts. To disable storage when using either API, set `store: false`."* Respostas retidas ficam 30 dias no provedor.
157
157
 
158
- Projetos desta casa mantêm o histórico **próprio** (ver `ai-agents-agent-session`), então não se quer uma segunda cópia da conversa no provedor. **Regra: `store: false` explícito.** Quem quiser o oposto registra o porquê em `decisions.md`.
158
+ Projetos desta casa mantêm o histórico **próprio** (ver `ai-agents-agent-session`), então não se quer uma segunda cópia da conversa no provedor. **Regra: `store: false` explícito.** Quem quiser o oposto registra o porquê em `plan.md` (`## Decisões`).
159
159
 
160
160
  O MAF tem um atalho de primeira classe para isso — medido na assembly `Microsoft.Agents.AI.OpenAI` 1.20.0:
161
161
 
@@ -105,11 +105,11 @@ You may need to step outside the sweet spot when:
105
105
 
106
106
  ## Checklist (verifiable in review)
107
107
 
108
- - [ ] Was each agent designed as single-agent BEFORE reaching for multi-agent? (Check `decisions.md`.)
108
+ - [ ] Was each agent designed as single-agent BEFORE reaching for multi-agent? (Check `plan.md` (`## Decisões`).)
109
109
  - [ ] If a Workflow is used, is fan-in/out or HITL checkpointing genuinely present? Or could `foreach + LINQ` replace it?
110
110
  - [ ] Are the 4 features (Chat, Structured Output, Tools, RAG Custom) all present where applicable?
111
111
  - [ ] Are hosted agent services avoided?
112
- - [ ] Nenhum agente carrega mais de ~12 tools sem uma decisão escrita em `decisions.md` sobre a poda
112
+ - [ ] Nenhum agente carrega mais de ~12 tools sem uma decisão escrita em `plan.md` (`## Decisões`) sobre a poda
113
113
 
114
114
  ---
115
115
 
@@ -210,8 +210,6 @@ MORPH_GHLBrain, `src/Morph.GHLBrain/Features/Conversation/Operator/`:
210
210
  | `set_lead_fields` | `Tools/SetLeadFieldsTool.cs` | `Ops/DossieOps.cs` | `CamposDesfecho` |
211
211
  | `route_lead` | `Tools/RouteLeadTool.cs` | `Ops/TriagemOps.cs` | `TriagemDesfecho` |
212
212
 
213
- As decisões estão em `.morph/features/tools-finas/2-plan/decisions.md` (ADR-1 e ADR-2) daquele repositório.
214
-
215
213
  ## Regras
216
214
 
217
215
  - **ALWAYS** a regra de uma tool vai numa `sealed class XOps(...)` com construtor primário e `AddScoped` explícito
@@ -86,7 +86,7 @@ Preview packages are subject to breaking API changes before GA (see the rename `
86
86
  |-----------|-----|
87
87
  | Default production RAG on Neon/Postgres (this framework's default stack), **already implemented and tested** | **`ai-agents-rag-custom-pgvector`** — framework-owned raw SQL, zero external connector, already the checklisted default. **Não se migra o que funciona** (item D4 da elevação-9) |
88
88
  | **Projeto novo** onde a escolha do store ainda não foi cravada, e trocá-lo depois deve custar pouco | `Microsoft.Extensions.VectorData.Abstractions` 10.9.0 + `CommunityToolkit.VectorData.PgVector` 1.0.1 — hoje **ambos estáveis**, o que remove o argumento "é preview" que existia em julho/2026 |
89
- | Project needs genuine portability across >1 vector backend (a client contract requires swapping Postgres for Qdrant or Azure AI Search later) | `Microsoft.Extensions.VectorData` + o conector correspondente — document the choice in `decisions.md` |
89
+ | Project needs genuine portability across >1 vector backend (a client contract requires swapping Postgres for Qdrant or Azure AI Search later) | `Microsoft.Extensions.VectorData` + o conector correspondente — document the choice in `plan.md` (`## Decisões`) |
90
90
  | Prototyping, tests, or demos where an in-memory store is enough | `CommunityToolkit.VectorData.InMemory` 1.0.1 |
91
91
  | Ingestão em pipeline (reader → chunker → writer) hoje | Só com `Microsoft.Extensions.DataIngestion`, que **continua preview**: registre a aceitação e um lembrete de revisitar no GA |
92
92
 
@@ -175,10 +175,10 @@ This maps conceptually onto the existing custom pattern: `IngestionDocumentReade
175
175
 
176
176
  - [ ] If `Microsoft.SemanticKernel.Connectors.*` appears in a `.csproj`, it is used only for `VectorStoreCollection`/`VectorStore` types — no `Kernel`, `KernelFunction`, or `ChatHistory` usage anywhere in the project.
177
177
  - [ ] No plain `Microsoft.SemanticKernel` (core) package reference.
178
- - [ ] If VectorData was chosen over custom pgvector, the reason is recorded in `decisions.md` per the decision matrix.
178
+ - [ ] If VectorData was chosen over custom pgvector, the reason is recorded in `plan.md` (`## Decisões`) per the decision matrix.
179
179
  - [ ] No new `Microsoft.SemanticKernel.Connectors.*` reference — new work uses `CommunityToolkit.VectorData.*`.
180
- - [ ] If a preview package (`Microsoft.Extensions.DataIngestion`, or any `*-preview` connector) was adopted, `decisions.md` records the preview-acceptance and a revisit-at-GA note.
181
- - [ ] Every VectorData/ingestion `PackageReference` carries an exact version — these packages are **not** in `framework/ai-pin.json`, so the project's own `decisions.md` (or a comment) states when the version was checked.
180
+ - [ ] If a preview package (`Microsoft.Extensions.DataIngestion`, or any `*-preview` connector) was adopted, `plan.md` (`## Decisões`) records the preview-acceptance and a revisit-at-GA note.
181
+ - [ ] Every VectorData/ingestion `PackageReference` carries an exact version — these packages are **not** in `framework/ai-pin.json`, so the project's own `plan.md` (`## Decisões`) (or a comment) states when the version was checked.
182
182
  - [ ] Embedding model/dimensions consistent between the `VectorStoreVector(N)` attribute and the chosen embedding model.
183
183
 
184
184
  ---
@@ -186,7 +186,7 @@ Sempre use `await using` no `StreamingRun` / `Run` — é `IAsyncDisposable`.
186
186
  ## Checklist (verifiable in review)
187
187
 
188
188
  - [ ] Foi verificado que um `foreach` ou single agent não resolve o problema?
189
- - [ ] O critério de fan-in/out genuíno ou HITL está documentado em `decisions.md`?
189
+ - [ ] O critério de fan-in/out genuíno ou HITL está documentado em `plan.md` (`## Decisões`)?
190
190
  - [ ] `Microsoft.Agents.AI` 1.0.* presente no `.csproj` (sem pacotes preview separados)?
191
191
  - [ ] Agents referenciando alias do Model Registry (não model strings hardcoded)?
192
192
  - [ ] `await using` no `StreamingRun` / `Run`?
@@ -62,7 +62,7 @@ Só o **porquê que o código não mostra**:
62
62
  ## Tamanho
63
63
 
64
64
  Uma linha é o normal; teto de ~3. Acima disso o comentário justifica o volume (algoritmo não
65
- óbvio, armadilha de terceiro com a reprodução). Bloco longo narrando decisões é `decisions.md` com
65
+ óbvio, armadilha de terceiro com a reprodução). Bloco longo narrando decisões é `plan.md` (`## Decisões`) com
66
66
  outro nome. Em volume, código de aplicação fica perto de zero: mais de uma linha de comentário a
67
67
  cada dez de código é sinal de que os nomes não estão fazendo o trabalho. Arquivo vizinho muito
68
68
  comentado não é modelo: código novo segue este padrão, não a densidade do legado.
@@ -333,7 +333,7 @@ var page = await _db.Books
333
333
  (ex.: `SELECT ... FOR UPDATE`, retry de `DbUpdateConcurrencyException`) ou SQL específico
334
334
  que o LINQ não expressa, escreva um store hand-written e purpose-built (ex.: `OutboxStore`,
335
335
  `LeaseStore`) com métodos nomeados pela intenção — e registre a justificativa em
336
- `decisions.md`. Nunca um genérico por entidade.
336
+ `plan.md` (`## Decisões`). Nunca um genérico por entidade.
337
337
 
338
338
  Veja `backend/dotnet/vsa-handler-patterns.md` → "Data Access: DbContext in the Slice".
339
339
 
@@ -173,7 +173,7 @@ The state check (`>= Completed`) and the business rule (`RequiresPayment && !IsP
173
173
  - [ ] Failures come back as `ValidationError` → 400 ProblemDetails with `errors[]`, never an exception?
174
174
  - [ ] Existence / uniqueness / state checks in the handler, returning typed `Error`s?
175
175
  - [ ] State checks validate INVALID states, with the error range at 100+?
176
- - [ ] All flows documented in decisions.md and tested?
176
+ - [ ] All flows documented in plan.md (## Decisões) and tested?
177
177
 
178
178
  ---
179
179
 
@@ -225,13 +225,13 @@ public sealed class SearchBooksHandler(
225
225
  When a slice needs concurrency control (`SELECT ... FOR UPDATE`, lease/outbox semantics,
226
226
  `DbUpdateConcurrencyException` retry loops) or SQL that LINQ cannot express, write a
227
227
  **hand-written, purpose-built store** with intention-named methods (e.g. `OutboxStore.ClaimBatchAsync`,
228
- `LeaseStore.TryAcquireAsync`) — and document the justification in `decisions.md`.
228
+ `LeaseStore.TryAcquireAsync`) — and document the justification in `plan.md` (`## Decisões`).
229
229
  Never a generic-per-entity abstraction.
230
230
 
231
231
  **Rule of thumb:** everything → `ApplicationDbContext` in the slice. Concurrency or
232
- specific SQL → dedicated hand-written store + `decisions.md` entry. Never reach for raw SQL
232
+ specific SQL → dedicated hand-written store + `plan.md` (`## Decisões`) entry. Never reach for raw SQL
233
233
  (`FromSqlRaw`) unless a query genuinely cannot be expressed in LINQ — and document that
234
- in `decisions.md`.
234
+ in `plan.md` (`## Decisões`).
235
235
 
236
236
  ---
237
237
 
@@ -307,8 +307,8 @@ builder.Services.AddExceptionHandler<CustomExceptionHandler>()
307
307
  | Share handlers across features | Each feature has its own handler, even if similar |
308
308
  | Use constructor + field for DI | Use primary constructors: `class Handler(IDep dep)` |
309
309
  | Group by technical concern (Controllers/, Services/) | Group by feature: `Features/BookFeature/CreateBook/` |
310
- | Route data access through any indirection layer | Inject `DbContext` and write LINQ in the slice; dedicated store only with `decisions.md` justification |
311
- | Use raw SQL (`FromSqlRaw` / `ExecuteQuery(string)`) by default | Use LINQ; raw SQL only with a `decisions.md` justification |
310
+ | Route data access through any indirection layer | Inject `DbContext` and write LINQ in the slice; dedicated store only with `plan.md` (`## Decisões`) justification |
311
+ | Use raw SQL (`FromSqlRaw` / `ExecuteQuery(string)`) by default | Use LINQ; raw SQL only with a `plan.md` (`## Decisões`) justification |
312
312
 
313
313
  ---
314
314
 
@@ -15,7 +15,7 @@ Background job processing for .NET 10 VSA applications with Hangfire on Neon Pos
15
15
 
16
16
  ## When to use Hangfire
17
17
 
18
- Hangfire is in the stack **only with a real reason**: work that must survive a process restart, run on a schedule, or be retried later (daily reindex, delayed reminders, retrying a flaky third party). Work that fits in the request (send one email after a signup, index one uploaded document) runs in the slice handler. Record the reason in `decisions.md`.
18
+ Hangfire is in the stack **only with a real reason**: work that must survive a process restart, run on a schedule, or be retried later (daily reindex, delayed reminders, retrying a flaky third party). Work that fits in the request (send one email after a signup, index one uploaded document) runs in the slice handler. Record the reason in `plan.md` (`## Decisões`).
19
19
 
20
20
  Hangfire provides fire-and-forget, delayed and recurring (cron) jobs, continuations, a dashboard and automatic retries.
21
21
 
@@ -64,7 +64,7 @@ place to audit.
64
64
  **The exception process:** a feature that genuinely needs the frontend to reach Neon directly for
65
65
  business data (for example, via the Neon MCP `provision_neon_data_api` tool) is an exception, not a
66
66
  default — treat it exactly like vertical-slice.md's "Stores dedicados (exceção justificada)" clause:
67
- document the justification in the feature's `decisions.md` before writing the code. A tool being
67
+ document the justification in the feature's `plan.md` (`## Decisões`) before writing the code. A tool being
68
68
  available is not, by itself, justification.
69
69
 
70
70
  See [Row-Level Security Integration](#row-level-security-integration) for how to constrain a
@@ -727,7 +727,7 @@ Each Neon branch gets its own isolated auth data. This means:
727
727
  fetch and cache the JWKS yourself and verify EdDSA signatures manually (BouncyCastle)
728
728
  11. **Route business data through the .NET backend by default** — the frontend's only inherent
729
729
  reason to talk to Neon directly is its own auth/session SDK; a direct Data API call needs a
730
- `decisions.md` ADR (see [Data Access Boundary](#data-access-boundary--backend-first-by-default))
730
+ `plan.md` (`## Decisões`) ADR (see [Data Access Boundary](#data-access-boundary--backend-first-by-default))
731
731
 
732
732
  ---
733
733
 
@@ -179,4 +179,4 @@ The minute comes from `TimeProvider` (testable with `FakeTimeProvider`), never `
179
179
  - Never omit TTL -- unbounded keys fill memory
180
180
  - Never wrap the cache in a `XService`/repository class -- cache-aside is three lines in the handler
181
181
  - Never return `null` for "not found" -- the handler returns `Result` with `NotFound`
182
- - Never swallow `RedisConnectionException` in an empty `catch`: a cache outage must be visible (health check + logs). Falling back to the database while Redis is down is a product decision: record it in `decisions.md` and implement it once, at the cache boundary, not per call site
182
+ - Never swallow `RedisConnectionException` in an empty `catch`: a cache outage must be visible (health check + logs). Falling back to the database while Redis is down is a product decision: record it in `plan.md` (`## Decisões`) and implement it once, at the cache boundary, not per call site
@@ -3,7 +3,7 @@
3
3
  > **Scope:** data-nosql
4
4
  > **Layer:** 3 (opcional — nenhuma rule nem persona o carrega; só sob demanda via `morph-spec standards --find`, depois de a decisão existir)
5
5
  > **Keywords:** cosmos-db, nosql, document-database, event-store, partition-key, azure-cosmos
6
- > **Load When:** `decisions.md` already records the choice of Cosmos DB over Neon for a specific store
6
+ > **Load When:** `plan.md` (`## Decisões`) already records the choice of Cosmos DB over Neon for a specific store
7
7
 
8
8
  **Verified against:** .NET 10 (SDK 10.0.400-preview) + Microsoft.Azure.Cosmos 3.63.2 + Newtonsoft.Json 13.0.4 — every `csharp` block below compiles with `TreatWarningsAsErrors` against the `Result`/`Error` types of `backend-dotnet-result-pattern`. Last-verified: 2026-10-03.
9
9
 
@@ -11,7 +11,7 @@
11
11
 
12
12
  ## Overview
13
13
 
14
- **Cosmos DB is not part of the stack.** The default store is Neon (Postgres) through EF Core, with the `ApplicationDbContext` used directly in the slice. Reach for Cosmos only when a requirement Postgres cannot meet is written down in `decisions.md` (the "why not Neon" included). Everything below applies the stack conventions to that exception: the client is injected straight into the slice handler, ids are `Guid.CreateVersion7()`, expected failures are `Result` values, and classes are `sealed`.
14
+ **Cosmos DB is not part of the stack.** The default store is Neon (Postgres) through EF Core, with the `ApplicationDbContext` used directly in the slice. Reach for Cosmos only when a requirement Postgres cannot meet is written down in `plan.md` (`## Decisões`) (the "why not Neon" included). Everything below applies the stack conventions to that exception: the client is injected straight into the slice handler, ids are `Guid.CreateVersion7()`, expected failures are `Result` values, and classes are `sealed`.
15
15
 
16
16
  ## When It Can Be Justified
17
17
 
@@ -155,7 +155,7 @@ using var feed = container.GetItemQueryIterator<OrderEvent>(
155
155
 
156
156
  | Do NOT | Do Instead |
157
157
  |--------|------------|
158
- | Pick Cosmos without a `decisions.md` entry | Neon (Postgres) via EF Core is the default store |
158
+ | Pick Cosmos without a `plan.md` (`## Decisões`) entry | Neon (Postgres) via EF Core is the default store |
159
159
  | Wrap `Container` in a generic `CosmosRepository<T>` | Inject the keyed `Container` into the slice handler |
160
160
  | `try/catch (CosmosException)` for 404/409 | Stream APIs + `StatusCode` → `Result` |
161
161
  | `Guid.NewGuid()` for document ids | `Guid.CreateVersion7()` |
@@ -16,7 +16,7 @@ An admin app has **one** form pattern. It is the base pattern of `nextjs/forms.m
16
16
  - **The Zod schema is shared.** The same schema types the form, validates it, and parses the API response (`admin-app/data-table.md` parses the list query with Zod too). One source of truth per entity.
17
17
  - **react-hook-form keeps inputs uncontrolled** — a 30-field form does not re-render on every keystroke, which is what `useState` per field does.
18
18
  - **shadcn's current form docs are written around it** (`Field`, `FieldLabel`, `FieldError` + `Controller`).
19
- - **Coexisting styles are the defect this rule exists for.** Measured in a real admin app: three form styles side by side (react-hook-form in some screens, hand-rolled `useState` in others) — three validation behaviours for one product, and a redesign that changed none of them. A screen that needs something the pattern cannot do registers the exception in `decisions.md`; it does not start a fourth style.
19
+ - **Coexisting styles are the defect this rule exists for.** Measured in a real admin app: three form styles side by side (react-hook-form in some screens, hand-rolled `useState` in others) — three validation behaviours for one product, and a redesign that changed none of them. A screen that needs something the pattern cannot do registers the exception in `plan.md` (`## Decisões`); it does not start a fourth style.
20
20
 
21
21
  ## Core Rules
22
22
 
@@ -0,0 +1,88 @@
1
+ # Art Direction — Decide What the Screen Is Before Drawing It
2
+
3
+ > **Scope:** frontend-design-system
4
+ > **Layer:** 3
5
+ > **Keywords:** art direction, concept, visual metaphor, design direction, template look, generic ui, memorable, mobile-first, brand moment
6
+ > **Load When:** ui-designer active, before any component of a new or changed screen
7
+
8
+ **Verified against:** the `login-ciclo-do-produto` design round (2026-10-06): a correct, plain design was rejected; a second round with a written direction, an HTML prototype and a screenshot self-review was approved on first sight. Last-verified: 2026-10-06.
9
+
10
+ ---
11
+
12
+ A design that follows the tokens, has every state and passes WCAG can still be forgettable. What made the difference in practice was not talent but order: a direction written before any component, a real prototype, and a critical look at the rendered result. This standard is the first of the three.
13
+
14
+ ---
15
+
16
+ ## Section 1: Write the Direction First
17
+
18
+ Before the first component, answer four questions in `1-design/direcao.md`:
19
+
20
+ 1. **Concept in one sentence.** What the screen says, not what it contains. *"The login tells the product cycle in scenes while you sign in."*
21
+ 2. **Visual metaphor.** The image that organizes the layout. *Stories; a control room; a ticket being stamped; a garden that grows.*
22
+ 3. **What makes it memorable.** The one thing someone would describe to a colleague. If nothing, the direction is not done.
23
+ 4. **What it must NOT look like.** Name the generic version you are avoiding (Section 4).
24
+
25
+ Only then pick components. A component chosen before the direction is chosen by habit.
26
+
27
+ ---
28
+
29
+ ## Section 2: Explore Two or Three Directions
30
+
31
+ For a new screen or a brand moment (login, onboarding, first screen, empty state, success, showcase), write two or three directions that are **distinct**, not three color variations of one layout. For each: concept, metaphor, the mobile idea, the motion idea, and the risk. Recommend one and say why, in terms of the product and the user, not taste.
32
+
33
+ A changed screen inside an established system may need only one direction, written the same way, with what changes and why.
34
+
35
+ ---
36
+
37
+ ## Section 3: Good and Bad Directions
38
+
39
+ | Bad direction | Why it fails | Good direction |
40
+ |---|---|---|
41
+ | "Clean, modern login with the logo and a form." | Describes every login. Nothing to remember. | "The panel tells the product cycle in three scenes, stories-style; the form is a sheet the thumb reaches." |
42
+ | "Dashboard with cards for each metric." | Content, not concept. Layout by habit. | "A control room: one hero number the operator acts on, the rest as quiet instruments around it." |
43
+ | "Empty state with an icon and a button." | The default of every kit. | "The empty list is the first page of a notebook: an illustrated first entry shows what a good one looks like." |
44
+ | "Mobile: same layout, stacked." | Mobile derived, not designed. | "Mobile is an app: bottom sheet, thumb-zone actions, the scene compressed to a strip above." |
45
+
46
+ ---
47
+
48
+ ## Section 4: Template Tells to Avoid
49
+
50
+ Each one is fine in isolation; together they read as "generated". If the screen has three or more, raise it.
51
+
52
+ - Raw shadcn look: default radius, default gray border, no brand in any surface.
53
+ - A white card centered on a gray background, logo on top, form inside.
54
+ - A generic icon list (three features, three Lucide icons, three lines of copy).
55
+ - Stack-default or AI-tell fonts with no tracking or scale decision (see `premium-finish` Section 1).
56
+ - Flat solid backgrounds with no light, layer or texture.
57
+ - Mobile as the desktop stacked: centered card, tiny targets, actions out of thumb reach.
58
+ - Motion as decoration: everything fades in, nothing tells a sequence.
59
+ - Made-up numbers on illustrative cards (`R$ 12.430`, `98% satisfaction`).
60
+
61
+ ---
62
+
63
+ ## Section 5: Mobile Is Designed, Not Derived
64
+
65
+ Draw the phone at 390 px as its own composition: bottom sheet for the primary task, actions in the thumb zone, targets of at least 44 px, the brand scene compressed rather than removed. Then check the desktop is not the phone blown up either.
66
+
67
+ ---
68
+
69
+ ## Section 6: Motion With Intent
70
+
71
+ Motion should tell something (a sequence, a cause, a state change). Pick the lightest tool that delivers it: CSS transition and `@keyframes`, then CSS scroll-driven animation, then Framer Motion, then GSAP with ScrollTrigger and timelines. Budget: 60 fps, only `transform` and `opacity`, no layout thrash, lazy below the fold. `prefers-reduced-motion` gets a composed static version, designed as carefully as the animated one.
72
+
73
+ ---
74
+
75
+ ## Section 7: Prototype and Self-Review
76
+
77
+ The direction is proved in a rendered prototype, not in prose: `1-design/prototipos/{screen}.html`, self-contained, using the project's REAL tokens read from its token CSS (the design-system doc can be stale), desktop and phone side by side in a device frame, with animated / static / pause controls. Serve it over local HTTP, screenshot at 1280 and 390, judge against this standard and the system bar (hierarchy, contrast, rhythm, mobile, "does it look like a template?"), fix, repeat. The final screenshots sit next to the HTML.
78
+
79
+ ---
80
+
81
+ ## Checklist
82
+
83
+ - [ ] `direcao.md` answers concept, metaphor, memorable, must-not-look-like
84
+ - [ ] Two or three distinct directions for a new screen or brand moment, one recommended with a reason
85
+ - [ ] Fewer than three template tells on the final screen
86
+ - [ ] Mobile composed at 390 px on its own terms
87
+ - [ ] Motion tells something, with a composed reduced-motion version
88
+ - [ ] Prototype rendered, screenshotted at 1280 and 390, and revised until it passes
@@ -3,9 +3,9 @@
3
3
  > **Scope:** frontend-design-system
4
4
  > **Layer:** 3
5
5
  > **Keywords:** premium, polish, typography, film grain, atmosphere, load-in, scrim, legibility over video, accent
6
- > **Load When:** ui-designer active, or the brief asks for a premium or high-end feel
6
+ > **Load When:** ui-designer active (every surface), or the brief asks for a premium or high-end feel
7
7
 
8
- **Verified against:** Production landing pages, CSS-only techniques, no runtime dependency. Last-verified: 2026-08-21.
8
+ **Verified against:** Production landing pages, CSS-only techniques, no runtime dependency; app patterns from an approved login prototype (2026-10-06). Last-verified: 2026-10-06.
9
9
 
10
10
  ---
11
11
 
@@ -148,6 +148,78 @@ Finish with fresh eyes: open the page as if you were the client. Whatever looks
148
148
 
149
149
  ---
150
150
 
151
+ ## Section 8: Patterns For App Screens
152
+
153
+ The finish is not only for marketing pages. Login, onboarding, the first screen after sign-up, an empty state and a success moment are brand moments inside the product, and a data screen also has to look designed: elegant density, illustrated empty states, skeletons with shimmer, transitions between states. These patterns come from an app login that was approved on first sight after a plain one was rejected.
154
+
155
+ ### Bottom sheet on mobile
156
+
157
+ On a phone the form lives in a sheet anchored to the bottom, inside the thumb zone, with the brand scene above it. Never the desktop card centered and shrunk.
158
+
159
+ ```css
160
+ .sheet {
161
+ position: fixed; inset: auto 0 0 0;
162
+ padding: 12px 20px calc(20px + env(safe-area-inset-bottom));
163
+ border-radius: 24px 24px 0 0;
164
+ background: var(--surface);
165
+ box-shadow: 0 -12px 40px color-mix(in oklab, var(--brand) 18%, transparent);
166
+ }
167
+ .sheet::before {
168
+ content: ''; display: block; width: 36px; height: 4px; margin: 0 auto 16px;
169
+ border-radius: 2px; background: var(--border);
170
+ }
171
+ .sheet button, .sheet input { min-height: 44px; }
172
+ ```
173
+
174
+ ### Stories-style progress
175
+
176
+ A sequence of scenes reads like stories: thin segmented bars at the top, each filling while its scene is on. One keyframe, the delay per segment, and the scene swap keyed to the same delays.
177
+
178
+ ```css
179
+ .stories { display: flex; gap: 4px; }
180
+ .stories span { flex: 1; height: 3px; border-radius: 2px; background: color-mix(in oklab, var(--fg) 20%, transparent); overflow: hidden; }
181
+ .stories span::after {
182
+ content: ''; display: block; height: 100%; background: var(--fg);
183
+ transform: scaleX(0); transform-origin: left;
184
+ animation: fill var(--beat) linear forwards;
185
+ animation-delay: calc(var(--i) * var(--beat));
186
+ }
187
+ @keyframes fill { to { transform: scaleX(1); } }
188
+ ```
189
+
190
+ ### Synchronized highlight by `animation-delay`
191
+
192
+ When a scene card lights up while its story bar runs, both share `--i` and `--beat`. No JavaScript timer: the browser keeps them in step, and pausing is one `animation-play-state: paused` on the parent.
193
+
194
+ ### Scene cards without real data
195
+
196
+ A card that illustrates the product cycle shows shapes, icons and labels, never a metric. A made-up number on a real screen reads as a real number ("R$ 12.430 recovered") and becomes a claim nobody can back. Use bars without values, avatars without names, a check without a count.
197
+
198
+ ### Dot grid faded with `mask-image`
199
+
200
+ Texture for a hero or a sheet backdrop, cheaper than an image and on brand:
201
+
202
+ ```css
203
+ .dots {
204
+ background-image: radial-gradient(color-mix(in oklab, var(--fg) 22%, transparent) 1px, transparent 1px);
205
+ background-size: 16px 16px;
206
+ mask-image: radial-gradient(ellipse at 50% 30%, #000 30%, transparent 75%);
207
+ }
208
+ ```
209
+
210
+ ### Static version for reduced motion
211
+
212
+ `prefers-reduced-motion: reduce` gets a composed still frame (the best scene, every bar full, the highlight on), not the first frame of a stopped animation.
213
+
214
+ ```css
215
+ @media (prefers-reduced-motion: reduce) {
216
+ .stories span::after { animation: none; transform: scaleX(1); }
217
+ .scene { animation: none; opacity: 1; }
218
+ }
219
+ ```
220
+
221
+ ---
222
+
151
223
  ## Checklist
152
224
 
153
225
  - [ ] Display font chosen from the brand, not from stack defaults or the AI-tell list
@@ -157,4 +229,7 @@ Finish with fresh eyes: open the page as if you were the client. Whatever looks
157
229
  - [ ] Directional scrim plus text-shadow on every text-over-media block
158
230
  - [ ] Accent used in three places or fewer
159
231
  - [ ] Details swept: scrollbar, selection, hairlines, hover micro-transitions
232
+ - [ ] App screen: mobile designed on its own (bottom sheet, thumb zone, 44px targets), never the desktop stacked
233
+ - [ ] No invented number or data on a real screen
234
+ - [ ] Reduced motion gets a composed static frame
160
235
  - [ ] Fresh-eyes pass done, and it does not read as a template
@@ -19,7 +19,7 @@ Stack: .NET VSA + Neon Serverless Postgres. For the end-to-end RAG pipeline (ing
19
19
  - ALWAYS call `UseVector()` on the `UseNpgsql(...)` options builder (EF Core); `NpgsqlDataSourceBuilder.UseVector()` is only for raw Npgsql
20
20
  - ALWAYS register the `vector` extension in `OnModelCreating` (`HasPostgresExtension("vector")`)
21
21
  - Map vector properties as `Pgvector.Vector` -- EF Core does not map `float[]` or `ReadOnlyMemory<float>` to the `vector` column
22
- - Query through the `ApplicationDbContext` in the slice handler with the `CosineDistance`/`L2Distance`/`MaxInnerProduct` LINQ translations -- no repository class, no raw SQL from C# without a `decisions.md` justification
22
+ - Query through the `ApplicationDbContext` in the slice handler with the `CosineDistance`/`L2Distance`/`MaxInnerProduct` LINQ translations -- no repository class, no raw SQL from C# without a `plan.md` (`## Decisões`) justification
23
23
  - IDs come from the app (`Guid.CreateVersion7()`), never from a `gen_random_uuid()` column default
24
24
 
25
25
  ## Enable pgvector
@@ -39,7 +39,7 @@ CREATE EXTENSION IF NOT EXISTS vector;
39
39
  <PackageReference Include="Pgvector.EntityFrameworkCore" Version="0.3.0" />
40
40
  ```
41
41
 
42
- `Pgvector.EntityFrameworkCore` 0.3.0 requires `Npgsql.EntityFrameworkCore.PostgreSQL` >= 9.0.1 and brings `Pgvector` (the `Vector` type and the raw-Npgsql plugin) transitively. The configuration below maps each column to the snake_case names of `backend/database/postgresql/database.md` (`embedding`, `created_at`) with `HasColumnName`; without it EF creates `"Embedding"`, `"CreatedAt"` and every SQL snippet below would have to quote PascalCase names. (A project that wants this for every entity can add `EFCore.NamingConventions` and `UseSnakeCaseNamingConvention()` once, instead of per column -- a project-wide decision for `decisions.md`.)
42
+ `Pgvector.EntityFrameworkCore` 0.3.0 requires `Npgsql.EntityFrameworkCore.PostgreSQL` >= 9.0.1 and brings `Pgvector` (the `Vector` type and the raw-Npgsql plugin) transitively. The configuration below maps each column to the snake_case names of `backend/database/postgresql/database.md` (`embedding`, `created_at`) with `HasColumnName`; without it EF creates `"Embedding"`, `"CreatedAt"` and every SQL snippet below would have to quote PascalCase names. (A project that wants this for every entity can add `EFCore.NamingConventions` and `UseSnakeCaseNamingConvention()` once, instead of per column -- a project-wide decision for `plan.md` (`## Decisões`).)
43
43
 
44
44
  ### Entity Definition
45
45
 
@@ -196,9 +196,9 @@ public sealed class SearchDocumentsHandler(
196
196
 
197
197
  Storing an embedding is an ordinary EF write in the handler that owns the document: `document.Embedding = new Vector(await embeddings.GenerateVectorAsync(text, cancellationToken: ct));` followed by `SaveChangesAsync`. No `UPDATE ... SET embedding` from C#.
198
198
 
199
- ### SQL Functions (only with a `decisions.md` justification)
199
+ ### SQL Functions (only with a `plan.md` (`## Decisões`) justification)
200
200
 
201
- When the query must live in the database (called from several apps, or a hybrid score the LINQ translation cannot express), a SQL function is acceptable -- record why in `decisions.md`, call it through EF Core with interpolated parameters, and keep the same distance rules:
201
+ When the query must live in the database (called from several apps, or a hybrid score the LINQ translation cannot express), a SQL function is acceptable -- record why in `plan.md` (`## Decisões`), call it through EF Core with interpolated parameters, and keep the same distance rules:
202
202
 
203
203
  ```sql
204
204
  CREATE OR REPLACE FUNCTION match_documents(
@@ -218,7 +218,7 @@ $$;
218
218
 
219
219
  ## Hybrid Search (Vector + Full-Text)
220
220
 
221
- Blends the vector score with `ts_rank`. Same rule as above: a SQL function, justified in `decisions.md`.
221
+ Blends the vector score with `ts_rank`. Same rule as above: a SQL function, justified in `plan.md` (`## Decisões`).
222
222
 
223
223
  ```sql
224
224
  CREATE OR REPLACE FUNCTION hybrid_search(
@@ -6,7 +6,7 @@
6
6
 
7
7
  VSA + .NET 10 + EF Core + Neon (Postgres) + Microsoft Agent Framework + Next.js (App Router) + Tailwind + Framer Motion + Shadcn + Hangfire (quando necessário).
8
8
 
9
- Padrões proibidos por padrão: `Guid.NewGuid()` (use `Guid.CreateVersion7()`), classes não-sealed sem justificativa, exceptions como fluxo de controle, camada de Service/Manager entre handler e dados, repository genérico (`IRepository<T>`/`IUnitOfWork`), SQL cru sem justificativa. Acesso a dados: `ApplicationDbContext` direto no slice (`DbSet<T>` já é repository, `DbContext` já é unit of work); para concorrência ou SQL específico, store dedicado hand-written com justificativa em `decisions.md`.
9
+ Padrões proibidos por padrão: `Guid.NewGuid()` (use `Guid.CreateVersion7()`), classes não-sealed sem justificativa, exceptions como fluxo de controle, camada de Service/Manager entre handler e dados, repository genérico (`IRepository<T>`/`IUnitOfWork`), SQL cru sem justificativa. Acesso a dados: `ApplicationDbContext` direto no slice (`DbSet<T>` já é repository, `DbContext` já é unit of work); para concorrência ou SQL específico, store dedicado hand-written com justificativa em `plan.md` (`## Decisões`).
10
10
 
11
11
  ## Harness
12
12
 
@@ -18,5 +18,5 @@ morph-spec NLH — leia `.morph/framework/MORPH.md` ao iniciar cada sessão. Em
18
18
 
19
19
  ## Slash commands
20
20
 
21
- - `/morph-proposal {feature}` — entendimento de negócio + use cases, spec e tasks (Gates 1 e 2)
22
- - `/morph-apply {feature}` — execução autônoma das tarefas + review (Gate 3)
21
+ - `/morph-plan {feature}` — entrevista, `plan.md`, `plan-check` e gate do plano
22
+ - `/morph-apply {feature}` — fatias do plano, `verify` e review (Gate 3)