@polymorphism-tech/morph-spec 8.47.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 (377) hide show
  1. package/CLAUDE.md +51 -43
  2. package/README.md +39 -38
  3. package/bin/morph-spec.js +41 -113
  4. package/bin/validate.js +1 -147
  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 +41 -101
  9. package/framework/MORPH.md +95 -252
  10. package/framework/agents.json +86 -21
  11. package/framework/commands/morph-apply.md +5 -28
  12. package/framework/commands/morph-archive.md +1 -1
  13. package/framework/commands/morph-hotfix.md +8 -8
  14. package/framework/commands/morph-infra.md +1 -1
  15. package/framework/commands/morph-preflight.md +2 -3
  16. package/framework/commands/morph-status.md +4 -4
  17. package/framework/docs/CLI.md +574 -286
  18. package/framework/evals/review-checklist.md +82 -41
  19. package/framework/hooks/README.md +10 -11
  20. package/framework/hooks/claude-code/core/block-destructive-worktree-removal.js +6 -49
  21. package/framework/hooks/claude-code/core/block-raw-worktree-add.js +2 -35
  22. package/framework/hooks/claude-code/core/chain.js +4 -65
  23. package/framework/hooks/claude-code/core/comment-guard.js +3 -17
  24. package/framework/hooks/claude-code/core/denylist.json +33 -3
  25. package/framework/hooks/claude-code/core/enforce-phase-writes.js +15 -63
  26. package/framework/hooks/claude-code/core/gate-guard.js +9 -78
  27. package/framework/hooks/claude-code/core/graph-refresh-kick.js +3 -24
  28. package/framework/hooks/claude-code/core/heavy-gate.js +3 -21
  29. package/framework/hooks/claude-code/core/heavy-release.js +2 -13
  30. package/framework/hooks/claude-code/core/loop-detect.js +2 -31
  31. package/framework/hooks/claude-code/core/pre-bash-denylist.js +36 -2
  32. package/framework/hooks/claude-code/core/protect-spec-files.js +25 -297
  33. package/framework/hooks/claude-code/core/state-sync.js +15 -85
  34. package/framework/hooks/claude-code/core/telemetry-log.js +15 -96
  35. package/framework/hooks/claude-code/core/validate-completion.js +37 -147
  36. package/framework/hooks/claude-code/core/warn-bash-source-write.js +23 -0
  37. package/framework/hooks/claude-code/core/worktree-context.js +15 -114
  38. package/framework/hooks/claude-code/core/worktree-create.js +6 -70
  39. package/framework/hooks/claude-code/core/worktree-env-inject.js +5 -56
  40. package/framework/hooks/claude-code/core/worktree-remove.js +5 -31
  41. package/framework/hooks/claude-code/statusline.py +55 -41
  42. package/framework/hooks/package.json +3 -0
  43. package/framework/hooks/shared/activity-logger.js +9 -89
  44. package/framework/hooks/shared/agent-reap.js +2 -17
  45. package/framework/hooks/shared/build-check.js +11 -76
  46. package/framework/hooks/shared/claim-registry.js +9 -119
  47. package/framework/hooks/shared/command-tokens.js +168 -44
  48. package/framework/hooks/shared/comment-rules.js +5 -20
  49. package/framework/hooks/shared/comment-scanner.js +11 -43
  50. package/framework/hooks/shared/comment-stripper.js +11 -85
  51. package/framework/hooks/shared/e2e-check.js +0 -0
  52. package/framework/hooks/shared/errata.js +59 -0
  53. package/framework/hooks/shared/feature-locator.js +11 -95
  54. package/framework/hooks/shared/frontend-locations.js +4 -0
  55. package/framework/hooks/shared/gate-question.js +12 -0
  56. package/framework/hooks/shared/git-exclude.js +3 -20
  57. package/framework/hooks/shared/git-paths.js +8 -104
  58. package/framework/hooks/shared/graph-freshness.js +22 -166
  59. package/framework/hooks/shared/graph-refresh.js +21 -149
  60. package/framework/hooks/shared/heavy-command.js +4 -12
  61. package/framework/hooks/shared/hook-response.js +8 -83
  62. package/framework/hooks/shared/morph-cli.js +8 -52
  63. package/framework/hooks/shared/payload-utils.js +10 -132
  64. package/framework/hooks/shared/phase-utils.js +14 -72
  65. package/framework/hooks/shared/redact-secrets.js +4 -15
  66. package/framework/hooks/shared/reparse-scan.js +6 -66
  67. package/framework/hooks/shared/slice-progress.js +99 -0
  68. package/framework/hooks/shared/source-files.js +4 -17
  69. package/framework/hooks/shared/spawn-command.js +23 -0
  70. package/framework/hooks/shared/state-reader.js +51 -247
  71. package/framework/hooks/shared/state-writer.js +9 -54
  72. package/framework/hooks/shared/stdin-reader.js +1 -11
  73. package/framework/hooks/shared/telemetry-logger.js +7 -67
  74. package/framework/hooks/shared/transcript-usage.js +7 -29
  75. package/framework/hooks/shared/worktree-root.js +7 -29
  76. package/framework/mcp/registry.json +3 -4
  77. package/framework/phases.json +23 -39
  78. package/framework/rules/csharp-standards.md +1 -1
  79. package/framework/rules/frontend-standards.md +1 -0
  80. package/framework/rules/hangfire-standards.md +1 -1
  81. package/framework/rules/neon-standards.md +1 -1
  82. package/framework/schemas/config.schema.json +14 -9
  83. package/framework/schemas/feature.schema.json +15 -50
  84. package/framework/skills/README.md +3 -4
  85. package/framework/skills/core/create-umbraco-lp/SKILL.md +1 -1
  86. package/framework/skills/core/migrate-lp-to-umbraco/SKILL.md +1 -1
  87. package/framework/skills/core/morph-apply/SKILL.md +149 -222
  88. package/framework/skills/core/morph-hotfix/SKILL.md +33 -42
  89. package/framework/skills/core/morph-machine/SKILL.md +2 -2
  90. package/framework/skills/core/morph-media/SKILL.md +1 -1
  91. package/framework/skills/core/morph-plan/SKILL.md +137 -299
  92. package/framework/skills/core/morph-review/SKILL.md +111 -136
  93. package/framework/skills/core/morph-standards/SKILL.md +27 -39
  94. package/framework/skills/core/morph-uiux/SKILL.md +94 -152
  95. package/framework/standards/STANDARDS.json +109 -1219
  96. package/framework/standards/STANDARDS.meta.json +1319 -0
  97. package/framework/standards/ai-agents/agent-archetypes.md +2 -2
  98. package/framework/standards/ai-agents/agent-session.md +1 -1
  99. package/framework/standards/ai-agents/conversational-agent-with-phases.md +4 -4
  100. package/framework/standards/ai-agents/durable-workflows-hitl.md +3 -3
  101. package/framework/standards/ai-agents/evals-with-cache.md +1 -2
  102. package/framework/standards/ai-agents/guardrails.md +1 -1
  103. package/framework/standards/ai-agents/multi-agent-patterns.md +2 -2
  104. package/framework/standards/ai-agents/observability-patterns.md +1 -1
  105. package/framework/standards/ai-agents/production.md +1 -1
  106. package/framework/standards/ai-agents/prompt-sources.md +2 -2
  107. package/framework/standards/ai-agents/providers/model-registry.md +1 -1
  108. package/framework/standards/ai-agents/rag-custom-pgvector.md +2 -2
  109. package/framework/standards/ai-agents/setup.md +3 -3
  110. package/framework/standards/ai-agents/sweet-spot.md +2 -2
  111. package/framework/standards/ai-agents/tool-adapters.md +0 -2
  112. package/framework/standards/ai-agents/vector-data-extensions.md +4 -4
  113. package/framework/standards/ai-agents/workflows.md +1 -1
  114. package/framework/standards/architecture/code-comments.md +7 -7
  115. package/framework/standards/architecture/vertical-slice/vertical-slice.md +1 -1
  116. package/framework/standards/backend/api/validation.md +1 -1
  117. package/framework/standards/backend/dotnet/vsa-handler-patterns.md +5 -5
  118. package/framework/standards/backend/integrations/hangfire/hangfire-jobs.md +1 -1
  119. package/framework/standards/backend/integrations/neon-auth/neon-auth.md +2 -2
  120. package/framework/standards/data/nosql/cache/redis.md +1 -1
  121. package/framework/standards/data/nosql/cosmos-db.md +3 -3
  122. package/framework/standards/frontend/admin-app/forms.md +1 -1
  123. package/framework/standards/frontend/design-system/art-direction.md +88 -0
  124. package/framework/standards/frontend/design-system/premium-finish.md +77 -2
  125. package/framework/standards/infrastructure/neon/neon-pgvector.md +5 -5
  126. package/framework/standards/integration/mcp/mcp-tools.md +7 -7
  127. package/framework/templates/CLAUDE.md.core.template +3 -3
  128. package/framework/templates/README.md +2 -3
  129. package/framework/templates/REGISTRY.json +15 -179
  130. package/framework/templates/docs/plan.md +72 -0
  131. package/framework/templates/docs/ui-mockups.md +4 -0
  132. package/framework/templates/dotnet/ai-kit/README.md +1 -9
  133. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Morph.AiKit.Tests.csproj +0 -10
  134. package/framework/templates/meta-prompts/squad-leaders/backend-squad.md +1 -1
  135. package/framework/templates/meta-prompts/squad-leaders/frontend-squad.md +1 -1
  136. package/framework/templates/meta-prompts/squad-leaders/squad-leader.md +1 -1
  137. package/framework/templates/meta-prompts/validators/pre-commit-validator.md +3 -4
  138. package/package.json +1 -1
  139. package/src/commands/context/context-refresh.js +0 -16
  140. package/src/commands/dashboard/dashboard.js +2 -8
  141. package/src/commands/e2e/e2e.js +18 -105
  142. package/src/commands/graph/affected.js +0 -14
  143. package/src/commands/graph/build.js +11 -50
  144. package/src/commands/graph/explain.js +0 -16
  145. package/src/commands/graph/status.js +1 -12
  146. package/src/commands/mcp/mcp-setup.js +4 -62
  147. package/src/commands/observability/cost.js +17 -111
  148. package/src/commands/observability/telemetry.js +1 -14
  149. package/src/commands/project/branch.js +4 -45
  150. package/src/commands/project/claim.js +4 -48
  151. package/src/commands/project/doctor-procs.js +1 -1
  152. package/src/commands/project/doctor.js +53 -307
  153. package/src/commands/project/env.js +1 -27
  154. package/src/commands/project/fleet.js +6 -35
  155. package/src/commands/project/heavy.js +3 -3
  156. package/src/commands/project/init.js +8 -68
  157. package/src/commands/project/install-plugin-cmd.js +0 -1
  158. package/src/commands/project/setup-infra-cmd.js +2 -1
  159. package/src/commands/project/stack-scan.js +58 -0
  160. package/src/commands/project/standards.js +65 -72
  161. package/src/commands/project/status.js +28 -121
  162. package/src/commands/project/update.js +31 -223
  163. package/src/commands/project/worktree.js +109 -883
  164. package/src/commands/scaffold/scaffold.js +0 -25
  165. package/src/commands/state/advance.js +65 -120
  166. package/src/commands/state/approve.js +87 -229
  167. package/src/commands/state/archive.js +23 -139
  168. package/src/commands/state/auto-approval.js +65 -0
  169. package/src/commands/state/create.js +49 -109
  170. package/src/commands/state/delete.js +11 -63
  171. package/src/commands/state/finish.js +105 -494
  172. package/src/commands/state/gate-check.js +74 -183
  173. package/src/commands/state/gate-decision.js +8 -42
  174. package/src/commands/state/handoff.js +4 -31
  175. package/src/commands/state/list.js +21 -91
  176. package/src/commands/state/report-check.js +134 -338
  177. package/src/commands/state/retype.js +12 -28
  178. package/src/commands/validation/index.js +0 -3
  179. package/src/commands/validation/mutate.js +79 -19
  180. package/src/commands/validation/plan-check.js +81 -0
  181. package/src/commands/validation/validate-feature.js +52 -216
  182. package/src/commands/validation/verify.js +45 -160
  183. package/src/core/paths/output-schema.js +9 -155
  184. package/src/core/state/feature-identity.js +1 -25
  185. package/src/core/state/gate-order.js +2 -30
  186. package/src/core/state/lifecycle-audit.js +8 -100
  187. package/src/core/state/state-manager.js +32 -395
  188. package/src/core/templates/template-registry.js +2 -97
  189. package/src/core/templates/template-renderer.js +13 -93
  190. package/src/core/templates/template-seed.js +21 -0
  191. package/src/core/work-types.js +10 -45
  192. package/src/dashboard/app/App.jsx +1 -8
  193. package/src/dashboard/app/components/ActivityFeed.jsx +2 -8
  194. package/src/dashboard/app/components/CommandPalette.jsx +4 -11
  195. package/src/dashboard/app/components/DetailPanel.jsx +1 -5
  196. package/src/dashboard/app/components/EntityLink.jsx +0 -12
  197. package/src/dashboard/app/components/ErrorBoundary.jsx +1 -8
  198. package/src/dashboard/app/components/KnowledgeMarkdown.jsx +0 -11
  199. package/src/dashboard/app/components/Markdown.jsx +0 -9
  200. package/src/dashboard/app/components/PhaseRail.jsx +0 -11
  201. package/src/dashboard/app/components/SearchFilter.jsx +0 -4
  202. package/src/dashboard/app/components/Sidebar.jsx +0 -5
  203. package/src/dashboard/app/hooks/useMorphQuery.js +1 -11
  204. package/src/dashboard/app/hooks/usePref.js +1 -5
  205. package/src/dashboard/app/lib/format.js +0 -2
  206. package/src/dashboard/app/lib/phases.js +3 -9
  207. package/src/dashboard/app/lib/project.js +0 -12
  208. package/src/dashboard/app/pages/Activity.jsx +1 -1
  209. package/src/dashboard/app/pages/AgentMap.jsx +1 -8
  210. package/src/dashboard/app/pages/FeatureDetail.jsx +139 -133
  211. package/src/dashboard/app/pages/Features.jsx +9 -16
  212. package/src/dashboard/app/pages/Guide.jsx +2 -3
  213. package/src/dashboard/app/pages/HookInspector.jsx +2 -23
  214. package/src/dashboard/app/pages/PhasePipeline.jsx +3 -7
  215. package/src/dashboard/app/pages/Portfolio.jsx +0 -1
  216. package/src/dashboard/app/pages/RulesMap.jsx +1 -16
  217. package/src/dashboard/app/pages/SkillsLibrary.jsx +1 -16
  218. package/src/dashboard/app/pages/Standards.jsx +2 -17
  219. package/src/dashboard/scanner/activity-scanner.js +14 -83
  220. package/src/dashboard/scanner/agents-scanner.js +1 -23
  221. package/src/dashboard/scanner/docs-scanner.js +1 -7
  222. package/src/dashboard/scanner/feature-status.js +2 -5
  223. package/src/dashboard/scanner/features-scanner.js +92 -113
  224. package/src/dashboard/scanner/hooks-scanner.js +5 -28
  225. package/src/dashboard/scanner/index.js +0 -4
  226. package/src/dashboard/scanner/portfolio.js +5 -29
  227. package/src/dashboard/scanner/project-api.js +8 -54
  228. package/src/dashboard/scanner/rules-scanner.js +1 -2
  229. package/src/dashboard/scanner/skills-scanner.js +2 -12
  230. package/src/dashboard/scanner/standards-scanner.js +4 -7
  231. package/src/dashboard/vite-plugin-morph-data.js +5 -19
  232. package/src/lib/ai/ai-checks.js +7 -52
  233. package/src/lib/ai/ai-project-scan.js +14 -108
  234. package/src/lib/ai/code-audit.js +7 -63
  235. package/src/lib/ai/pin-drift.js +8 -51
  236. package/src/lib/ai/registry-audit.js +11 -90
  237. package/src/lib/ci/ci-verify.js +14 -13
  238. package/src/lib/ci/github-ci.js +9 -37
  239. package/src/lib/ci/workflow-scaffold.js +2 -10
  240. package/src/lib/detectors/claude-config-detector.js +13 -74
  241. package/src/lib/detectors/index.js +8 -59
  242. package/src/lib/e2e/compose-env.js +5 -66
  243. package/src/lib/e2e/stack-teardown.js +6 -40
  244. package/src/lib/generators/architecture-scanner.js +18 -156
  245. package/src/lib/generators/handoff-generator.js +37 -112
  246. package/src/lib/generators/scaffold-generator.js +5 -101
  247. package/src/lib/generators/settings-generator.js +11 -122
  248. package/src/lib/git/branch-classifier.js +11 -84
  249. package/src/lib/git/default-branch.js +14 -169
  250. package/src/lib/git/evidence-staleness.js +2 -1
  251. package/src/lib/git/gh.js +2 -17
  252. package/src/lib/git/pending-prs.js +6 -37
  253. package/src/lib/git/pr-files.js +3 -28
  254. package/src/lib/git/pr-index.js +3 -34
  255. package/src/lib/git/tree-fingerprint.js +17 -17
  256. package/src/lib/git/tree-state.js +6 -33
  257. package/src/lib/graph/god-nodes.js +2 -22
  258. package/src/lib/graph/graph-health.js +3 -24
  259. package/src/lib/graph/graph-loader.js +5 -56
  260. package/src/lib/graph/graphify-runtime.js +7 -37
  261. package/src/lib/graph/graphifyignore.js +8 -74
  262. package/src/lib/graph/sanitize.js +16 -136
  263. package/src/lib/heavy/cleanup.js +2 -6
  264. package/src/lib/installers/effects.js +8 -93
  265. package/src/lib/installers/mcp-installer.js +9 -169
  266. package/src/lib/installers/memory-installer.js +8 -33
  267. package/src/lib/installers/templates-reconcile.js +5 -60
  268. package/src/lib/mutation/commands.js +3 -2
  269. package/src/lib/mutation/dotnet-introspection.js +281 -0
  270. package/src/lib/mutation/plan.js +14 -6
  271. package/src/lib/mutation/runner.js +1 -1
  272. package/src/lib/mutation/subset.js +47 -13
  273. package/src/lib/plan/artifact-vocabulary.js +40 -0
  274. package/src/lib/plan/checks.js +208 -0
  275. package/src/lib/plan/plan-parser.js +204 -0
  276. package/src/lib/plan/plan-template.js +18 -0
  277. package/src/lib/projects/registry.js +7 -44
  278. package/src/lib/review-reports.js +204 -0
  279. package/src/lib/risk-detector.js +131 -274
  280. package/src/lib/specs/adr-index.js +38 -85
  281. package/src/lib/specs/design-seed.js +18 -0
  282. package/src/lib/specs/frontmatter.js +31 -0
  283. package/src/lib/specs/gfm-table.js +11 -0
  284. package/src/lib/specs/revocations.js +31 -102
  285. package/src/lib/specs/screen-checklist.js +56 -132
  286. package/src/lib/stack/dotnet-build-ignores.js +43 -0
  287. package/src/lib/stack/stack-profile.js +1 -28
  288. package/src/lib/stack/stack-scan.js +260 -0
  289. package/src/lib/stack-filter.js +4 -27
  290. package/src/lib/standards/registry.js +37 -0
  291. package/src/lib/standards/sections.js +47 -0
  292. package/src/lib/standards/verified-against.js +19 -191
  293. package/src/lib/tasks/eval-node.js +23 -179
  294. package/src/lib/tasks/linux-runner.js +18 -142
  295. package/src/lib/tasks/test-nodes.js +43 -313
  296. package/src/lib/tasks/test-runner.js +107 -447
  297. package/src/lib/telemetry/metrics.js +13 -103
  298. package/src/lib/telemetry/telemetry-reader.js +13 -238
  299. package/src/lib/telemetry/verify-event.js +4 -34
  300. package/src/lib/validators/code-budget/code-budget-validator.js +4 -44
  301. package/src/lib/validators/code-budget/index.js +0 -7
  302. package/src/lib/validators/contracts/contract-compliance-validator.js +4 -26
  303. package/src/lib/validators/contracts/index.js +0 -6
  304. package/src/lib/validators/nextjs/index.js +0 -5
  305. package/src/lib/validators/nextjs/next-component-validator.js +4 -81
  306. package/src/lib/validators/packages/index.js +0 -6
  307. package/src/lib/validators/packages/package-validator.js +6 -56
  308. package/src/lib/validators/reuse/index.js +0 -8
  309. package/src/lib/validators/reuse/reuse-validator.js +24 -137
  310. package/src/lib/validators/reuse/symbol-scanner.js +6 -62
  311. package/src/lib/validators/traceability-check.js +54 -156
  312. package/src/lib/validators/validation-runner.js +20 -125
  313. package/src/lib/validators/verify-runner.js +152 -575
  314. package/src/lib/work-type-detector.js +5 -67
  315. package/src/lib/worktree/docker-audit.js +17 -137
  316. package/src/lib/worktree/env-allocator.js +10 -98
  317. package/src/lib/worktree/feature-truth.js +12 -115
  318. package/src/lib/worktree/finish-backup.js +32 -242
  319. package/src/lib/worktree/fleet-scanner.js +31 -126
  320. package/src/lib/worktree/ignored-triage.js +15 -91
  321. package/src/lib/worktree/vscode-settings.js +2 -3
  322. package/src/lib/worktree/worktree-audit.js +21 -213
  323. package/src/lib/worktree/worktree-include.js +3 -5
  324. package/src/scripts/global-install.js +3 -9
  325. package/src/scripts/install-plugin.js +1 -13
  326. package/src/scripts/setup-infra.js +17 -138
  327. package/src/utils/agents-installer.js +92 -272
  328. package/src/utils/banner.js +4 -25
  329. package/src/utils/claude-md-injector.js +1 -37
  330. package/src/utils/claude-settings-manager.js +1 -87
  331. package/src/utils/file-copier.js +32 -90
  332. package/src/utils/hooks-installer.js +26 -296
  333. package/src/utils/skills-installer.js +4 -102
  334. package/src/utils/version-checker.js +4 -83
  335. package/framework/commands/morph-proposal.md +0 -57
  336. package/framework/evals/trace-schema.md +0 -67
  337. package/framework/hooks/claude-code/core/tasks-json-guard.js +0 -83
  338. package/framework/hooks/claude-code/core/trace-autogen.js +0 -277
  339. package/framework/hooks/git/pre-commit/specs.sh +0 -50
  340. package/framework/hooks/shared/tasks-validator.js +0 -111
  341. package/framework/rules/morph-task-tracking.md +0 -54
  342. package/framework/rules/morph-workflow.md +0 -244
  343. package/framework/schemas/tasks.schema.json +0 -79
  344. package/framework/skills/core/morph-brainstorming/SKILL.md +0 -161
  345. package/framework/skills/core/morph-implement/SKILL.md +0 -194
  346. package/framework/skills/core/morph-proposal/SKILL.md +0 -152
  347. package/framework/skills/core/morph-stack-scan/SKILL.md +0 -145
  348. package/framework/templates/docs/proposal.md +0 -192
  349. package/framework/templates/docs/spec.md +0 -57
  350. package/framework/templates/docs/ui-components.md +0 -52
  351. package/framework/templates/docs/ui-design-system.md +0 -76
  352. package/framework/templates/docs/ui-flows.md +0 -167
  353. package/framework/templates/examples/spec-examples.md +0 -91
  354. package/framework/templates/feature/decisions.md +0 -124
  355. package/framework/templates/feature/recap.md +0 -145
  356. package/framework/templates/tasks.template.json +0 -17
  357. package/src/commands/state/usecase.js +0 -143
  358. package/src/commands/tasks/dag.js +0 -181
  359. package/src/commands/utils/index.js +0 -3
  360. package/src/lib/agents/output-collector.js +0 -76
  361. package/src/lib/detectors/design-system-detector.js +0 -188
  362. package/src/lib/evaluator-report.js +0 -104
  363. package/src/lib/generators/design-system-generator.js +0 -508
  364. package/src/lib/specs/acervo-format.js +0 -70
  365. package/src/lib/specs/acervo-lifecycle.js +0 -264
  366. package/src/lib/specs/done-criteria-check.js +0 -200
  367. package/src/lib/specs/usecase-check.js +0 -301
  368. package/src/lib/specs/usecase-promoter.js +0 -301
  369. package/src/lib/specs/usecase-registry.js +0 -237
  370. package/src/lib/tasks/dispatch-planner.js +0 -319
  371. package/src/lib/tasks/dotnet-test-introspection.js +0 -632
  372. package/src/lib/tasks/mermaid-renderer.js +0 -132
  373. package/src/lib/tasks/task-classifier.js +0 -30
  374. package/src/lib/tasks/task-parser.js +0 -209
  375. package/src/lib/tasks/tasks-json-parser.js +0 -296
  376. package/src/lib/tasks/test-scope.js +0 -597
  377. package/src/utils/agent-id-mapper.js +0 -11
@@ -128,13 +128,13 @@ não escolhe o histórico; escolher "chat com histórico" não escolhe as fases.
128
128
  | Agente de batch no caminho síncrono de uma requisição | Latência de LLM no p99 do endpoint, sem retry e sem visibilidade | Job assíncrono |
129
129
  | Imagem descrita numa chamada e tipada noutra | Duas chamadas pagas, e o erro de descrição deixa de ser rastreável | Uma chamada multimodal com `RunAsync<T>` |
130
130
  | Projeção papel → `ChatMessage` em dois arquivos | Os dois divergem, e o bug aparece como "o agente esqueceu" | Uma projeção, pura e testável |
131
- | Escolher o arquétipo na implementação | A forma muda o desenho das tasks; escolhida depois, ela vira refactor | Escolha na fase de plano, e registre em `decisions.md` |
131
+ | Escolher o arquétipo na implementação | A forma muda o desenho das tasks; escolhida depois, ela vira refactor | Escolha na fase de plano, e registre em `plan.md` (`## Decisões`) |
132
132
 
133
133
  ---
134
134
 
135
135
  ## Checklist (verifiable in review)
136
136
 
137
- - [ ] O arquétipo escolhido está **nomeado** no `decisions.md` da feature, com a pergunta de
137
+ - [ ] O arquétipo escolhido está **nomeado** no `plan.md` (`## Decisões`) da feature, com a pergunta de
138
138
  `## Como escolher` que o decidiu
139
139
  - [ ] Nenhum agente novo por fase de conversa — a fase é dado do turno
140
140
  - [ ] Agente one-shot recebe prompt e alias como parâmetro, e não guarda estado entre invocações
@@ -228,7 +228,7 @@ O histórico cresce a cada turno. Quando estoura o context window do modelo, as
228
228
 
229
229
  ## Checklist (verifiable in review)
230
230
 
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
231
+ - [ ] A escolha da fonte de histórico foi feita pela tabela de critério — e está escrita em `plan.md` (`## Decisões`) quando não foi a conversa própria
232
232
  - [ ] O provider de histórico é registrado como **uma** instância compartilhada
233
233
  - [ ] Nenhum campo de instância do provider guarda estado de conversa; o que é por sessão está em `ProviderSessionState<TState>` e declarado em `StateKeys`
234
234
  - [ ] Existe teste com **duas sessões concorrentes** sobre o mesmo provider
@@ -170,7 +170,7 @@ comprar a única coisa que o aninhamento oferece — deixar o modelo decidir.
170
170
  contabilidade por agente); o teto de tool calls do externo não governa o interno; o timeout do turno
171
171
  passa a cobrir duas chamadas de LLM em série; e o span do interno pendura-se sob `execute_tool`, onde
172
172
  nenhum painel de agente procura. Quando a decisão **é** do modelo, esses quatro custos continuam
173
- valendo — a diferença é que aí eles foram escolhidos, e o `decisions.md` diz por quê.
173
+ valendo — a diferença é que aí eles foram escolhidos, e o `plan.md` (`## Decisões`) diz por quê.
174
174
 
175
175
  Os dois lados de campo, e é raro ter os dois:
176
176
 
@@ -198,7 +198,7 @@ A composição legítima — quando ela é mesmo necessária — é assunto de
198
198
  | Teto tratado como opção de chamada | Vai ao provider, onde não significa nada | É opção do pipeline, nível de agente |
199
199
  | `RequireAny` adotado sem medir `recovered` | Troca uma recuperação medida por uma falha nova | Aplique o critério de saída antes |
200
200
  | Etapa FIXA do turno aninhada numa tool call | Paga custo, teto, timeout e span quebrados sem comprar nada — ninguém precisava decidir | Sequência, no código |
201
- | Agent-as-Tool adotado sem registrar a decisão, ou além de 2 níveis | Os quatro custos viram surpresa, e o 3º nível é sinal de que devia ser sequência | Decisão no `decisions.md`, teto ≤ 2 níveis (`ai-agents-multi-agent-patterns`) |
201
+ | Agent-as-Tool adotado sem registrar a decisão, ou além de 2 níveis | Os quatro custos viram surpresa, e o 3º nível é sinal de que devia ser sequência | Decisão no `plan.md` (`## Decisões`), teto ≤ 2 níveis (`ai-agents-multi-agent-patterns`) |
202
202
 
203
203
  ---
204
204
 
@@ -212,8 +212,8 @@ A composição legítima — quando ela é mesmo necessária — é assunto de
212
212
  - [ ] Há teto de tool calls por turno, com tool isenta, e bater o teto é observável
213
213
  - [ ] O teto está no nível de agente, não nas opções de chamada
214
214
  - [ ] Se `RequireAny` foi adotado: a taxa de `recovered` e o custo da segunda chamada estão no
215
- `decisions.md`. Se não foi: o critério de saída está escrito
216
- - [ ] Nenhuma etapa **fixa** do turno é invocada de dentro de uma tool call. Onde há aninhamento, quem decide é o **modelo**, está registrado no `decisions.md`, e respeita o teto de ≤ 2 níveis de `ai-agents-multi-agent-patterns`
215
+ `plan.md` (`## Decisões`). Se não foi: o critério de saída está escrito
216
+ - [ ] Nenhuma etapa **fixa** do turno é invocada de dentro de uma tool call. Onde há aninhamento, quem decide é o **modelo**, está registrado no `plan.md` (`## Decisões`), e respeita o teto de ≤ 2 níveis de `ai-agents-multi-agent-patterns`
217
217
 
218
218
  ---
219
219
 
@@ -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.
@@ -228,8 +228,7 @@ Declare-o como um nó a mais em `project.tests[]` — não como uma estrutura pa
228
228
 
229
229
  | Quando | O que acontece |
230
230
  |---|---|
231
- | `verify {feature} {task}` (loop de task) | **pulado**, com motivo registrado — o relógio de uma task não paga uma suíte de eval |
232
- | `verify {feature}` (escopo de feature) | **roda**, offline, contra a cache commitada |
231
+ | `verify {feature}` | **roda**, offline, contra a cache commitada |
233
232
  | miss de cache sem credencial | **reprova** nomeando o cenário, o caminho, o comando de regravação e o arquivo de credencial |
234
233
  | `--refresh-cache` | regrava a árvore contra o provider real. **Nunca implícito**: é uma chamada paga |
235
234
 
@@ -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.
@@ -3,7 +3,7 @@
3
3
  > **Scope:** stacks=["dotnet"]
4
4
  > **Layer:** 0 (lista da persona `maf-expert`; resumo injetado pela rule `ai-agents-standards` em `**/Agents/**`, `**/agents/**`, `**/*Agent*.cs`; texto completo sob demanda via `morph-spec standards --find`)
5
5
  > **Keywords:** maf setup, microsoft agents ai, chatclient, ai agent, agent framework, agent dotnet, AsAIAgent, responses api, chat completions, store false
6
- > **Read by Claude in:** plan (pra citar pacote em tasks.json) + implement (pra escrever .csproj e Program.cs)
6
+ > **Read by Claude in:** plan (pra citar pacote no plan.md) + implement (pra escrever .csproj e Program.cs)
7
7
 
8
8
  **Verified against:** 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/Agents/AgentFactory.cs` (pipeline e escolha de protocolo). A superfície do SDK `OpenAI` e das pontes `Microsoft.Agents.AI.OpenAI` / `Microsoft.Extensions.AI.OpenAI` foi **medida por reflexão sobre as assemblies do pin** em 2026-09-08 — o ai-kit **não exercita** o cliente concreto da OpenAI — referencia o pacote no `.csproj`, mas não há `using OpenAI` em `src/` (medido 2026-09-08); ver a tabela "Dois níveis de garantia" no README do kit. Last-verified: 2026-09-08.
9
9
 
@@ -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`?
@@ -41,10 +41,10 @@ Só o **porquê que o código não mostra**:
41
41
 
42
42
  ## O que não merece
43
43
 
44
- - **História de processo.** Task, UC, ADR, FR, Gate, avaliador, `spec.md`, mockup, "confirmado ao
45
- implementar a T11", "o Gate 3 pediu". Isso vai na mensagem de commit e no `decisions.md`, onde tem
46
- data e autor e não envelhece dentro do arquivo. Em teste, o elo com a pós-condição vai no **nome**
47
- do teste (`P5_estado_do_lead_espelha_o_crm`, `DisplayName`), nunca em `// UC-672 P5`.
44
+ - **História de processo.** Fatia, cenário, ADR, Gate, avaliador, `plan.md`, mockup, "confirmado ao
45
+ implementar a F2", "o Gate 3 pediu". Isso vai na mensagem de commit e no `plan.md`, onde tem
46
+ data e autor e não envelhece dentro do arquivo. Em teste, o elo com o cenário vai no **nome**
47
+ do teste (`C5_estado_do_lead_espelha_o_crm`, `DisplayName`), nunca em `// C5`.
48
48
  - **Repetição do código.** `// incrementa o contador` sobre `count++`, `// valida o request` sobre
49
49
  `validator.Validate(request)`. Nome bom substitui comentário.
50
50
  - **Doc-comment que repete a assinatura.** `/// <summary>Obtém o pedido.</summary>` sobre
@@ -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.
@@ -70,12 +70,12 @@ comentado não é modelo: código novo segue este padrão, não a densidade do l
70
70
  ## Exemplo
71
71
 
72
72
  ```ts
73
- // Ruim: rotula, conta a task, repete o código e afirma comportamento que nenhum teste cobra.
73
+ // Ruim: rotula, conta a fatia, repete o código e afirma comportamento que nenhum teste cobra.
74
74
  /**
75
75
  * Salva o documento.
76
76
  * @param doc o documento
77
77
  */
78
- // T8 + T11: mutação obrigatória do relatório, item c. Faz upsert e nunca duplica.
78
+ // F2 + C3: mutação obrigatória do relatório, item c. Faz upsert e nunca duplica.
79
79
  async function save(doc: Doc) {
80
80
  await upsert({ key: doc.sourceId, hash: sha256(doc.body) });
81
81
  }
@@ -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