@polymorphism-tech/morph-spec 8.46.0 → 9.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +53 -44
- package/README.md +3 -4
- package/bin/morph-spec.js +38 -55
- package/bin/validate.js +5 -134
- package/claude-plugin.json +1 -1
- package/docs/CHEATSHEET.md +2 -2
- package/docs/QUICKSTART.md +1 -1
- package/framework/CLAUDE.md +41 -101
- package/framework/MORPH.md +95 -252
- package/framework/agents.json +75 -18
- package/framework/commands/create-umbraco-lp.md +2 -0
- package/framework/commands/migrate-lp-to-umbraco.md +2 -0
- package/framework/commands/morph-apply.md +5 -28
- package/framework/commands/morph-archive.md +2 -2
- package/framework/commands/morph-hotfix.md +8 -8
- package/framework/commands/morph-infra.md +17 -203
- package/framework/commands/morph-media.md +3 -0
- package/framework/commands/morph-preflight.md +7 -31
- package/framework/commands/morph-proposal.md +2 -50
- package/framework/commands/morph-status.md +3 -3
- package/framework/commands/morph-troubleshoot.md +2 -14
- package/framework/docs/CLI.md +585 -286
- package/framework/evals/review-checklist.md +82 -41
- package/framework/hooks/README.md +10 -11
- package/framework/hooks/claude-code/core/comment-guard.js +1 -1
- package/framework/hooks/claude-code/core/denylist.json +33 -3
- package/framework/hooks/claude-code/core/enforce-phase-writes.js +16 -20
- package/framework/hooks/claude-code/core/gate-guard.js +2 -11
- package/framework/hooks/claude-code/core/pre-bash-denylist.js +38 -0
- package/framework/hooks/claude-code/core/protect-spec-files.js +30 -242
- package/framework/hooks/claude-code/core/state-sync.js +17 -19
- package/framework/hooks/claude-code/core/telemetry-log.js +3 -3
- package/framework/hooks/claude-code/core/validate-completion.js +33 -97
- package/framework/hooks/claude-code/core/warn-bash-source-write.js +31 -0
- package/framework/hooks/claude-code/core/worktree-context.js +5 -4
- package/framework/hooks/claude-code/statusline.py +55 -41
- package/framework/hooks/package.json +3 -0
- package/framework/hooks/shared/activity-logger.js +1 -1
- package/framework/hooks/shared/build-check.js +10 -6
- package/framework/hooks/shared/command-tokens.js +169 -0
- package/framework/hooks/shared/comment-rules.js +1 -1
- package/framework/hooks/shared/comment-scanner.js +10 -23
- package/framework/hooks/shared/comment-stripper.js +1 -1
- package/framework/hooks/shared/e2e-check.js +67 -31
- package/framework/hooks/shared/errata.js +72 -0
- package/framework/hooks/shared/feature-locator.js +1 -1
- package/framework/hooks/shared/frontend-locations.js +6 -0
- package/framework/hooks/shared/gate-question.js +18 -0
- package/framework/hooks/shared/phase-utils.js +15 -32
- package/framework/hooks/shared/slice-progress.js +118 -0
- package/framework/hooks/shared/spawn-command.js +23 -0
- package/framework/hooks/shared/state-reader.js +61 -87
- package/framework/hooks/shared/state-writer.js +3 -3
- package/framework/mcp/registry.json +3 -4
- package/framework/phases.json +23 -39
- package/framework/rules/ai-agents-standards.md +18 -16
- package/framework/rules/asaas-standards.md +3 -1
- package/framework/rules/csharp-standards.md +10 -8
- package/framework/rules/data-standards.md +5 -5
- package/framework/rules/dotnet-templates.md +1 -1
- package/framework/rules/frontend-standards.md +4 -2
- package/framework/rules/gsap-standards.md +10 -5
- package/framework/rules/hangfire-standards.md +3 -1
- package/framework/rules/infrastructure-standards.md +4 -2
- package/framework/rules/neon-auth-standards.md +3 -1
- package/framework/rules/neon-standards.md +6 -4
- package/framework/rules/nextjs-standards.md +13 -11
- package/framework/rules/nextjs-templates.md +1 -1
- package/framework/rules/resend-standards.md +3 -1
- package/framework/schemas/config.schema.json +14 -9
- package/framework/schemas/feature.schema.json +15 -52
- package/framework/skills/README.md +4 -5
- package/framework/skills/core/create-umbraco-lp/SKILL.md +3 -3
- package/framework/skills/core/migrate-lp-to-umbraco/SKILL.md +3 -3
- package/framework/skills/core/morph-apply/SKILL.md +150 -223
- package/framework/skills/core/morph-hotfix/SKILL.md +34 -43
- package/framework/skills/core/morph-machine/SKILL.md +4 -4
- package/framework/skills/core/morph-media/SKILL.md +3 -3
- package/framework/skills/core/morph-plan/SKILL.md +138 -300
- package/framework/skills/core/morph-review/SKILL.md +112 -137
- package/framework/skills/core/morph-standards/SKILL.md +29 -41
- package/framework/skills/core/morph-uiux/SKILL.md +78 -153
- package/framework/standards/STANDARDS.json +90 -1219
- package/framework/standards/STANDARDS.meta.json +1305 -0
- package/framework/standards/ai-agents/evals-with-cache.md +2 -3
- package/framework/standards/ai-agents/llm-runtime-defaults.md +1 -1
- package/framework/standards/ai-agents/modalities-speech-to-text.md +36 -26
- package/framework/standards/ai-agents/prompt-sources.md +6 -4
- package/framework/standards/ai-agents/providers/model-registry.md +1 -1
- package/framework/standards/ai-agents/rag-custom-pgvector.md +67 -39
- package/framework/standards/ai-agents/setup.md +2 -2
- package/framework/standards/ai-agents/structured-output.md +1 -1
- package/framework/standards/ai-agents/sweet-spot.md +1 -1
- package/framework/standards/architecture/code-comments.md +8 -8
- package/framework/standards/architecture/vertical-slice/vertical-slice.md +18 -9
- package/framework/standards/backend/api/validation.md +135 -47
- package/framework/standards/backend/database/postgresql/database.md +11 -7
- package/framework/standards/backend/database/vector-search-rag.md +207 -324
- package/framework/standards/backend/dotnet/fluent-validation-vsa.md +14 -8
- package/framework/standards/backend/dotnet/result-pattern.md +40 -6
- package/framework/standards/backend/dotnet/scalar-ui.md +13 -7
- package/framework/standards/backend/dotnet/scrutor.md +1 -1
- package/framework/standards/backend/dotnet/testing.md +1 -1
- package/framework/standards/backend/dotnet/vsa-handler-patterns.md +7 -7
- package/framework/standards/backend/integrations/asaas/asaas-api.md +309 -165
- package/framework/standards/backend/integrations/hangfire/hangfire-jobs.md +134 -154
- package/framework/standards/data/nosql/cache/redis.md +120 -44
- package/framework/standards/data/nosql/cosmos-db.md +114 -71
- package/framework/standards/frontend/design-system/animations.md +1 -1
- package/framework/standards/frontend/design-system/naming.md +1 -1
- package/framework/standards/frontend/nextjs/motion-patterns.md +45 -29
- package/framework/standards/frontend/nextjs/naming-conventions.md +1 -1
- package/framework/standards/infrastructure/docker/coolify-deploy.md +8 -6
- package/framework/standards/infrastructure/neon/neon-pgvector.md +120 -75
- package/framework/standards/infrastructure/neon/neon-setup.md +53 -31
- package/framework/standards/integration/mcp/mcp-tools.md +7 -7
- package/framework/templates/README.md +2 -3
- package/framework/templates/REGISTRY.json +6 -170
- package/framework/templates/code/dotnet/contracts/contracts-vsa.cs +2 -2
- package/framework/templates/code/dotnet/extensions/database-extensions.cs +1 -1
- package/framework/templates/code/dotnet/extensions/result-extensions.cs +27 -0
- package/framework/templates/code/dotnet/feature/endpoint.cs.hbs +2 -2
- package/framework/templates/docs/plan.md +72 -0
- package/framework/templates/dotnet/ai-kit/README.md +1 -9
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaDisclosureTests.cs +1 -1
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Morph.AiKit.Tests.csproj +0 -10
- package/framework/templates/infrastructure/docker/coolify.template.json +3 -3
- package/framework/templates/infrastructure/github/README.md +2 -1
- package/framework/templates/infrastructure/github/workflows/deploy-coolify.yml.hbs +2 -1
- package/framework/templates/meta-prompts/squad-leaders/backend-squad.md +1 -1
- package/framework/templates/meta-prompts/squad-leaders/frontend-squad.md +1 -1
- package/framework/templates/meta-prompts/squad-leaders/squad-leader.md +1 -1
- package/framework/templates/meta-prompts/validators/pre-commit-validator.md +3 -4
- package/package.json +1 -1
- package/src/commands/e2e/e2e.js +2 -2
- package/src/commands/observability/cost.js +18 -60
- package/src/commands/observability/telemetry.js +3 -5
- package/src/commands/project/doctor-procs.js +1 -1
- package/src/commands/project/doctor.js +9 -9
- package/src/commands/project/fleet.js +4 -4
- package/src/commands/project/heavy.js +3 -3
- package/src/commands/project/init.js +6 -1
- package/src/commands/project/setup-infra-cmd.js +2 -1
- package/src/commands/project/stack-scan.js +58 -0
- package/src/commands/project/standards.js +79 -25
- package/src/commands/project/status.js +29 -69
- package/src/commands/project/update.js +33 -19
- package/src/commands/project/worktree.js +1 -1
- package/src/commands/state/advance.js +62 -46
- package/src/commands/state/approve.js +95 -138
- package/src/commands/state/archive.js +20 -84
- package/src/commands/state/auto-approval.js +68 -0
- package/src/commands/state/create.js +28 -1
- package/src/commands/state/delete.js +1 -1
- package/src/commands/state/finish.js +11 -23
- package/src/commands/state/gate-check.js +86 -95
- package/src/commands/state/gate-decision.js +6 -4
- package/src/commands/state/handoff.js +1 -1
- package/src/commands/state/list.js +9 -9
- package/src/commands/state/report-check.js +157 -311
- package/src/commands/state/retype.js +9 -3
- package/src/commands/validation/mutate.js +77 -14
- package/src/commands/validation/plan-check.js +81 -0
- package/src/commands/validation/validate-feature.js +60 -135
- package/src/commands/validation/verify.js +41 -82
- package/src/core/paths/output-schema.js +20 -67
- package/src/core/state/gate-order.js +5 -6
- package/src/core/state/lifecycle-audit.js +2 -2
- package/src/core/state/state-manager.js +17 -98
- package/src/core/templates/template-registry.js +2 -2
- package/src/core/templates/template-seed.js +22 -0
- package/src/core/work-types.js +10 -10
- package/src/dashboard/app/App.jsx +0 -2
- package/src/dashboard/app/components/ActivityFeed.jsx +2 -3
- package/src/dashboard/app/components/CommandPalette.jsx +7 -8
- package/src/dashboard/app/components/EntityLink.jsx +1 -2
- package/src/dashboard/app/components/Markdown.jsx +1 -1
- package/src/dashboard/app/components/Sidebar.jsx +1 -2
- package/src/dashboard/app/hooks/useMorphQuery.js +1 -1
- package/src/dashboard/app/lib/phases.js +2 -4
- package/src/dashboard/app/pages/Activity.jsx +1 -1
- package/src/dashboard/app/pages/FeatureDetail.jsx +139 -129
- package/src/dashboard/app/pages/Features.jsx +9 -9
- package/src/dashboard/app/pages/Guide.jsx +2 -2
- package/src/dashboard/app/pages/PhasePipeline.jsx +3 -4
- package/src/dashboard/app/pages/RulesMap.jsx +3 -3
- package/src/dashboard/app/pages/SkillsLibrary.jsx +3 -3
- package/src/dashboard/app/pages/Standards.jsx +1 -1
- package/src/dashboard/scanner/activity-scanner.js +6 -16
- package/src/dashboard/scanner/agents-scanner.js +1 -1
- package/src/dashboard/scanner/docs-scanner.js +5 -23
- package/src/dashboard/scanner/features-scanner.js +95 -60
- package/src/dashboard/scanner/index.js +0 -2
- package/src/dashboard/scanner/project-api.js +1 -1
- package/src/dashboard/scanner/rules-scanner.js +15 -10
- package/src/dashboard/scanner/skills-scanner.js +2 -3
- package/src/dashboard/scanner/standards-scanner.js +2 -1
- package/src/lib/ci/ci-verify.js +17 -1
- package/src/lib/ci/github-ci.js +1 -1
- package/src/lib/detectors/index.js +3 -8
- package/src/lib/generators/handoff-generator.js +34 -65
- package/src/lib/generators/settings-generator.js +11 -89
- package/src/lib/git/evidence-staleness.js +1 -1
- package/src/lib/git/tree-fingerprint.js +19 -7
- package/src/lib/git/tree-state.js +2 -2
- package/src/lib/heavy/cleanup.js +1 -5
- package/src/lib/installers/memory-installer.js +6 -8
- package/src/lib/mutation/commands.js +3 -2
- package/src/lib/{tasks/dotnet-test-introspection.js → mutation/dotnet-introspection.js} +17 -282
- package/src/lib/mutation/plan.js +14 -6
- package/src/lib/mutation/runner.js +1 -1
- package/src/lib/mutation/subset.js +46 -9
- package/src/lib/plan/artifact-vocabulary.js +60 -0
- package/src/lib/plan/checks.js +234 -0
- package/src/lib/plan/plan-parser.js +209 -0
- package/src/lib/plan/plan-template.js +18 -0
- package/src/lib/review-reports.js +222 -0
- package/src/lib/risk-detector.js +134 -135
- package/src/lib/specs/adr-index.js +50 -69
- package/src/lib/specs/design-seed.js +18 -0
- package/src/lib/specs/frontmatter.js +44 -0
- package/src/lib/specs/gfm-table.js +17 -0
- package/src/lib/specs/old-format.js +68 -0
- package/src/lib/specs/revocations.js +37 -95
- package/src/lib/specs/screen-checklist.js +18 -17
- package/src/lib/stack/dotnet-build-ignores.js +47 -0
- package/src/lib/stack/stack-profile.js +1 -1
- package/src/lib/stack/stack-scan.js +267 -0
- package/src/lib/standards/registry.js +43 -0
- package/src/lib/standards/sections.js +58 -0
- package/src/lib/tasks/eval-node.js +4 -12
- package/src/lib/tasks/test-nodes.js +1 -74
- package/src/lib/tasks/test-runner.js +75 -117
- package/src/lib/telemetry/metrics.js +8 -69
- package/src/lib/telemetry/telemetry-reader.js +5 -118
- package/src/lib/telemetry/verify-event.js +5 -7
- package/src/lib/validators/code-budget/code-budget-validator.js +1 -1
- package/src/lib/validators/contracts/contract-compliance-validator.js +2 -2
- package/src/lib/validators/reuse/reuse-validator.js +24 -48
- package/src/lib/validators/reuse/symbol-scanner.js +2 -4
- package/src/lib/validators/traceability-check.js +85 -129
- package/src/lib/validators/validation-runner.js +8 -88
- package/src/lib/validators/verify-runner.js +134 -301
- package/src/lib/worktree/docker-audit.js +1 -2
- package/src/lib/worktree/fleet-scanner.js +25 -38
- package/src/scripts/setup-infra.js +42 -22
- package/src/utils/agents-installer.js +92 -13
- package/src/utils/claude-settings-manager.js +0 -35
- package/src/utils/file-copier.js +34 -6
- package/src/utils/hooks-installer.js +16 -9
- package/src/utils/skills-installer.js +1 -2
- package/framework/commands/commit.md +0 -166
- package/framework/evals/trace-schema.md +0 -67
- package/framework/hooks/claude-code/core/tasks-json-guard.js +0 -83
- package/framework/hooks/claude-code/core/trace-autogen.js +0 -277
- package/framework/hooks/git/pre-commit/specs.sh +0 -50
- package/framework/hooks/shared/tasks-validator.js +0 -111
- package/framework/rubrics/backend.json +0 -41
- package/framework/rubrics/default.json +0 -36
- package/framework/rubrics/frontend.json +0 -36
- package/framework/rules/morph-task-tracking.md +0 -54
- package/framework/rules/morph-workflow.md +0 -244
- package/framework/schemas/tasks.schema.json +0 -79
- package/framework/skills/core/morph-brainstorming/SKILL.md +0 -161
- package/framework/skills/core/morph-implement/SKILL.md +0 -194
- package/framework/skills/core/morph-proposal/SKILL.md +0 -152
- package/framework/skills/core/morph-stack-scan/SKILL.md +0 -145
- package/framework/templates/docs/proposal.md +0 -192
- package/framework/templates/docs/spec.md +0 -57
- package/framework/templates/docs/ui-components.md +0 -52
- package/framework/templates/docs/ui-design-system.md +0 -76
- package/framework/templates/docs/ui-flows.md +0 -167
- package/framework/templates/examples/spec-examples.md +0 -91
- package/framework/templates/feature/decisions.md +0 -124
- package/framework/templates/feature/recap.md +0 -145
- package/framework/templates/project/validate.js +0 -97
- package/framework/templates/tasks.template.json +0 -17
- package/src/commands/state/usecase.js +0 -143
- package/src/commands/tasks/dag.js +0 -181
- package/src/dashboard/app/pages/Rubrics.jsx +0 -97
- package/src/dashboard/scanner/rubrics-scanner.js +0 -12
- package/src/lib/agents/output-collector.js +0 -76
- package/src/lib/evaluator-report.js +0 -91
- package/src/lib/specs/acervo-format.js +0 -70
- package/src/lib/specs/acervo-lifecycle.js +0 -264
- package/src/lib/specs/done-criteria-check.js +0 -200
- package/src/lib/specs/usecase-check.js +0 -301
- package/src/lib/specs/usecase-promoter.js +0 -301
- package/src/lib/specs/usecase-registry.js +0 -237
- package/src/lib/tasks/dispatch-planner.js +0 -319
- package/src/lib/tasks/mermaid-renderer.js +0 -132
- package/src/lib/tasks/task-classifier.js +0 -30
- package/src/lib/tasks/task-parser.js +0 -209
- package/src/lib/tasks/tasks-json-parser.js +0 -296
- package/src/lib/tasks/test-scope.js +0 -597
- package/src/lib/validators/architecture/architecture-validator.js +0 -270
- package/src/lib/validators/architecture/index.js +0 -7
- package/src/lib/validators/css/css-validator.js +0 -340
- package/src/lib/validators/css/index.js +0 -7
- package/src/lib/validators/design-system/design-system-validator.js +0 -237
- package/src/lib/validators/design-system/index.js +0 -7
- package/src/lib/validators/score-aggregator.js +0 -244
- package/src/lib/validators/ui/index.js +0 -7
- package/src/lib/validators/ui/ui-contrast-validator.js +0 -422
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
name: morph-media
|
|
3
3
|
description: Conduz a AUTORIA de mídia gerada por IA — escolher o modelo pelo trabalho, montar o prompt como spec versionada, encadear derivadas a partir de um herói aprovado, subir a escada de custo e conduzir o gate humano de escolha entre N candidatas. É o lado processo; o conhecimento de API, custo e conformidade vive nos standards de mídia.
|
|
4
4
|
version: core
|
|
5
|
-
|
|
6
|
-
user-
|
|
7
|
-
cliVersion: "
|
|
5
|
+
when_to_use: Use quando a tarefa for PRODUZIR imagem ou vídeo por IA (catálogo, marketing, asset de LP) e alguém precisar decidir modelo, prompt e aprovação
|
|
6
|
+
user-invocable: true
|
|
7
|
+
cliVersion: "9.0.0"
|
|
8
8
|
stacks:
|
|
9
9
|
- dotnet
|
|
10
10
|
- nextjs
|
|
@@ -1,307 +1,145 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: morph-plan
|
|
3
|
-
description:
|
|
3
|
+
description: Leva uma feature do pedido ao plano aprovado — roteia o tipo de trabalho, varre o ambiente, conduz a entrevista pela árvore de decisões, escreve 2-plan/plan.md, extrai checks.json com plan-check e apresenta o gate do plano.
|
|
4
4
|
version: core
|
|
5
|
-
|
|
6
|
-
user-
|
|
7
|
-
cliVersion: "
|
|
5
|
+
when_to_use: Use quando uma feature, bug ou chore começar ("/morph-proposal {feature}", "vamos planejar X"), ou ao retomar uma feature cujo gate plan ainda não foi aprovado
|
|
6
|
+
user-invocable: true
|
|
7
|
+
cliVersion: "9.0.0"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# morph-plan
|
|
11
11
|
|
|
12
|
-
##
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
3
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
`Id` é `UC-{nn}` ou `{feature}/ADR-{nnn}`. UC revogado exige `Substituto`; `parcial` exige
|
|
149
|
-
`Escopo`. O `finish` aplica as linhas válidas e devolve as malformadas em `revocationProblems`.
|
|
150
|
-
**Rode `morph-spec usecase check {feature}` logo depois de escrever a seção** — o spec congela no
|
|
151
|
-
Gate 2.
|
|
152
|
-
|
|
153
|
-
4. **Seção `## Contrato de implementação` do `spec.md`** — o que quem implementa precisa saber e o
|
|
154
|
-
código não diz. Curta; o resto já está nos standards que cada task carrega.
|
|
155
|
-
- **Standards:** `morph-spec standards --find "<domínio>"` por domínio tocado (o digest decide);
|
|
156
|
-
liste os ids. Inclua `architecture-code-comments` e o standard de teste do stack. Feature com
|
|
157
|
-
agente MAF: os `standards/ai-agents/*.md` que ela exige (`--category ai-agents`) — convenção de
|
|
158
|
-
projeto vem deles; superfície da API pode vir do context7.
|
|
159
|
-
- **Proibições desta feature** além das de `MORPH.md` § "Stack baked-in", quando houver.
|
|
160
|
-
- **Verificação de runtime** — como se prova que a feature funciona rodando:
|
|
161
|
-
- O stack sobe pelo `docker compose` do projeto (`morph-spec e2e up {feature}`). Projeto que
|
|
162
|
-
containeriza sem compose: **isso é uma task**.
|
|
163
|
-
- Os fluxos que o avaliador vai navegar, nos verbos das pós-condições; quais viram spec
|
|
164
|
-
Playwright (caminho crítico e bug corrigido).
|
|
165
|
-
- Base URL do ambiente: `process.env.PLAYWRIGHT_BASE_URL ?? \`http://localhost:${process.env.PORT ?? 3000}\``,
|
|
166
|
-
compose publicando `"${PORT:-3000}:3000"` e sem `container_name` (standard
|
|
167
|
-
`infrastructure/docker/local-compose-isolation`). Cravado: **isso é uma task**.
|
|
168
|
-
- App com login: `e2e.auth` em `config.json` (`mode: seed|storageState|bypass|none`,
|
|
169
|
-
`seedCommand`, `storageStatePath`, `envFile`), credenciais num `.env.e2e` gitignored.
|
|
170
|
-
**`mode` é obrigatório sempre que houver `seedCommand`** — sem ele o seed fica inerte. Sem setup de
|
|
171
|
-
login, crie a task.
|
|
172
|
-
- Não se aplica (biblioteca pura): registre a dispensa e o porquê.
|
|
173
|
-
- **Baseline é um COMANDO, nunca um número.** O spec congela no Gate 2 e é lido por dias: número
|
|
174
|
-
cravado (`2366 passando`) está errado na primeira task, e quem confia nele "conserta" o que não
|
|
175
|
-
quebrou. Registre como medir (`npm test`, `dotnet test`); o `expectedCount` de `project.tests[]`
|
|
176
|
-
é gravado por `morph-spec verify {feature} --record-baseline`, nunca digitado.
|
|
177
|
-
- **Pré-requisito é um PREDICADO, nunca um SHA literal**: "`git merge-base --is-ancestor
|
|
178
|
-
origin/main HEAD` sai 0", não "confirme que main contém `49dfba2`" — o SHA muda no primeiro
|
|
179
|
-
squash.
|
|
180
|
-
|
|
181
|
-
5. Produza `tasks.json` em `.morph/features/{feature}/2-plan/` seguindo o schema
|
|
182
|
-
`.morph/framework/schemas/tasks.schema.json` (o hook `tasks-json-guard` valida cada write):
|
|
183
|
-
|
|
184
|
-
```json
|
|
185
|
-
{
|
|
186
|
-
"version": "1.0",
|
|
187
|
-
"feature": "{feature-name}",
|
|
188
|
-
"tasks": [
|
|
189
|
-
{
|
|
190
|
-
"id": "T1",
|
|
191
|
-
"title": "Título curto",
|
|
192
|
-
"description": "O que esta task realiza e por quê",
|
|
193
|
-
"dependencies": [],
|
|
194
|
-
"effort": "S",
|
|
195
|
-
"doneCriteria": "P2 — Cada veterinário traz suas especialidades em lista, nunca string concatenada",
|
|
196
|
-
"status": "pending",
|
|
197
|
-
"outputs": ["src/Vets/ListVets.cs", "tests/Vets/ListVetsTests.cs"],
|
|
198
|
-
"group": "backend",
|
|
199
|
-
"usecase": "UC-07",
|
|
200
|
-
"agent": "dotnet-senior",
|
|
201
|
-
"standards": ["standards/backend/dotnet/vsa-handler-patterns.md"],
|
|
202
|
-
"reuse": [{ "concept": "VetDto", "verdict": "CRIAR", "why": "graph explain VetDto → not-found; grep -rn VetDto → 0" }]
|
|
203
|
-
}
|
|
204
|
-
]
|
|
205
|
-
}
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
- `id` `T\d+`; `dependencies` com ids Tn; `effort` S (≤30min) | M (≤1h) | L (≤2h) | XL (>2h);
|
|
209
|
-
`status` nasce `pending`; `group` backend | frontend | tests | infra | docs.
|
|
210
|
-
- `usecase`: o **id** (`UC-07`), nunca o nome do arquivo.
|
|
211
|
-
- `outputs`: paths planejados — o `dag` detecta colisão entre fluxos paralelos por eles.
|
|
212
|
-
**No máximo 8 `outputs` por task** (testes incluídos): acima disso o sub-agente bate no teto de
|
|
213
|
-
turnos; o `dag` recusa antes do Gate 2.
|
|
214
|
-
|
|
215
|
-
**5a. Carimbe `agent` e `standards`** com UMA leitura de `.morph/framework/agents.json`: `agent` é
|
|
216
|
-
o id da persona (sem `morph-`) cujo `domains` cobre o domínio da task; `standards`, o array dela
|
|
217
|
-
mais o que a task exige. **Persona com `surfaces`** (a `ui-designer`): some a lista da superfície
|
|
218
|
-
que o checklist de tela do `1-design/mockups.md` declara em `Superfície`, nunca de outra; sem
|
|
219
|
-
mockup, escolha pela tela e registre em `decisions.md`. Task que cria ou altera UI carimba
|
|
220
|
-
`agent: "ui-designer"` mesmo sem o ramo uiux. Task sem persona clara (config, docs) fica sem `agent`.
|
|
221
|
-
|
|
222
|
-
**5b. Carimbe `reuse`** na task que escreve cada conceito do passo 1c: `concept`, `verdict`,
|
|
223
|
-
`target` (o que reusar ou estender) e, em `CRIAR`, `why`. Conceito sem task: falta task ou o
|
|
224
|
-
conceito não é desta feature — resolva antes do Gate 2.
|
|
225
|
-
|
|
226
|
-
**O `doneCriteria` carrega a pós-condição LITERAL**, prefixada pelo rótulo (`"P2 — Cada
|
|
227
|
-
veterinário traz..."`). Reescrever com outras palavras é onde o requisito se perde. Toda
|
|
228
|
-
pós-condição de todo UC tem ao menos uma task.
|
|
229
|
-
|
|
230
|
-
**`morph-spec dag {feature}` cobra o encanamento.** Ele reporta UC inexistente (erro), pós-condição sem task e `doneCriteria` parafraseado (avisos), e `doneCriteria` com vocabulário de artefato (`grep`, "contém a string", "o binário", "nenhum arquivo", "arquivo/pasta/diretório em", glob `**/`) sem `Por que artefato:` (aviso). Também aponta task sobre UC `superseded` e linha de revogação que o `finish` não aplicaria.
|
|
231
|
-
|
|
232
|
-
**Orçamento de teste por task.** Cada pós-condição compra **um** teste, cada bug corrigido **um** de
|
|
233
|
-
regressão; acima disso, uma linha de justificativa na `description`. Cenários do mesmo
|
|
234
|
-
comportamento são linhas de tabela (`[Theory]`/`it.each`). **Nenhum teste que só fixa texto**
|
|
235
|
-
(copy, config, prosa). O `verify` avisa quando o teste adicionado passa de 1,5× a produção.
|
|
236
|
-
|
|
237
|
-
**Critério sobre saída de LLM vira eval de runtime — nunca "suíte estrutural".** Vale quando a seção
|
|
238
|
-
de contrato cita um standard `ai-agents` e o `doneCriteria` julga o que o modelo *responde*:
|
|
239
|
-
- a prova é um **eval de runtime**; a evidência vai em
|
|
240
|
-
`.morph/features/{feature}/3-implement/evidencias/{taskId}.md`, e esse path entra em
|
|
241
|
-
`outputs` — é por ele que implementador e avaliador sabem que ela é devida. Com nó
|
|
242
|
-
`runner: "evals"` (standard `ai-agents-evals-with-cache`), o cenário mora no dataset do nó;
|
|
243
|
-
- **no máximo 1 teste de estrutura** da fonte do prompt — nunca vocabulário do que o modelo
|
|
244
|
-
deveria dizer;
|
|
245
|
-
- as duas coisas vão na `description` da task.
|
|
246
|
-
|
|
247
|
-
**5c. Cross-check do `1-design/` — todo aviso de capacidade tem destino.** Com o diretório
|
|
248
|
-
presente, antes de fechar o array `tasks`:
|
|
249
|
-
|
|
250
|
-
```bash
|
|
251
|
-
grep -riE "capacidade nova|precisa de backend|dimensionar junto" .morph/features/{feature}/1-design/
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
Cada ocorrência vira **task irmã** ou exclusão registrada em `decisions.md` com o motivo —
|
|
255
|
-
**nunca fica sem destino**. Sem hits, ou sem `1-design/`, o passo é um no-op.
|
|
256
|
-
|
|
257
|
-
**5d. O checklist de tela vira critério.** A task que entrega uma `## Tela:` do
|
|
258
|
-
`1-design/mockups.md` carrega no `doneCriteria` as decisões do `### Checklist de tela` (volume,
|
|
259
|
-
paginação, ordenação, filtro, os três estados, mobile, abas), citando a seção por path
|
|
260
|
-
(`1-design/mockups.md#tela-…`) — "lista pagina no servidor, 25 por página" é critério; "conforme
|
|
261
|
-
o mockup" não é. Item "não se aplica" não vira critério.
|
|
262
|
-
|
|
263
|
-
Antes de retornar, valide rodando `morph-spec dag {feature}` — schema do tasks.json (ids, enums,
|
|
264
|
-
dependências) e a análise de DAG que a `/morph-apply` vai usar.
|
|
265
|
-
|
|
266
|
-
6. Apresente o Gate 2 segundo trust mode.
|
|
267
|
-
|
|
268
|
-
Rode `morph-spec gate-check {feature} plan [--json]` — decide pelos sinais do disco e persiste
|
|
269
|
-
`gateDecisions.plan`. Divergência de design system do Gate 1 sem resolução, ou violação de
|
|
270
|
-
standard, entram por `--signals` (as únicas chaves aceitas):
|
|
271
|
-
```
|
|
272
|
-
morph-spec gate-check {feature} plan --signals '{"designSystemDivergence":true,"standardsViolations":["<id>"]}'
|
|
273
|
-
```
|
|
274
|
-
Risco que nenhuma chave representa: `gate-decision` direto. Nunca edite `feature.json` à mão.
|
|
275
|
-
`morph-spec dag {feature} --mermaid` dá o diagrama do plano para o gate.
|
|
276
|
-
|
|
277
|
-
**Se `pause === true`**, `AskUserQuestion`:
|
|
278
|
-
|
|
279
|
-
```
|
|
280
|
-
question: "Gate 2 — Plano de {feature} aprovado?{ reason ? ' Sinal: ' + reason : '' }"
|
|
281
|
-
header: "Gate 2"
|
|
282
|
-
options:
|
|
283
|
-
- { label: "aprovado, prosseguir", description: "Aceitar use cases, spec e tasks e habilitar /morph-apply" }
|
|
284
|
-
- { label: "preciso ajustar", description: "Apontar mudanças no plano antes de prosseguir" }
|
|
285
|
-
- { label: "cancelar feature", description: "Abortar" }
|
|
286
|
-
```
|
|
287
|
-
|
|
288
|
-
**Se `pause === false`**: resumo de 3 linhas (problema → solução; tasks e esforço; caminho
|
|
289
|
-
crítico) e `morph-spec approve {feature} plan --mode auto` (ou `advance {feature}`). A pergunta
|
|
290
|
-
nomeia a feature — é por ela que o hook `state-sync` grava a aprovação.
|
|
291
|
-
|
|
292
|
-
Aprovado o Gate 2, o frontmatter de cada use case passa de `status: draft` a `status: approved`.
|
|
293
|
-
O `finish` os promove ao acervo com `status: implemented`.
|
|
294
|
-
|
|
295
|
-
## Output esperado
|
|
296
|
-
|
|
297
|
-
- `2-plan/usecases/UC-{nn}-{slug}.md` — pós-condições testáveis
|
|
298
|
-
- `2-plan/spec.md` — arquitetura, seção de revogação e `## Contrato de implementação`
|
|
299
|
-
- `2-plan/tasks.json` — válido contra o schema, `doneCriteria` literal, `agent`/`standards`/`reuse`
|
|
300
|
-
carimbados, `3-implement/evidencias/{taskId}.md` em `outputs` nas tasks de critério sobre LLM
|
|
301
|
-
- Gate 2 registrado em `feature.json`
|
|
302
|
-
|
|
303
|
-
## Referências
|
|
304
|
-
|
|
305
|
-
- `.morph/framework/MORPH.md` — §2 (fases), §3 (contratos de output), §5 (gates)
|
|
306
|
-
- `morph-spec standards --find|graph explain|graph affected --uses-only|usecase reserve|usecase check|dag` — `.morph/framework/CLI.md`
|
|
307
|
-
- `.morph/framework/schemas/tasks.schema.json`
|
|
12
|
+
## 0. Contrato
|
|
13
|
+
|
|
14
|
+
Saída: `.morph/features/{feature}/2-plan/plan.md` (fonte única da feature) e `2-plan/checks.json`, gravado só por `morph-spec plan-check`. O usuário só toca a entrevista e o gate; o resto você resolve. Nada de código nesta fase. O `create` escreve o esqueleto de `plan.md` no nascimento: só é retomada com `2-plan/checks.json` no disco ou com o `plan.md` já sem os `<…>` do esqueleto — aí vá ao §5 (corrigir) ou ao §7 (gate).
|
|
15
|
+
|
|
16
|
+
## 1. Roteamento
|
|
17
|
+
|
|
18
|
+
Sem nome de feature, pergunte (`AskUserQuestion`, header "Feature"). Feature que ainda não existe (sem `feature.json`), uma vez só:
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
morph-spec create {feature} --request "<pedido do usuário>"
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Tipo óbvio pelo pedido: `--type <tipo> --description "<o quê/porquê>"`. O `--request` semeia a descrição; sem ele nem `--description`, o `create` recusa. **Exit 2** (empate ou nenhum sinal): você é o roteador — escolha entre os `candidates` e re-rode com `--type <tipo> --request "<pedido>"`. `AskUserQuestion` só quando o pedido é genuinamente indeterminado.
|
|
25
|
+
|
|
26
|
+
| Tipo | Caminho |
|
|
27
|
+
|---|---|
|
|
28
|
+
| `hotfix` | `Skill(morph-hotfix)` com o nome e **encerre** esta skill |
|
|
29
|
+
| `chore` | plan.md curto (§8), `plan-check`, e `Skill(morph-apply)` direto — a única exceção ao §9 |
|
|
30
|
+
| `bug` | fluxo inteiro em modo bug-lean (§8) |
|
|
31
|
+
| `feature` | fluxo inteiro (§2–§7) |
|
|
32
|
+
|
|
33
|
+
## 2. Varredura — antes de qualquer pergunta
|
|
34
|
+
|
|
35
|
+
Fato não se pergunta: as decisões são do usuário, os fatos são seus.
|
|
36
|
+
|
|
37
|
+
1. `morph-spec stack-scan {feature}` → `2-plan/stack-scan.md`. Greenfield sai curto; em brownfield lista desvios por severidade contra `project.stack`. Desvio Bloqueante ou Alto vira um nó da árvore ("a migração entra nesta feature ou vira feature separada?") — **dentro** da árvore, nunca uma pergunta antes dela.
|
|
38
|
+
2. Leia `.morph/config/config.json`, `.morph/context/` (o inventário `README.md` dá componentes e endpoints; `morph-spec context refresh` o regera), as features ativas e o índice de ADRs `.morph/specs/adrs/`. Decisão vigente é a do índice; `decisions.md` e use cases de `.morph/archive/` são **história, não instrução** — abra um só para entender por que algo é como é.
|
|
39
|
+
3. **Conflitos com o acervo — avise, não entreviste.** Para cada ADR ou documento de `.morph/context/` que o pedido contradiz: uma linha de aviso no resumo que abre o §3 (fonte, o que diz, o que o pedido muda). **Pedido explícito sobre o ponto → vale o mais novo**, e você segue. Só entra na árvore o conflito que o pedido deixa **ambíguo** ("o admin passa a Geist" não diz nada da vitrine: a vitrine é decisão, o admin não). Todo conflito, decidido ou não, vai para `### Conflitos com o acervo` do plan.md.
|
|
40
|
+
4. **Design system:** compare `.morph/context/design-system.md` com o detectado e com mocks recentes do usuário. Divergência (tokens, versão, fonte aprovada) é **decisão da árvore** e sinal `designSystemDivergence` no §7. Resolvida, **reescreva o corpo** do arquivo com a fonte escolhida — a seção que descrevia a antiga passa a descrever a nova, com o escopo onde o valor antigo ainda vale; o changelog guarda **só data e motivo**, nunca o valor novo. Este é o protocolo que a `morph-uiux` reaplica.
|
|
41
|
+
|
|
42
|
+
## 3. Árvore de decisões e modo
|
|
43
|
+
|
|
44
|
+
Entra na árvore só o que (a) muda escopo, comportamento ou arquitetura e (b) a varredura não respondeu. Ordene pelo que **poda**: "síncrono ou assíncrono?" vem antes de "qual política de retry". Publique a árvore ao usuário antes de perguntar.
|
|
45
|
+
|
|
46
|
+
**Pergunta de abertura** (só `feature` e `bug`; `chore` e `hotfix` não passam por aqui): uma `AskUserQuestion`, header "Descoberta", com a árvore resumida e o modo recomendado em primeiro lugar com `(Recomendado)` no label. Muitas decisões, ou decisões acopladas → entrevista; árvore rasa → automático.
|
|
47
|
+
|
|
48
|
+
- **Entrevista:** **uma pergunta por chamada** de `AskUserQuestion` — lote desorienta e impede que uma resposta pode ramos. Cada pergunta traz a resposta recomendada como primeira opção, `(Recomendado)`. Mostre a árvore quando ela mudar de forma. Termina quando a árvore zera; o usuário pode encerrar antes, e o que ficou aberto vira `## Fora de escopo`. O gate do plano pausa sempre neste modo (§7).
|
|
49
|
+
- **Automático:** até 4 perguntas, **só sobre nós abertos** da árvore — nunca uma lista fixa. Árvore vazia → nenhuma pergunta.
|
|
50
|
+
|
|
51
|
+
**Headless** (`AskUserQuestion` indisponível ou negada, como sob `claude -p`): nunca decida você os nós abertos. Escreva-os em texto, numerados, cada um com a resposta recomendada; rode `morph-spec gate-decision {feature} plan --pause true --reason "entrevista headless"` e **encerre o turno**. Retome quando o usuário responder.
|
|
52
|
+
|
|
53
|
+
## 4. Território
|
|
54
|
+
|
|
55
|
+
Feature grande ou brownfield: despache `subagent_type: "morph-scout"` (não registrado: `general-purpose` com o campo `persona` do `scout` de `.morph/framework/agents.json`) para os arquivos que a feature toca e o blast radius dos símbolos centrais. Grave em `2-plan/scout-map.md` e audite:
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
morph-spec scout-check .morph/features/{feature}/2-plan/scout-map.md --json
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Exit ≠ 0 → descarte o mapa e re-despache **uma** vez com as `failures` coladas; segunda reprovação: grep você mesmo. Mapa aprovado prova que as citações existem, não que a conclusão está certa — confira com grep próprio o Inferido que muda o plano. Pular o scout numa feature pequena no domínio carregado: uma linha em `## Arquitetura`.
|
|
62
|
+
|
|
63
|
+
**Reuso — o que já existe.** Para cada conceito central (entidade, DTO, componente, hook, helper, dublê de teste): `morph-spec graph explain <nome> --json` e `morph-spec graph affected <nome> --uses-only --json`. Antes, `morph-spec graph status --json`; stale numa worktree → `morph-spec graph refresh`. `--uses-only` importa: o grep conta herança como uso — no ProspectPRO apontou 23 arquivos onde 20 eram interfaces filhas herdando o contrato e só 2 usavam de verdade. **Sem grafo** (`no-graph`, `not-found` num grafo stale), caia para `grep -rn "<nome>"` e registre que a contagem veio do grep, que superestima consumidores. A ausência de grafo nunca bloqueia.
|
|
64
|
+
|
|
65
|
+
## 5. plan.md
|
|
66
|
+
|
|
67
|
+
O `create` já escreveu o esqueleto em `2-plan/plan.md` (leia e preencha; `chore` e `hotfix` nascem com o gate carimbado e criam o arquivo numa única escrita); gramática completa: `morph-spec plan-check --help`. `plan-check` é o único leitor; o que ele não reconhece, ninguém lê.
|
|
68
|
+
|
|
69
|
+
**Cenários** (`## Cenários`): `- **Cn** — Dado …, quando …, então …`, com `prova:` (`teste` | `e2e` | `eval` | `manual`) **na linha seguinte, sem linha em branco** — linha vazia encerra o cenário.
|
|
70
|
+
- **Observável em teste**: que asserção eu escreveria? Sem resposta, reescreva ou descarte.
|
|
71
|
+
- **Artefato não é comportamento.** Cenário que cita `grep`, "contém a string", "o binário", "nenhum arquivo", "arquivo/pasta/diretório em" ou glob `**/` descreve o repositório. Tente o efeito em runtime; se o artefato É o entregável, justifique em `> Por que artefato:` logo abaixo (nunca na mesma linha, nunca `> [!note]`).
|
|
72
|
+
- **Saída de LLM** (o que o modelo responde) prova-se por `eval` de runtime, nunca pelo texto do prompt: evidência em `3-implement/evidencias/{Cn}.md`, path listado em `arquivos:` da fatia; com nó `runner: "evals"` (standard `ai-agents-evals-with-cache`) o cenário mora no dataset. No máximo 1 teste de estrutura da fonte do prompt.
|
|
73
|
+
- **"O comando de teste da raiz roda de ponta a ponta"** prova-se pelo `verify {feature}` (o nó `e2e` e o nó de teste `e2e: true` já percorrem a cadeia): nomeie essa rodada como a prova, nunca uma execução avulsa. Precisando mesmo rodar fora dele, numa linha só (o Bash não guarda o env entre chamadas): `eval "$(morph-spec env {feature})" && morph-spec heavy run -- <comando>` — o `COMPOSE_PROJECT_NAME` da feature é o que o `finish` derruba com os volumes. `prova: manual` registra passo e resultado em `3-implement/evidencias/{Cn}.md`.
|
|
74
|
+
- **Orçamento de teste**: um teste por cenário, um de regressão por bug; acima disso, uma linha de porquê. Cenários do mesmo comportamento são linhas de tabela (`[Theory]`/`it.each`); nenhum teste que só fixa texto. O `verify` avisa quando o teste passa de 1,5× a produção.
|
|
75
|
+
|
|
76
|
+
```markdown
|
|
77
|
+
## Cenários
|
|
78
|
+
- **C1** — Dado um tenant com `criterion_overrides`, quando ele é publicado, então a publicação é recusada nomeando a chave.
|
|
79
|
+
prova: teste
|
|
80
|
+
- **C2** — Nenhum arquivo em `tenants/**` contém a chave `criterion_overrides`.
|
|
81
|
+
prova: teste
|
|
82
|
+
> Por que artefato: a chave saiu do contrato; nenhum leitor de runtime a consulta.
|
|
83
|
+
|
|
84
|
+
## Fatias
|
|
85
|
+
### F1 — Recusar a chave na publicação
|
|
86
|
+
- persona: dotnet-senior
|
|
87
|
+
- standards: backend-dotnet-vsa-handler-patterns, backend-dotnet-testing, architecture-code-comments
|
|
88
|
+
- arquivos: src/Tenants/Publish.cs, tests/Tenants/PublishTests.cs
|
|
89
|
+
- cobre: C1, C2
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
**Decisões** (`## Decisões`): uma `### ADR-001 — título` por decisão não trivial (alternativa descartada, motivo, quem decidiu), com `**Alcance:** feature` ou `projeto` — `projeto` quando vale além desta feature. Em projeto greenfield, a decisão que fixa stack, layout, infraestrutura ou test runner é `projeto`: a próxima feature a herda, e só o índice de ADRs a mostra. `### Conflitos com o acervo` existe sempre; "nenhum" vale. Proibição além das de `MORPH.md` § "Stack baked-in" é ADR.
|
|
93
|
+
|
|
94
|
+
**Arquitetura**: componentes, fluxo de dados, edge cases **técnicos** e integrações; não repita os cenários.
|
|
95
|
+
|
|
96
|
+
**Reuso**: tabela `| conceito | veredito | alvo | why |`, veredito `REUSAR` | `ESTENDER` | `CRIAR`. **`CRIAR` exige `why`** — a consulta que respondeu "não existe" (`graph explain X → not-found; grep -rn X → 0`). Conceito de duas features vai para um módulo comum, nunca import cruzado entre slices. O validador `reuse` do `verify` cobra: símbolo novo homônimo de um existente reprova na mesma feature e avisa entre features; `CRIAR` declarado rebaixa a aviso. Conceito sem fatia que o escreva: falta fatia ou o conceito não é desta feature — resolva antes do gate.
|
|
97
|
+
|
|
98
|
+
**Fatias** (`### Fn — título`): a unidade de entrega e de relatório (`3-implement/reports/Fn.md`).
|
|
99
|
+
- `persona:` obrigatório — o id sem `morph-`, cujo `domains` cobre a fatia (uma leitura de `agents.json`). Fatia que cria ou altera UI é `ui-designer`, mesmo sem o ramo de design; com `superfície:`, os standards são os daquela chave de `surfaces`.
|
|
100
|
+
- `standards:` — `morph-spec standards --find "<domínio>"` por domínio (o digest decide): os da persona mais o que a fatia exige, sempre `architecture-code-comments` e o de teste do stack; agente MAF soma `--category ai-agents`.
|
|
101
|
+
- `arquivos:` — os paths planejados, testes incluídos, **no máximo 8**: acima disso o sub-agente bate no teto de turnos.
|
|
102
|
+
- `depende:` opcional; `cobre:` lista os Cn — todo cenário é coberto por alguma fatia. Fatias sem `depende:` comum e sem arquivo em comum rodam em paralelo; o `plan-check` imprime as ondas.
|
|
103
|
+
- Cenário que se observa por um artefato de outra fatia (rota, endpoint, componente que ela cria) faz da fatia que o cobre um `depende:` daquela — senão as duas caem na mesma onda e o teste do cenário não tem por onde provar. O `plan-check` não vê de quem é a rota: a regra é sua.
|
|
104
|
+
|
|
105
|
+
**Contrato de implementação**: o que quem implementa precisa e o código não diz.
|
|
106
|
+
- **Verificação de runtime:** o stack sobe por `morph-spec e2e up {feature}` (compose do projeto; sem compose, isso é uma fatia); os fluxos que o verificador navega, nos verbos dos cenários; base URL `process.env.PLAYWRIGHT_BASE_URL ?? \`http://localhost:${process.env.PORT ?? 3000}\``, compose com `"${PORT:-3000}:3000"` e sem `container_name` (standard `infrastructure/docker/local-compose-isolation`). App com login: `e2e.auth` em `config.json` (`mode: seed|storageState|bypass|none`, `seedCommand`, `storageStatePath`, `envFile`), credenciais num `.env.e2e` gitignored — **`mode` é obrigatório sempre que houver `seedCommand`**, sem ele o seed fica inerte. Biblioteca pura: registre a dispensa e o porquê.
|
|
107
|
+
- **Baseline é um COMANDO, nunca um número.** O plano congela e é lido por dias: um número cravado está errado na primeira fatia, e quem confia nele "conserta" o que não quebrou. Registre como medir (`npm test`, `dotnet test`); o `expectedCount` sai de `morph-spec verify {feature} --record-baseline`, nunca digitado. Sem `project.stack`/`project.tests` no `config.json`, a `morph-apply` os declara a partir destes comandos antes do primeiro verify.
|
|
108
|
+
- **Pré-requisito é um PREDICADO, nunca um SHA literal:** "`git merge-base --is-ancestor origin/main HEAD` sai 0" — o SHA muda no primeiro squash.
|
|
109
|
+
|
|
110
|
+
Plano bom cabe em duas páginas; crescendo além, corte escopo. Feche com `morph-spec plan-check {feature}` até zero erro. Ele também recusa veredito de reuso fora do enum, id `C`/`F`/`ADR` duplicado, `## Errata` fora do fim, `## Cenários` vazio e fatia sem `persona:`; avisa chave de fatia desconhecida, superfície fora da `ui-designer`, ADR sem **Alcance**, fatia sem `cobre:` e mais de 12 fatias.
|
|
111
|
+
|
|
112
|
+
## 6. Ramo de design
|
|
113
|
+
|
|
114
|
+
Critério objetivo, decidido **uma vez**, aqui: a feature cria ou altera superfície de UI (componente, página, tela, estilo, fluxo de navegação)? Sim → `morph-spec advance {feature} --design`, sempre por ele e nunca criando `1-design/` à mão: no gate auto-aprovado ele aprova `plan`; com o gate já aprovado pelo humano, só abre o ramo. Nos dois casos escreve `1-design/mockups.md` do template e, se faltar, `.morph/context/design-system.md`. Depois, `Skill(morph-uiux)`. Não → `morph-spec advance {feature}` leva a implement. Ninguém redecide adiante.
|
|
115
|
+
|
|
116
|
+
## 7. Gate do plano
|
|
117
|
+
|
|
118
|
+
```
|
|
119
|
+
morph-spec gate-check {feature} plan [--json]
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Divergência de design system ou violação de standard que o disco não vê entram por `--signals '{"designSystemDivergence":true,"standardsViolations":["<id>"]}'` (as únicas chaves aceitas). **Modo entrevista** pausa sempre, e `shouldPauseGate` não conhece isso — registre direto: `morph-spec gate-decision {feature} plan --pause true --reason "modo entrevista — entendimento compartilhado" --signals '{"discoveryMode":"interview"}'`. Outro risco que nenhuma chave representa: `gate-decision` também. Nunca edite `feature.json` à mão.
|
|
123
|
+
|
|
124
|
+
**`pause === true`**: apresente o entendimento compartilhado (problema, fora de escopo, cenários, fatias, riscos) e uma `AskUserQuestion`, header "Gate plano":
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
question: "Gate do plano — Plano de {feature} aprovado?{ reason ? ' Sinal: ' + reason : '' }"
|
|
128
|
+
options: "aprovado, prosseguir" | "preciso ajustar" | "cancelar feature"
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
A pergunta **nomeia a feature**: é por ela que o hook `state-sync` grava a aprovação; sem o nome, com mais de uma feature na árvore, ele recusa. O hook só aceita resposta que começa com "aprovado" ou contém "pode avançar", "pode implementar" ou "pode prosseguir" — "lgtm" não grava. Sem `AskUserQuestion` (headless): `morph-spec approve {feature} plan --approver <quem>`. "Preciso ajustar" → edite, `plan-check`, reapresente.
|
|
132
|
+
|
|
133
|
+
**`pause === false`**: resumo de 3 linhas (problema → solução; fatias e ondas; risco principal) e `morph-spec advance {feature}` (ou `--design`, §6).
|
|
134
|
+
|
|
135
|
+
**Congelamento:** aprovado o gate, o corpo do plan.md trava — fato errado sobre o código vai num bloco `## Errata` append-only no fim (não muda o `planHash`); `checks.json` só se regrava por `plan-check`. Mudança de escopo: `morph-spec unapprove {feature} plan`, editar, `plan-check`, reapresentar o gate.
|
|
136
|
+
|
|
137
|
+
## 8. Deltas por tipo
|
|
138
|
+
|
|
139
|
+
- **`bug` (bug-lean):** a varredura roda inteira; a árvore é de repro, diagnóstico e comportamento do sistema, não de negócio; no modo automático, no máximo 1 pergunta de repro, e só se o pedido não deixar claro. `## Problema` traz repro, diagnóstico e causa provável; os cenários são o sintoma ausente e a regressão; `### Conflitos com o acervo` continua presente.
|
|
140
|
+
- **`chore`:** nasce com o gate `plan` carimbado por política. Escreva o plan.md curto numa única escrita (o gate já aprovado congela o arquivo depois de criado): `## Problema`, um ou dois cenários, `## Decisões` só com `### Conflitos com o acervo`, uma fatia. `plan-check` e `Skill(morph-apply)`.
|
|
141
|
+
- **`hotfix`:** é da `morph-hotfix`.
|
|
142
|
+
|
|
143
|
+
## 9. Encerramento
|
|
144
|
+
|
|
145
|
+
Diga ao usuário: "Plano aprovado. Rode `/morph-apply {feature}` para implementar." Não despache a `morph-apply` — o usuário decide quando começar (exceção: `chore`).
|