@polymorphism-tech/morph-spec 9.0.0 → 9.2.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 +8 -9
- package/README.md +38 -36
- package/bin/morph-spec.js +11 -63
- package/bin/validate.js +1 -39
- package/claude-plugin.json +1 -1
- package/docs/CHEATSHEET.md +1 -1
- package/docs/QUICKSTART.md +1 -1
- package/framework/CLAUDE.md +2 -1
- package/framework/MORPH.md +3 -3
- package/framework/agents.json +19 -11
- package/framework/commands/morph-apply.md +1 -1
- package/framework/commands/morph-status.md +1 -1
- package/framework/docs/CLI.md +22 -31
- package/framework/evals/review-checklist.md +12 -2
- package/framework/hooks/README.md +8 -44
- package/framework/hooks/claude-code/core/block-destructive-worktree-removal.js +6 -49
- package/framework/hooks/claude-code/core/block-raw-worktree-add.js +2 -35
- package/framework/hooks/claude-code/core/chain.js +4 -65
- package/framework/hooks/claude-code/core/comment-guard.js +2 -16
- package/framework/hooks/claude-code/core/enforce-phase-writes.js +6 -50
- package/framework/hooks/claude-code/core/gate-guard.js +7 -67
- package/framework/hooks/claude-code/core/graph-refresh-kick.js +3 -24
- package/framework/hooks/claude-code/core/heavy-gate.js +3 -21
- package/framework/hooks/claude-code/core/heavy-release.js +2 -13
- package/framework/hooks/claude-code/core/loop-detect.js +2 -31
- package/framework/hooks/claude-code/core/pre-bash-denylist.js +0 -4
- package/framework/hooks/claude-code/core/protect-spec-files.js +7 -67
- package/framework/hooks/claude-code/core/state-sync.js +12 -68
- package/framework/hooks/claude-code/core/telemetry-log.js +12 -93
- package/framework/hooks/claude-code/core/validate-completion.js +11 -57
- package/framework/hooks/claude-code/core/warn-bash-source-write.js +1 -9
- package/framework/hooks/claude-code/core/worktree-context.js +10 -110
- package/framework/hooks/claude-code/core/worktree-create.js +6 -70
- package/framework/hooks/claude-code/core/worktree-env-inject.js +5 -56
- package/framework/hooks/claude-code/core/worktree-remove.js +5 -31
- package/framework/hooks/claude-code/statusline.sh +11 -11
- package/framework/hooks/shared/activity-logger.js +9 -89
- package/framework/hooks/shared/agent-reap.js +2 -17
- package/framework/hooks/shared/build-check.js +6 -75
- package/framework/hooks/shared/claim-registry.js +9 -119
- package/framework/hooks/shared/command-tokens.js +6 -51
- package/framework/hooks/shared/comment-rules.js +5 -20
- package/framework/hooks/shared/comment-scanner.js +6 -25
- package/framework/hooks/shared/comment-stripper.js +11 -85
- package/framework/hooks/shared/e2e-check.js +0 -0
- package/framework/hooks/shared/errata.js +2 -15
- package/framework/hooks/shared/feature-locator.js +11 -95
- package/framework/hooks/shared/frontend-locations.js +1 -3
- package/framework/hooks/shared/gate-question.js +1 -7
- package/framework/hooks/shared/git-exclude.js +3 -20
- package/framework/hooks/shared/git-paths.js +8 -104
- package/framework/hooks/shared/graph-freshness.js +22 -166
- package/framework/hooks/shared/graph-refresh.js +21 -149
- package/framework/hooks/shared/heavy-command.js +4 -12
- package/framework/hooks/shared/hook-response.js +8 -83
- package/framework/hooks/shared/morph-cli.js +8 -52
- package/framework/hooks/shared/payload-utils.js +10 -132
- package/framework/hooks/shared/phase-utils.js +1 -42
- package/framework/hooks/shared/redact-secrets.js +4 -15
- package/framework/hooks/shared/reparse-scan.js +6 -66
- package/framework/hooks/shared/slice-progress.js +4 -23
- package/framework/hooks/shared/source-files.js +4 -17
- package/framework/hooks/shared/state-reader.js +13 -183
- package/framework/hooks/shared/state-writer.js +8 -52
- package/framework/hooks/shared/stdin-reader.js +1 -11
- package/framework/hooks/shared/telemetry-logger.js +7 -67
- package/framework/hooks/shared/transcript-usage.js +7 -29
- package/framework/hooks/shared/worktree-root.js +7 -29
- package/framework/rules/csharp-standards.md +1 -1
- package/framework/rules/frontend-standards.md +1 -0
- package/framework/rules/hangfire-standards.md +1 -1
- package/framework/rules/neon-standards.md +1 -1
- package/framework/rules/nextjs-standards.md +1 -1
- package/framework/skills/core/create-umbraco-lp/SKILL.md +1 -1
- package/framework/skills/core/migrate-lp-to-umbraco/SKILL.md +1 -1
- package/framework/skills/core/morph-apply/SKILL.md +4 -4
- package/framework/skills/core/morph-hotfix/SKILL.md +3 -3
- package/framework/skills/core/morph-machine/SKILL.md +1 -1
- package/framework/skills/core/morph-media/SKILL.md +1 -1
- package/framework/skills/core/morph-plan/SKILL.md +9 -7
- package/framework/skills/core/morph-review/SKILL.md +9 -6
- package/framework/skills/core/morph-standards/SKILL.md +1 -1
- package/framework/skills/core/morph-uiux/SKILL.md +29 -12
- package/framework/standards/STANDARDS.json +36 -14
- package/framework/standards/STANDARDS.meta.json +16 -2
- package/framework/standards/ai-agents/agent-archetypes.md +2 -2
- package/framework/standards/ai-agents/agent-session.md +1 -1
- package/framework/standards/ai-agents/conversational-agent-with-phases.md +4 -4
- package/framework/standards/ai-agents/durable-workflows-hitl.md +3 -3
- package/framework/standards/ai-agents/guardrails.md +1 -1
- package/framework/standards/ai-agents/multi-agent-patterns.md +2 -2
- package/framework/standards/ai-agents/observability-patterns.md +1 -1
- package/framework/standards/ai-agents/production.md +1 -1
- package/framework/standards/ai-agents/prompt-sources.md +2 -2
- package/framework/standards/ai-agents/providers/model-registry.md +1 -1
- package/framework/standards/ai-agents/rag-custom-pgvector.md +2 -2
- package/framework/standards/ai-agents/setup.md +2 -2
- package/framework/standards/ai-agents/sweet-spot.md +2 -2
- package/framework/standards/ai-agents/tool-adapters.md +0 -2
- package/framework/standards/ai-agents/vector-data-extensions.md +4 -4
- package/framework/standards/ai-agents/workflows.md +1 -1
- package/framework/standards/architecture/code-comments.md +1 -1
- package/framework/standards/architecture/vertical-slice/vertical-slice.md +1 -1
- package/framework/standards/backend/api/validation.md +1 -1
- package/framework/standards/backend/dotnet/testing.md +10 -4
- package/framework/standards/backend/dotnet/vsa-handler-patterns.md +5 -5
- package/framework/standards/backend/integrations/hangfire/hangfire-jobs.md +1 -1
- package/framework/standards/backend/integrations/neon-auth/neon-auth.md +2 -2
- package/framework/standards/data/nosql/cache/redis.md +1 -1
- package/framework/standards/data/nosql/cosmos-db.md +3 -3
- package/framework/standards/frontend/admin-app/forms.md +1 -1
- package/framework/standards/frontend/design-system/art-direction.md +88 -0
- package/framework/standards/frontend/design-system/premium-finish.md +77 -2
- package/framework/standards/frontend/nextjs/testing.md +10 -6
- package/framework/standards/infrastructure/neon/neon-pgvector.md +5 -5
- package/framework/templates/.idea/morph-templates.xml +92 -0
- package/framework/templates/.vscode/morph-templates.code-snippets +186 -0
- package/framework/templates/CLAUDE.md.core.template +3 -3
- package/framework/templates/IDE-SNIPPETS.md +262 -262
- package/framework/templates/REGISTRY.json +9 -9
- package/framework/templates/code/dotnet/abstractions/api-endpoint.cs +7 -7
- package/framework/templates/code/dotnet/feature/request.cs.hbs +4 -4
- package/framework/templates/code/dotnet/feature/response.cs.hbs +4 -4
- package/framework/templates/code/sql/ai-agents/pgvector-embeddings-migration.sql.template +91 -91
- package/framework/templates/docs/plan.md +3 -1
- package/framework/templates/docs/ui-mockups.md +4 -0
- package/framework/templates/frontend/nextjs/client-component.tsx.hbs +26 -26
- package/framework/templates/frontend/nextjs/feature-form.tsx.hbs +56 -56
- package/framework/templates/frontend/nextjs/tsconfig.json.hbs +26 -26
- package/framework/templates/infrastructure/docker/Dockerfile.template +58 -58
- package/framework/templates/infrastructure/docker/dockerfile-api.dockerfile +38 -38
- package/framework/templates/infrastructure/docker/dockerfile-web.dockerfile +48 -48
- package/framework/templates/infrastructure/github/actions/docker-build-push/action.yml.hbs +45 -45
- package/framework/templates/infrastructure/github/actions/health-check/action.yml.hbs +27 -27
- package/framework/templates/infrastructure/github/workflows/docker-build-push.yml.hbs +59 -59
- package/framework/templates/infrastructure/github/workflows/dotnet-build.yml.hbs +39 -39
- package/framework/templates/meta-prompts/fusion/fusion-agent.md +76 -76
- package/framework/templates/meta-prompts/fusion/fusion-aggregator.md +100 -100
- package/framework/templates/state.template.json +17 -17
- package/framework/templates/ui/design-system.css +226 -226
- package/package.json +1 -1
- package/src/commands/context/context-refresh.js +0 -16
- package/src/commands/dashboard/dashboard.js +2 -8
- package/src/commands/e2e/e2e.js +17 -104
- package/src/commands/graph/affected.js +0 -14
- package/src/commands/graph/build.js +11 -50
- package/src/commands/graph/explain.js +0 -16
- package/src/commands/graph/status.js +1 -12
- package/src/commands/mcp/mcp-setup.js +4 -62
- package/src/commands/observability/cost.js +5 -57
- package/src/commands/observability/telemetry.js +1 -14
- package/src/commands/project/branch.js +4 -45
- package/src/commands/project/claim.js +4 -48
- package/src/commands/project/doctor.js +48 -302
- package/src/commands/project/env.js +1 -27
- package/src/commands/project/fleet.js +3 -32
- package/src/commands/project/init.js +4 -68
- package/src/commands/project/install-plugin-cmd.js +0 -1
- package/src/commands/project/standards.js +1 -62
- package/src/commands/project/status.js +0 -53
- package/src/commands/project/update.js +31 -239
- package/src/commands/project/worktree.js +108 -882
- package/src/commands/scaffold/scaffold.js +0 -25
- package/src/commands/state/advance.js +14 -85
- package/src/commands/state/approve.js +15 -97
- package/src/commands/state/archive.js +12 -64
- package/src/commands/state/auto-approval.js +2 -5
- package/src/commands/state/create.js +22 -109
- package/src/commands/state/delete.js +11 -63
- package/src/commands/state/finish.js +98 -475
- package/src/commands/state/gate-check.js +22 -132
- package/src/commands/state/gate-decision.js +3 -39
- package/src/commands/state/handoff.js +3 -30
- package/src/commands/state/list.js +14 -84
- package/src/commands/state/report-check.js +8 -58
- package/src/commands/state/retype.js +4 -26
- package/src/commands/validation/index.js +0 -3
- package/src/commands/validation/mutate.js +11 -11
- package/src/commands/validation/plan-check.js +4 -2
- package/src/commands/validation/tests-audit.js +7 -0
- package/src/commands/validation/validate-feature.js +10 -97
- package/src/commands/validation/verify.js +30 -113
- package/src/core/paths/output-schema.js +2 -101
- package/src/core/state/feature-identity.js +1 -25
- package/src/core/state/gate-order.js +0 -27
- package/src/core/state/lifecycle-audit.js +8 -100
- package/src/core/state/state-manager.js +22 -304
- package/src/core/templates/template-registry.js +2 -97
- package/src/core/templates/template-renderer.js +13 -93
- package/src/core/templates/template-seed.js +0 -1
- package/src/core/work-types.js +1 -36
- package/src/dashboard/app/App.jsx +1 -8
- package/src/dashboard/app/components/ActivityFeed.jsx +0 -5
- package/src/dashboard/app/components/CommandPalette.jsx +0 -7
- package/src/dashboard/app/components/DetailPanel.jsx +1 -5
- package/src/dashboard/app/components/EntityLink.jsx +0 -12
- package/src/dashboard/app/components/ErrorBoundary.jsx +1 -8
- package/src/dashboard/app/components/KnowledgeMarkdown.jsx +0 -11
- package/src/dashboard/app/components/Markdown.jsx +0 -9
- package/src/dashboard/app/components/PhaseRail.jsx +0 -11
- package/src/dashboard/app/components/SearchFilter.jsx +0 -4
- package/src/dashboard/app/components/Sidebar.jsx +0 -5
- package/src/dashboard/app/hooks/useMorphQuery.js +1 -11
- package/src/dashboard/app/hooks/usePref.js +1 -5
- package/src/dashboard/app/lib/format.js +0 -2
- package/src/dashboard/app/lib/phases.js +1 -5
- package/src/dashboard/app/lib/project.js +0 -12
- package/src/dashboard/app/main.jsx +13 -13
- package/src/dashboard/app/pages/AgentMap.jsx +1 -8
- package/src/dashboard/app/pages/FeatureDetail.jsx +1 -5
- package/src/dashboard/app/pages/Features.jsx +1 -8
- package/src/dashboard/app/pages/Guide.jsx +0 -1
- package/src/dashboard/app/pages/HookInspector.jsx +2 -23
- package/src/dashboard/app/pages/PhasePipeline.jsx +0 -3
- package/src/dashboard/app/pages/Portfolio.jsx +0 -1
- package/src/dashboard/app/pages/RulesMap.jsx +1 -16
- package/src/dashboard/app/pages/SkillsLibrary.jsx +1 -16
- package/src/dashboard/app/pages/Standards.jsx +2 -17
- package/src/dashboard/scanner/activity-scanner.js +10 -69
- package/src/dashboard/scanner/agents-scanner.js +1 -23
- package/src/dashboard/scanner/docs-scanner.js +0 -6
- package/src/dashboard/scanner/feature-status.js +2 -5
- package/src/dashboard/scanner/features-scanner.js +10 -66
- package/src/dashboard/scanner/hooks-scanner.js +5 -28
- package/src/dashboard/scanner/index.js +0 -4
- package/src/dashboard/scanner/portfolio.js +5 -29
- package/src/dashboard/scanner/project-api.js +8 -54
- package/src/dashboard/scanner/rules-scanner.js +1 -2
- package/src/dashboard/scanner/skills-scanner.js +2 -12
- package/src/dashboard/scanner/standards-scanner.js +2 -6
- package/src/dashboard/vite-plugin-morph-data.js +5 -19
- package/src/dashboard/vite.config.js +24 -24
- package/src/lib/ai/ai-checks.js +7 -52
- package/src/lib/ai/ai-project-scan.js +14 -108
- package/src/lib/ai/code-audit.js +7 -63
- package/src/lib/ai/pin-drift.js +8 -51
- package/src/lib/ai/registry-audit.js +11 -90
- package/src/lib/ci/ci-verify.js +4 -19
- package/src/lib/ci/github-ci.js +9 -37
- package/src/lib/ci/workflow-scaffold.js +14 -10
- package/src/lib/detectors/claude-config-detector.js +13 -74
- package/src/lib/detectors/index.js +4 -50
- package/src/lib/e2e/applicability.js +37 -0
- package/src/lib/e2e/compose-env.js +5 -66
- package/src/lib/e2e/stack-teardown.js +6 -40
- package/src/lib/generators/architecture-scanner.js +18 -156
- package/src/lib/generators/handoff-generator.js +9 -53
- package/src/lib/generators/scaffold-generator.js +5 -101
- package/src/lib/generators/settings-generator.js +4 -37
- package/src/lib/git/branch-classifier.js +11 -84
- package/src/lib/git/default-branch.js +14 -169
- package/src/lib/git/evidence-staleness.js +1 -0
- package/src/lib/git/gh.js +2 -17
- package/src/lib/git/pending-prs.js +6 -37
- package/src/lib/git/pr-files.js +3 -28
- package/src/lib/git/pr-index.js +3 -34
- package/src/lib/git/tree-fingerprint.js +3 -15
- package/src/lib/git/tree-state.js +6 -33
- package/src/lib/graph/god-nodes.js +2 -22
- package/src/lib/graph/graph-health.js +3 -24
- package/src/lib/graph/graph-loader.js +5 -56
- package/src/lib/graph/graphify-runtime.js +7 -37
- package/src/lib/graph/graphifyignore.js +8 -74
- package/src/lib/graph/sanitize.js +16 -136
- package/src/lib/heavy/cleanup.js +1 -1
- package/src/lib/installers/effects.js +8 -93
- package/src/lib/installers/mcp-installer.js +9 -169
- package/src/lib/installers/memory-installer.js +4 -27
- package/src/lib/installers/templates-reconcile.js +5 -60
- package/src/lib/mutation/adapters.js +6 -17
- package/src/lib/mutation/dotnet-introspection.js +20 -106
- package/src/lib/mutation/runner.js +23 -75
- package/src/lib/mutation/subset.js +1 -4
- package/src/lib/mutation/trx.js +0 -1
- package/src/lib/plan/artifact-vocabulary.js +5 -25
- package/src/lib/plan/checks.js +34 -33
- package/src/lib/plan/plan-parser.js +7 -8
- package/src/lib/projects/registry.js +7 -44
- package/src/lib/review-reports.js +11 -26
- package/src/lib/risk-detector.js +41 -173
- package/src/lib/specs/adr-index.js +6 -34
- package/src/lib/specs/frontmatter.js +2 -15
- package/src/lib/specs/gfm-table.js +1 -7
- package/src/lib/specs/revocations.js +1 -14
- package/src/lib/specs/screen-checklist.js +47 -124
- package/src/lib/stack/dotnet-build-ignores.js +2 -6
- package/src/lib/stack/stack-profile.js +1 -28
- package/src/lib/stack/stack-scan.js +1 -8
- package/src/lib/stack-filter.js +4 -27
- package/src/lib/standards/registry.js +1 -7
- package/src/lib/standards/sections.js +2 -13
- package/src/lib/standards/verified-against.js +19 -191
- package/src/lib/tasks/eval-node.js +21 -169
- package/src/lib/tasks/linux-runner.js +18 -142
- package/src/lib/tasks/test-nodes.js +43 -240
- package/src/lib/tasks/test-runner.js +43 -341
- package/src/lib/telemetry/metrics.js +7 -36
- package/src/lib/telemetry/telemetry-reader.js +13 -125
- package/src/lib/telemetry/verify-event.js +2 -30
- package/src/lib/tests-audit/audit.js +96 -0
- package/src/lib/validators/code-budget/code-budget-validator.js +4 -44
- package/src/lib/validators/code-budget/index.js +0 -7
- package/src/lib/validators/contracts/contract-compliance-validator.js +2 -24
- package/src/lib/validators/contracts/index.js +0 -6
- package/src/lib/validators/nextjs/index.js +0 -5
- package/src/lib/validators/nextjs/next-component-validator.js +4 -81
- package/src/lib/validators/packages/index.js +0 -6
- package/src/lib/validators/packages/package-validator.js +6 -56
- package/src/lib/validators/reuse/index.js +0 -8
- package/src/lib/validators/reuse/reuse-validator.js +11 -101
- package/src/lib/validators/reuse/symbol-scanner.js +6 -62
- package/src/lib/validators/traceability-check.js +5 -63
- package/src/lib/validators/validation-runner.js +21 -158
- package/src/lib/validators/verify-runner.js +85 -376
- package/src/lib/work-type-detector.js +5 -67
- package/src/lib/worktree/docker-audit.js +17 -136
- package/src/lib/worktree/env-allocator.js +10 -98
- package/src/lib/worktree/feature-truth.js +12 -115
- package/src/lib/worktree/finish-backup.js +32 -242
- package/src/lib/worktree/fleet-scanner.js +13 -95
- package/src/lib/worktree/ignored-triage.js +15 -91
- package/src/lib/worktree/vscode-settings.js +2 -3
- package/src/lib/worktree/worktree-audit.js +21 -213
- package/src/lib/worktree/worktree-include.js +3 -5
- package/src/scripts/global-install.js +3 -9
- package/src/scripts/install-plugin.js +1 -13
- package/src/scripts/setup-infra.js +17 -147
- package/src/utils/agents-installer.js +29 -276
- package/src/utils/banner.js +4 -25
- package/src/utils/claude-md-injector.js +1 -37
- package/src/utils/claude-settings-manager.js +1 -52
- package/src/utils/file-copier.js +11 -95
- package/src/utils/hooks-installer.js +21 -298
- package/src/utils/skills-installer.js +4 -101
- package/src/utils/version-checker.js +4 -83
- package/framework/commands/morph-proposal.md +0 -9
- package/framework/hooks/git/commit-msg/conventional-commits.sh +0 -33
- package/framework/hooks/git/pre-commit/agents.sh +0 -25
- package/framework/hooks/git/pre-commit/orchestrator.sh +0 -64
- package/framework/hooks/git/pre-push/run-tests.sh +0 -44
- package/src/commands/utils/index.js +0 -3
- package/src/lib/detectors/design-system-detector.js +0 -188
- package/src/lib/generators/design-system-generator.js +0 -508
- package/src/lib/specs/old-format.js +0 -68
- package/src/utils/agent-id-mapper.js +0 -11
|
@@ -1,29 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
* Padrão: `<raiz>/worktrees/<nome>` (mais o legado `.worktrees/`). Com `worktree.root` na
|
|
5
|
-
* config (ou `MORPH_WORKTREE_ROOT`), as novas nascem em `<root>/<chave-do-repo>/<nome>`, FORA da
|
|
6
|
-
* árvore aberta no editor. A chave é `basename-<hash da raiz>`: só o basename colidiria entre dois
|
|
7
|
-
* repositórios de mesmo nome que dividem o mesmo root.
|
|
8
|
-
*
|
|
9
|
-
* Um root DENTRO da raiz é recusado: toda lista que se orienta pelo nome do container
|
|
10
|
-
* (.gitignore, graphifyignore, descoberta de testes, tar do --linux, globs do editor) deixaria de
|
|
11
|
-
* enxergá-lo, em silêncio. Recusado, vale o padrão e o motivo volta em `warning`.
|
|
12
|
-
*
|
|
13
|
-
* O predicado "está no container" é a UNIÃO do layout configurado com o padrão e o legado: uma
|
|
14
|
-
* worktree que já existe continua reconhecida depois que a chave muda. Mora em `hooks/shared`
|
|
15
|
-
* porque hook não importa `src/`; o `src/` importa daqui.
|
|
16
|
-
*
|
|
17
|
-
* @module worktree-root
|
|
18
|
-
*/
|
|
1
|
+
// "Está no container" é a UNIÃO do layout configurado com o padrão e o legado:
|
|
2
|
+
// uma worktree antiga segue reconhecida. Root dentro da raiz é recusado, porque as
|
|
3
|
+
// listas orientadas pelo nome `worktrees/` deixariam de enxergá-lo.
|
|
19
4
|
|
|
20
5
|
import { createHash } from 'crypto';
|
|
21
6
|
import { readFileSync } from 'fs';
|
|
22
7
|
import { homedir } from 'os';
|
|
23
8
|
import { basename, isAbsolute, join, relative, resolve } from 'path';
|
|
24
9
|
|
|
25
|
-
// No leading dot
|
|
26
|
-
// frontend suite report 0 tests without an error. `.worktrees/` is the pre-C1 name, still read everywhere.
|
|
10
|
+
// No leading dot: Jest escapes it inside an absolute `rootDir` glob and reports 0 tests.
|
|
27
11
|
export const WORKTREES_DIR = 'worktrees';
|
|
28
12
|
export const LEGACY_WORKTREES_DIR = '.worktrees';
|
|
29
13
|
export const WORKTREE_DIR_NAMES = [WORKTREES_DIR, LEGACY_WORKTREES_DIR];
|
|
@@ -31,7 +15,7 @@ export const WORKTREE_DIR_NAMES = [WORKTREES_DIR, LEGACY_WORKTREES_DIR];
|
|
|
31
15
|
const fwd = (p) => String(p).replace(/\\/g, '/');
|
|
32
16
|
const foldCase = (p) => (process.platform === 'win32' ? p.toLowerCase() : p);
|
|
33
17
|
|
|
34
|
-
|
|
18
|
+
// Só o basename colidiria entre repositórios; o hash é estável entre `R:` e `r:`.
|
|
35
19
|
export function repoKey(primaryRoot) {
|
|
36
20
|
const root = fwd(resolve(primaryRoot));
|
|
37
21
|
const hash = createHash('sha1').update(foldCase(root)).digest('hex').slice(0, 8);
|
|
@@ -54,11 +38,7 @@ function isInside(root, path) {
|
|
|
54
38
|
return rel === '' || (!rel.startsWith('..') && !isAbsolute(rel));
|
|
55
39
|
}
|
|
56
40
|
|
|
57
|
-
/**
|
|
58
|
-
* @param {string} primaryRoot
|
|
59
|
-
* @param {{ env?: NodeJS.ProcessEnv }} [opts]
|
|
60
|
-
* @returns {{ dir: string|null, base?: string, warning?: string }} `dir` = `<root>/<repoKey>`
|
|
61
|
-
*/
|
|
41
|
+
/** @returns {{ dir: string|null, base?: string, warning?: string }} `dir` = `<root>/<repoKey>` */
|
|
62
42
|
export function externalContainer(primaryRoot, { env = process.env } = {}) {
|
|
63
43
|
const configured = configuredRoot(primaryRoot, env);
|
|
64
44
|
if (!configured) return { dir: null };
|
|
@@ -70,19 +50,17 @@ export function externalContainer(primaryRoot, { env = process.env } = {}) {
|
|
|
70
50
|
return { dir: fwd(join(base, repoKey(primaryRoot))), base: fwd(base) };
|
|
71
51
|
}
|
|
72
52
|
|
|
73
|
-
/** Where a NEW worktree lands. */
|
|
74
53
|
export function newWorktreesDir(primaryRoot, opts) {
|
|
75
54
|
return externalContainer(primaryRoot, opts).dir ?? `${fwd(resolve(primaryRoot))}/${WORKTREES_DIR}`;
|
|
76
55
|
}
|
|
77
56
|
|
|
78
|
-
/** Every directory that counts as "the container", external first. Forward slashes. */
|
|
79
57
|
export function containerDirs(primaryRoot, opts) {
|
|
80
58
|
const root = fwd(resolve(primaryRoot));
|
|
81
59
|
const external = externalContainer(primaryRoot, opts).dir;
|
|
82
60
|
return [...(external ? [external] : []), ...WORKTREE_DIR_NAMES.map((name) => `${root}/${name}`)];
|
|
83
61
|
}
|
|
84
62
|
|
|
85
|
-
|
|
63
|
+
// Ask `containerDirs` once per audit, not once per path.
|
|
86
64
|
export function isUnder(dirs, path) {
|
|
87
65
|
const target = foldCase(fwd(resolve(path)));
|
|
88
66
|
return dirs.some((dir) => target.startsWith(`${foldCase(dir)}/`));
|
|
@@ -9,7 +9,7 @@ stacks:
|
|
|
9
9
|
# C# and .NET VSA Standards
|
|
10
10
|
|
|
11
11
|
- **architecture-vertical-slice-vertical-slice** (`architecture/vertical-slice/vertical-slice.md`) — Uma slice por operação em `Features/{Entity}Feature/{Verb}{Entity}/`: Request/Response `sealed record`, Handler, Validator e Endpoint `IApiEndpoint` `internal sealed`. Decorators Scrutor: Logging → Validation → Handler. PROIBIDO: MediatR/`IRequest`, AggregateRoot, DomainEvent, CQRS formal, camada Application Service, DTO compartilhado entre features, `IRepository<T>`/`IUnitOfWork`.
|
|
12
|
-
- **backend-dotnet-vsa-handler-patterns** (`backend/dotnet/vsa-handler-patterns.md`) — Handler `sealed class` com primary constructor implementando `IHandler<TRequest, TResponse>` (não MediatR): injeta `ApplicationDbContext` direto, usa `Guid.CreateVersion7()` (nunca `Guid.NewGuid()`), passa `CancellationToken` em tudo e devolve `Result<T>`. Erros em `{Feature}Errors.cs`. SQL cru ou store dedicado só com justificativa em `
|
|
12
|
+
- **backend-dotnet-vsa-handler-patterns** (`backend/dotnet/vsa-handler-patterns.md`) — Handler `sealed class` com primary constructor implementando `IHandler<TRequest, TResponse>` (não MediatR): injeta `ApplicationDbContext` direto, usa `Guid.CreateVersion7()` (nunca `Guid.NewGuid()`), passa `CancellationToken` em tudo e devolve `Result<T>`. Erros em `{Feature}Errors.cs`. SQL cru ou store dedicado só com justificativa em `plan.md` (`## Decisões`).
|
|
13
13
|
- **backend-dotnet-result-pattern** (`backend/dotnet/result-pattern.md`) — Falha esperada é `Result`/`Result<T>`, nunca exceção. Endpoint: `result.Match(value => Results.Ok(value), error => error.ToHttpResult())`; nunca leia `.Value` fora do `Match`. Status pelo `ErrorType` (Validation 400, NotFound 404, Conflict 409, Unauthorized 401, Forbidden 403, Unexpected 500), nunca BadRequest para tudo. PROIBIDO: try/catch no handler, retornar null, erro string sem código.
|
|
14
14
|
- **backend-dotnet-fluent-validation-vsa** (`backend/dotnet/fluent-validation-vsa.md`) — Um `sealed AbstractValidator<TRequest>` (FluentValidation 12) por request, na pasta da slice; o `ValidationDecorator` roda antes do handler e devolve `Result.Failure(ValidationError)`. `AddValidatorsFromAssembly()` ANTES de `AddHandlersFromAssembly()`. Sempre `.WithMessage()`; tempo via `TimeProvider` lido DENTRO da regra. Nunca lance `ValidationException`.
|
|
15
15
|
- **backend-dotnet-scrutor** (`backend/dotnet/scrutor.md`) — `AddHandlersFromAssembly` registra cada `IHandler<,>` como Scoped (filtro `!t.ContainsGenericParameters`) e depois `Decorate` Validation e então Logging (o último registrado é o mais externo). Endpoints `IApiEndpoint` via `TryAddEnumerable` Transient + `MapApiEndpoints`. Nunca registre handler um a um.
|
|
@@ -11,5 +11,6 @@ stacks:
|
|
|
11
11
|
|
|
12
12
|
- **frontend-design-system-naming** (`frontend/design-system/naming.md`) — BEM para componente reutilizável (`.card`, `.card__header`, `.card--featured`); prefixo de página para elemento específico (`.home-hero`). Custom properties em `:root` com namespace `--app-`. Estado por sufixo fixo: `--active`, `--disabled`, `--loading`, `--error`.
|
|
13
13
|
- **frontend-design-system-animations** (`frontend/design-system/animations.md`) — Classes `.animate-*`, `.duration-fast/normal/slow`, `.stagger-1..10`. Lista escalonada exige `animation-delay` E `animation-fill-mode: backwards`. Sempre o bloco `prefers-reduced-motion: reduce`. Além do CSS: Motion (`motion/react`) para enter/exit/layout; GSAP só para ScrollTrigger, SVG morph e timelines.
|
|
14
|
+
- **frontend-design-system-art-direction** (`frontend/design-system/art-direction.md`) — Tela nova ou alterada segue a direção escrita em `1-design/direcao.md` e o protótipo de `1-design/prototipos/`: celular composto (folha inferior, alvos de 44px), movimento só em `transform`/`opacity` com versão estática em `prefers-reduced-motion`, nenhum número inventado em cena ilustrativa.
|
|
14
15
|
|
|
15
16
|
> Resumo injetado quando você lê ou edita um arquivo casado por `paths:`. Texto completo: `morph-spec standards --find "<id>"` e leia só a seção necessária de `.morph/framework/standards/<path>`.
|
|
@@ -10,6 +10,6 @@ stacks:
|
|
|
10
10
|
|
|
11
11
|
# Hangfire Background Jobs Standards
|
|
12
12
|
|
|
13
|
-
- **backend-integrations-hangfire-hangfire-jobs** (`backend/integrations/hangfire/hangfire-jobs.md`) — Hangfire 1.8.25 só com razão real em `
|
|
13
|
+
- **backend-integrations-hangfire-hangfire-jobs** (`backend/integrations/hangfire/hangfire-jobs.md`) — Hangfire 1.8.25 só com razão real em `plan.md` (`## Decisões`); o que cabe no request fica no handler. Storage `Hangfire.PostgreSql` 1.21.1 com `UseNpgsqlConnection` no endpoint DIRETO do Neon; referencie `Newtonsoft.Json` 13.0.4. Job é classe fina e idempotente que chama o handler; `[AutomaticRetry]`, sem try/catch nem retry manual. Dashboard exige Admin autenticado.
|
|
14
14
|
|
|
15
15
|
> Resumo injetado quando você lê ou edita um arquivo casado por `paths:`. Texto completo: `morph-spec standards --find "<id>"` e leia só a seção necessária de `.morph/framework/standards/<path>`.
|
|
@@ -11,7 +11,7 @@ stacks:
|
|
|
11
11
|
# Neon PostgreSQL Standards
|
|
12
12
|
|
|
13
13
|
- **infrastructure-neon-setup** (`infrastructure/neon/neon-setup.md`) — Duas connection strings: `DefaultConnection` (pooled `-pooler`) para a app e `MigrationConnection` (direta) para migrations e advisory locks; nunca commitadas (user-secrets / env do Coolify). Formato keyword (`Host=...;SSL Mode=Require`), não URI. `EnableRetryOnFailure(5, 10s)` por causa do scale-to-zero. Branch sempre com `--expires-at`.
|
|
14
|
-
- **infrastructure-neon-pgvector** (`infrastructure/neon/neon-pgvector.md`) — `Npgsql.EntityFrameworkCore.PostgreSQL` 10.0.3 + `Pgvector.EntityFrameworkCore` 0.3.0; coluna `Vector` (`vector(1536)`) e `UseVector()` no `UseNpgsql`. SEMPRE índice HNSW com operator class casando a função LINQ (senão seq scan); distância em ordem ASC. PROIBIDO: DocumentRepository, SQL cru do C# sem `
|
|
14
|
+
- **infrastructure-neon-pgvector** (`infrastructure/neon/neon-pgvector.md`) — `Npgsql.EntityFrameworkCore.PostgreSQL` 10.0.3 + `Pgvector.EntityFrameworkCore` 0.3.0; coluna `Vector` (`vector(1536)`) e `UseVector()` no `UseNpgsql`. SEMPRE índice HNSW com operator class casando a função LINQ (senão seq scan); distância em ordem ASC. PROIBIDO: DocumentRepository, SQL cru do C# sem `plan.md` (`## Decisões`), default `gen_random_uuid()`.
|
|
15
15
|
- **infrastructure-neon-pgrag** (`infrastructure/neon/neon-pgrag.md`) — A extensão `rag` é EXPERIMENTAL: protótipo e RAG só-SQL, não produção sem teste. Nunca misture modelos de embedding numa coluna (bge-small 384 × text-embedding-3-small 1536). Índice HNSW depois da carga inicial. Produção .NET com lógica própria: tool MAF tipada sobre pgvector.
|
|
16
16
|
- **backend-integrations-neon-auth-neon-auth** (`backend/integrations/neon-auth/neon-auth.md`) — SDK `@neondatabase/auth`: `createNeonAuth()` no server, `createAuthClient()` no client, `auth.middleware()` com `runtime='nodejs'`. Duas constantes de prefixo (`BACKEND_API_PREFIX`/`PROXY_API_PREFIX`), nunca uma só. O front não consulta o Neon para dado de negócio. .NET: token EdDSA/Ed25519, verificado pelo JWKS com BouncyCastle + `SignatureValidator` devolvendo `JsonWebToken`.
|
|
17
17
|
|
|
@@ -15,7 +15,7 @@ stacks:
|
|
|
15
15
|
- **frontend-nextjs-data-fetching** (`frontend/nextjs/data-fetching.md`) — Server Component com `BACKEND_API_PREFIX`; Client Component só pelo proxy same-origin com `PROXY_API_PREFIX`. TanStack Query 5 com key factory por feature e `invalidateQueries({ queryKey })`; toda resposta passa por Zod. PROIBIDO: `useEffect(() => fetch…)` e paginar/filtrar a coleção inteira no browser.
|
|
16
16
|
- **frontend-nextjs-forms** (`frontend/nextjs/forms.md`) — react-hook-form + Zod (`zodResolver`) + Field do shadcn via `Controller`; tipo por `z.infer`; nunca `useState` por campo. Submit por `useMutation`, erro em `root`. Edição reusa o schema de criação (`.partial()`). Zod 4: `z.email()`.
|
|
17
17
|
- **frontend-nextjs-state-management** (`frontend/nextjs/state-management.md`) — Estado de servidor no TanStack Query, nunca copiado para `useState`. Página, ordenação, filtros e aba ativa na URL (`searchParams`). Context só para tema, usuário ou locale. NUNCA Zustand/Redux antes de esgotar Server Components + TanStack Query.
|
|
18
|
-
- **frontend-nextjs-testing** (`frontend/nextjs/testing.md`) — Vitest + Testing Library; MSW para API; Playwright para e2e. Teste comportamento, não implementação. Orçamento: um teste por
|
|
18
|
+
- **frontend-nextjs-testing** (`frontend/nextjs/testing.md`) — Vitest + Testing Library; MSW para API; Playwright para e2e. Teste comportamento, não implementação. Orçamento por risco: um teste por cenário com `risco:` + o de regressão do bug, componente sem risco é `leitura`/`e2e`; cenários do mesmo comportamento em `it.each`; nada de teste que só confere string de copy.
|
|
19
19
|
- **frontend-nextjs-nextjs-patterns** (`frontend/nextjs/nextjs-patterns.md`) — Route Handler é BFF: `auth.getSession()` (401 sem sessão) e delega ao .NET; banco NUNCA em route handler. Zod no client e no server (`safeParse`, 400). `strict: true` + `noUncheckedIndexedAccess`; sem `any` em resposta de API. shadcn via `npx shadcn@latest add`.
|
|
20
20
|
- **frontend-nextjs-motion-patterns** (`frontend/nextjs/motion-patterns.md`) — Motion via `motion/react` (nunca `framer-motion` junto). Variants em `motion/variants.ts` com durations/easings de `@/lib/design-tokens`. `useReducedMotion()` obrigatório; o `layout.tsx` raiz segue Server Component. 3–5 momentos de motion por página; cena guiada por scroll é do GSAP, nunca no mesmo elemento.
|
|
21
21
|
- **architecture-code-comments** (`architecture/code-comments.md`) — Padrão é nenhum comentário: renomeie, extraia, tipe ou teste antes. Só o porquê que o código não mostra (invariante, ordem, quirk externo com link), até ~3 linhas. PROIBIDO: história de processo (task, UC, ADR, Gate), repetir o código, XML doc/JSDoc que repete a assinatura, banner, `#region`, código comentado, TODO solto. O hook `comment-guard` bloqueia.
|
|
@@ -4,7 +4,7 @@ description: Guia a criação de uma landing page nova ponta-a-ponta a partir do
|
|
|
4
4
|
version: core
|
|
5
5
|
when_to_use: Use quando for iniciar um novo projeto de LP com o template Umbraco genérico
|
|
6
6
|
user-invocable: true
|
|
7
|
-
cliVersion: "9.
|
|
7
|
+
cliVersion: "9.2.0"
|
|
8
8
|
stacks:
|
|
9
9
|
- umbraco
|
|
10
10
|
---
|
|
@@ -4,7 +4,7 @@ description: Migra uma landing page existente (React/Vite, Next.js estático ou
|
|
|
4
4
|
version: core
|
|
5
5
|
when_to_use: Use quando o usuário pedir "use /migrate-lp-to-umbraco {projeto}" ou descrever a necessidade de migrar uma LP para Umbraco
|
|
6
6
|
user-invocable: true
|
|
7
|
-
cliVersion: "9.
|
|
7
|
+
cliVersion: "9.2.0"
|
|
8
8
|
stacks:
|
|
9
9
|
- umbraco
|
|
10
10
|
---
|
|
@@ -4,7 +4,7 @@ description: Executa as fatias do plano de uma feature morph-spec — dispatch p
|
|
|
4
4
|
version: core
|
|
5
5
|
when_to_use: Use com o gate do plano aprovado, em "use /morph-apply {feature}" ou "implementar feature"
|
|
6
6
|
user-invocable: true
|
|
7
|
-
cliVersion: "9.
|
|
7
|
+
cliVersion: "9.2.0"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# morph-apply
|
|
@@ -64,7 +64,7 @@ O hook `validate-completion` (no Stop) e o `report-check` cobram o relatório pe
|
|
|
64
64
|
|
|
65
65
|
`**Arquivos:**` lista todo arquivo criado ou modificado; cada `C{n}` que a fatia `cobre` aparece pelo
|
|
66
66
|
id; relatório que abre com `PARCIAL` não conta como feito. Os relatórios **são** o registro da
|
|
67
|
-
implementação
|
|
67
|
+
implementação: o `verify` confere a união dos `**Arquivos:**` contra os
|
|
68
68
|
`arquivos:` das fatias (aviso, nunca reprova). `**Standards:**` nomeia os ids que o agente de fato
|
|
69
69
|
consultou (o `report-check` não o exige).
|
|
70
70
|
- Persona não registrada: `general-purpose` com o campo `persona` de `agents.json` colado, e
|
|
@@ -78,7 +78,7 @@ relatório) está no corpo da persona gerada e chega a todo dispatch sem ser col
|
|
|
78
78
|
```
|
|
79
79
|
dispatch Agent (subagent_type: "morph-{id}") with prompt:
|
|
80
80
|
Fatia F{n} — <título>
|
|
81
|
-
cobre: <cada Cn com o texto literal do cenário e
|
|
81
|
+
cobre: <cada Cn com o texto literal do cenário, a `prova:` e o `risco:`>
|
|
82
82
|
arquivos: <os `arquivos:` da fatia>
|
|
83
83
|
standards: <por id: o digest de `morph-spec standards --find` + as 3-8 regras que ESTA fatia aplica>
|
|
84
84
|
reuso: <as linhas de `## Reuso` que tocam a fatia — conceito, veredito, alvo>
|
|
@@ -128,7 +128,7 @@ config **antes** do verify: o stamp grava o HEAD, e código ou `config.json` com
|
|
|
128
128
|
|
|
129
129
|
Depois `morph-spec verify {feature} --json`, **sem filtro** — nunca recorte o
|
|
130
130
|
verify da feature. `--filter` é do loop do próprio sub-agente; o Gate 3 e o CI rodam a suíte
|
|
131
|
-
inteira. Nó de teste sem `expectedCount
|
|
131
|
+
inteira. Nó de teste sem `expectedCount`, ou fatia que apagou teste de propósito (limpeza, `morph-spec tests-audit`): acrescente `--record-baseline` a ESTA rodada — ela mede e
|
|
132
132
|
prova de uma vez; nunca um segundo verify só para gravar a baseline. Vermelho: corrija com `verify.feedback` (direto no código, ou re-despachando a fatia dona)
|
|
133
133
|
e rode de novo; **3 tentativas** sem verde → `AskUserQuestion` ("Verify de {feature} vermelho após 3
|
|
134
134
|
tentativas — aceitar com ressalva, continuar tentando, ou parar?").
|
|
@@ -4,7 +4,7 @@ description: ADW cirúrgico de hotfix — resolve uma queda/bug crítico de prod
|
|
|
4
4
|
version: core
|
|
5
5
|
when_to_use: Use quando chegar "/morph-hotfix {feature}", quando a morph-plan rotear o pedido como workType hotfix, ou quando o usuário disser "produção caiu / hotfix / urgente" a respeito de um incidente
|
|
6
6
|
user-invocable: true
|
|
7
|
-
cliVersion: "9.
|
|
7
|
+
cliVersion: "9.2.0"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# morph-hotfix
|
|
@@ -53,8 +53,8 @@ Escreva o `plan.md` mínimo (~25 linhas) numa única escrita: o hotfix nasce com
|
|
|
53
53
|
|
|
54
54
|
- `## Problema` — o sintoma em produção, o root cause que o scout localizou e o blast radius.
|
|
55
55
|
- `## Cenários` — dois, sempre:
|
|
56
|
-
- **C1** — o sintoma ausente: dado o estado que quebrava, quando a ação que falhava, então o resultado certo. `prova: teste` (ou `e2e`).
|
|
57
|
-
- **C2** —
|
|
56
|
+
- **C1** — o sintoma ausente: dado o estado que quebrava, quando a ação que falhava, então o resultado certo. `prova: teste` (ou `e2e`) e `risco: regressão` — o teste do bug real, o único que o hotfix escreve; o `plan-check` recusa o plano sem ele.
|
|
57
|
+
- **C2** — o blast radius: o que o fix poderia quebrar continua funcionando. `prova: leitura` (o caminho tocado, citado por `arquivo:linha`) ou um teste existente que já o cobre — nunca um teste novo.
|
|
58
58
|
- `## Decisões` com `### Conflitos com o acervo` (`nenhum` vale).
|
|
59
59
|
- `## Fatias` — uma, `### F1 — fix`, com `persona:`, `arquivos:` e `cobre: C1, C2`.
|
|
60
60
|
|
|
@@ -4,7 +4,7 @@ description: Cuida da RAM e da CPU da máquina enquanto o morph-spec trabalha
|
|
|
4
4
|
version: core
|
|
5
5
|
when_to_use: Use quando a máquina estiver lenta ou sem RAM, um comando pesado esperou ou foi recusado pela fila, sobrou worktree de sub-agent, ou vários sub-agents pesados vão rodar em paralelo
|
|
6
6
|
user-invocable: false
|
|
7
|
-
cliVersion: "9.
|
|
7
|
+
cliVersion: "9.2.0"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# morph-machine
|
|
@@ -4,7 +4,7 @@ description: Conduz a AUTORIA de mídia gerada por IA — escolher o modelo pelo
|
|
|
4
4
|
version: core
|
|
5
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
6
|
user-invocable: true
|
|
7
|
-
cliVersion: "9.
|
|
7
|
+
cliVersion: "9.2.0"
|
|
8
8
|
stacks:
|
|
9
9
|
- dotnet
|
|
10
10
|
- nextjs
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
name: morph-plan
|
|
3
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
|
-
when_to_use: Use quando uma feature, bug ou chore começar ("/morph-
|
|
5
|
+
when_to_use: Use quando uma feature, bug ou chore começar ("/morph-plan {feature}", "vamos planejar X"), ou ao retomar uma feature cujo gate plan ainda não foi aprovado
|
|
6
6
|
user-invocable: true
|
|
7
|
-
cliVersion: "9.
|
|
7
|
+
cliVersion: "9.2.0"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# morph-plan
|
|
@@ -66,19 +66,21 @@ Exit ≠ 0 → descarte o mapa e re-despache **uma** vez com as `failures` colad
|
|
|
66
66
|
|
|
67
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
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
|
-
- **
|
|
69
|
+
**Cenários** (`## Cenários`): `- **Cn** — Dado …, quando …, então …`, com `prova:` (`teste` | `e2e` | `eval` | `manual` | `leitura`) **na linha seguinte, sem linha em branco** — linha vazia encerra o cenário.
|
|
70
|
+
- **Teste é por risco, não por código novo.** `prova: teste` exige `risco:` (`regra` | `dinheiro` | `contrato` | `concorrência` | `dado` | `regressão`) na linha abaixo: ramo de regra de negócio, valor, contrato externo, corrida, integridade de dado ou o bug real. Sem risco (CRUD, DTO, mapping, wiring, constante, texto, layout) a prova é `leitura` — o verificador fecha citando `arquivo:linha` — ou `e2e` quando o fluxo é o que importa. O `plan-check` recusa `teste` sem `risco:`.
|
|
71
|
+
- **Observável**: que asserção (ou que linha de código) prova? Sem resposta, reescreva ou descarte.
|
|
71
72
|
- **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
73
|
- **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
74
|
- **"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
|
|
75
|
+
- **Orçamento de teste**: um teste por cenário de risco — o cenário é a unidade, nunca a pós-condição nem o componente; variantes são linhas de tabela (`[Theory]`/`it.each`); acima disso, o porquê na linha do cenário. Nenhum teste que só fixa texto, prompt ou constante, nenhum de DTO/mapping, e o mesmo comportamento numa camada só (handler **ou** endpoint). Teste além do orçamento é escopo para o revisor. O `verify` avisa quando o teste passa da produção.
|
|
75
76
|
|
|
76
77
|
```markdown
|
|
77
78
|
## Cenários
|
|
78
79
|
- **C1** — Dado um tenant com `criterion_overrides`, quando ele é publicado, então a publicação é recusada nomeando a chave.
|
|
79
80
|
prova: teste
|
|
81
|
+
risco: contrato
|
|
80
82
|
- **C2** — Nenhum arquivo em `tenants/**` contém a chave `criterion_overrides`.
|
|
81
|
-
prova:
|
|
83
|
+
prova: leitura
|
|
82
84
|
> Por que artefato: a chave saiu do contrato; nenhum leitor de runtime a consulta.
|
|
83
85
|
|
|
84
86
|
## Fatias
|
|
@@ -136,7 +138,7 @@ A pergunta **nomeia a feature**: é por ela que o hook `state-sync` grava a apro
|
|
|
136
138
|
|
|
137
139
|
## 8. Deltas por tipo
|
|
138
140
|
|
|
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;
|
|
141
|
+
- **`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; um cenário é o sintoma ausente com `prova: teste` e `risco: regressão` (o `plan-check` recusa bug sem ele) — esse é o teste que fica; `### Conflitos com o acervo` continua presente.
|
|
140
142
|
- **`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
143
|
- **`hotfix`:** é da `morph-hotfix`.
|
|
142
144
|
|
|
@@ -4,7 +4,7 @@ description: Conduz o Gate 3 — despacha verificador ∥ revisor (∥ seguranç
|
|
|
4
4
|
version: core
|
|
5
5
|
when_to_use: Use quando a fase review começar, com todas as fatias com relatório final e o verify da feature verde
|
|
6
6
|
user-invocable: true
|
|
7
|
-
cliVersion: "9.
|
|
7
|
+
cliVersion: "9.2.0"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# morph-review
|
|
@@ -32,14 +32,15 @@ Commite o trabalho da feature (`git add <paths>` + `git commit`) e rode
|
|
|
32
32
|
`morph-spec verify {feature} --ci --json` com `run_in_background`. Ele empurra a branch, espera o run
|
|
33
33
|
e grava o stamp do artefato que o run publicou; sem CI, roda local e diz por quê.
|
|
34
34
|
**Sem `--filter`, sempre**: o Gate 3 roda a suíte inteira. Esta é a única execução de testes do Gate 3 — nenhum agente
|
|
35
|
-
roda a suíte de novo. `repeatOf` no JSON = nada mudou, use aquela rodada; `reason: "stamp-reused"` =
|
|
36
|
-
|
|
35
|
+
roda a suíte de novo. `repeatOf` no JSON = nada mudou, use aquela rodada; `reason: "stamp-reused"` = nada
|
|
36
|
+
fora de `.morph/` andou desde o último verify verde (local ou CI): ele vale e o CI não roda de novo.
|
|
37
37
|
- **Quando a saída mostrar `CI rodando`, despache (passo 3) sem esperar o fim**: o push e o
|
|
38
38
|
workflow já estão commitados e a foto da árvore não os acusa. Saiu `verify local`: espere o fim
|
|
39
39
|
antes do passo 3 — suíte local e `mutate` disputam a máquina. Exit 2 = trabalho fora de commit.
|
|
40
40
|
- Nó `e2e`: `pass` local → `morph-spec e2e status {feature} --json` → `baseUrl` vai ao verificador.
|
|
41
41
|
`fail` → correção (CI: `gh run view <id> --log-failed`). `skip` → quem classifica é o `gate-check`
|
|
42
|
-
(`classifyE2eSkip`): dispensa de projeto
|
|
42
|
+
(`classifyE2eSkip`): dispensa de projeto e `not applicable` (feature sem UI/spec/container no diff e sem
|
|
43
|
+
`prova: e2e`) passam; ambiente, `--skip-e2e` ou razão desconhecida pausam.
|
|
43
44
|
- `traceability.warnings` do verify vão ao revisor como sinal.
|
|
44
45
|
|
|
45
46
|
## 3. Dispatch — verificador ∥ revisor (∥ segurança)
|
|
@@ -49,7 +50,8 @@ Anote `base` (merge-base com a default) e `sha` (`git rev-parse HEAD`). Blast ra
|
|
|
49
50
|
símbolo público do diff, `morph-spec graph affected <símbolo> --prod --json`; sem grafo
|
|
50
51
|
(`no-graph`/`not-found`/`ambiguous`), siga sem o blast radius — o revisor cai para `git grep` — e
|
|
51
52
|
registre a ausência no recado a ele. Cada agente nasce com contexto fresco e **nunca recebe relatório anterior** (ancoragem).
|
|
52
|
-
|
|
53
|
+
`chore` tem review leve: só o revisor (∥ segurança, quando exigida) — sem verificador, sem cobertura de
|
|
54
|
+
`Cn`, sem mutação. Despache todos na mesma resposta:
|
|
53
55
|
```
|
|
54
56
|
dispatch Agent (subagent_type: "morph-verifier", model: {reviewModels.verifier.model}) with prompt:
|
|
55
57
|
feature, base, sha, JSON do verify (nós, e2e, URL) se já terminou, 1-design/mockups.md e
|
|
@@ -92,7 +94,8 @@ retomar, despache um novo.
|
|
|
92
94
|
## 5. Bloqueadores
|
|
93
95
|
O avaliador também erra: **antes de editar, reverifique cada bloqueador no código** — evidência que
|
|
94
96
|
não se reproduz vira pergunta ao mesmo agente, não correção. Confirmado: corrija (loop da
|
|
95
|
-
`morph-apply`), commite, rode
|
|
97
|
+
`morph-apply`), commite, rode `verify {feature}` local (o stamp verde dele é a prova: um `--ci` depois
|
|
98
|
+
reusa, não roda de novo) e uma foto `--before-eval` nova.
|
|
96
99
|
Retome por `SendMessage` TODO agente exigido, com o `sha` novo e `tree.dirty`/`tree.commits`: quem
|
|
97
100
|
abriu bloqueadores **confirme só os bloqueadores** (retomando o MESMO agente que os abriu); os outros
|
|
98
101
|
julgam só o delta `{sha anterior}..{sha novo}` — o que a correção abriu. `reviewModels.security.required`
|
|
@@ -4,7 +4,7 @@ description: Localiza um standard específico via busca server-side (morph-spec
|
|
|
4
4
|
version: core
|
|
5
5
|
when_to_use: Use quando precisar consultar um standard específico durante a implementação
|
|
6
6
|
user-invocable: true
|
|
7
|
-
cliVersion: "9.
|
|
7
|
+
cliVersion: "9.2.0"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# morph-standards
|
|
@@ -4,7 +4,7 @@ description: Conduz a fase opcional de UI/UX de uma feature com plano aprovado
|
|
|
4
4
|
version: core
|
|
5
5
|
when_to_use: Use quando o ramo de design for tomado (morph-spec advance {feature} --design, depois do gate do plano) e antes de /morph-apply
|
|
6
6
|
user-invocable: true
|
|
7
|
-
cliVersion: "9.
|
|
7
|
+
cliVersion: "9.2.0"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# morph-uiux
|
|
@@ -22,7 +22,9 @@ Entra depois do gate do plano, quando a `morph-plan` §6 decidiu que a feature c
|
|
|
22
22
|
|
|
23
23
|
- WCAG AA e todos os estados de componente interativo (default/hover/focus/disabled/loading/error), não só o caminho feliz.
|
|
24
24
|
- Reusa token e componente existentes antes de criar; token novo precisa de justificativa. Sistemas, não telas isoladas.
|
|
25
|
-
- **Toda tela sai com o checklist de tela preenchido.** O `advance --design` já escreveu `1-design/mockups.md` a partir do template do pacote, a fonte única dos dez itens (tabela `### Checklist de tela` dentro de cada `## Tela:`). "Não se aplica" vale se escrito; `…`, vazio ou "a definir" reprovam. Design sem tela nova ou alterada (só componente ou estilo): apague o `1-design/mockups.md` semeado. É o checklist que faz a lista de 2 000 linhas paginar: o verificador do Gate 3 cobra cada item decidido em `## Checklist de tela`. Tela de dados segue os standards de `admin-app` (lista/tabela, formulário, feedback, estrutura de página)
|
|
25
|
+
- **Toda tela sai com o checklist de tela preenchido.** O `advance --design` já escreveu `1-design/mockups.md` a partir do template do pacote, a fonte única dos dez itens (tabela `### Checklist de tela` dentro de cada `## Tela:`). "Não se aplica" vale se escrito; `…`, vazio ou "a definir" reprovam. Design sem tela nova ou alterada (só componente ou estilo): apague o `1-design/mockups.md` semeado. É o checklist que faz a lista de 2 000 linhas paginar: o verificador do Gate 3 cobra cada item decidido em `## Checklist de tela`. Tela de dados segue os standards de `admin-app` (lista/tabela, formulário, feedback, estrutura de página); login, onboarding, primeira tela, estado vazio de destaque e sucesso são `brand-moment`.
|
|
26
|
+
- **Conformidade não basta: a régua estética vale junto.** Direção escrita antes de componente (`1-design/direcao.md`: conceito, metáfora, o que torna a tela memorável, o que ela não pode parecer; 2 ou 3 direções para tela nova ou momento de marca), celular desenhado e não derivado, movimento com versão estática digna. A régua é o standard `frontend-design-system-art-direction`.
|
|
27
|
+
- **Toda tela nova ou alterada tem protótipo renderizado e conferido por print.** `1-design/prototipos/{tela}.html` autossuficiente, com os tokens reais do projeto (lidos do CSS de tokens), desktop e celular lado a lado, controles animado/estático/pausar; prints `{tela}-1280.png` e `{tela}-390.png` ao lado, saídos do laço de autocrítica. A `## Tela:` aponta o protótipo na linha `**Protótipo:**`.
|
|
26
28
|
|
|
27
29
|
## 3. Dispatch
|
|
28
30
|
|
|
@@ -34,17 +36,30 @@ Plano: `2-plan/plan.md` — fatias de UI [F2 (admin-app), F3 …]. Stack: [proje
|
|
|
34
36
|
Design system: `.morph/context/design-system.md` (tokens e componentes a reusar).
|
|
35
37
|
|
|
36
38
|
Nesta ordem, só o aplicável ao escopo:
|
|
37
|
-
1. `1-design/
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
3. `
|
|
42
|
-
|
|
39
|
+
1. `1-design/direcao.md` — antes de qualquer componente: conceito em uma frase, metáfora visual,
|
|
40
|
+
o que torna a tela memorável, o que ela NÃO pode parecer. Tela nova ou momento de marca:
|
|
41
|
+
2 ou 3 direções distintas, uma recomendada com o porquê (standard `frontend-design-system-art-direction`).
|
|
42
|
+
2. `1-design/design-system.md` (obrigatório: sem ele o `advance` recusa) — tokens (cor, tipografia, espaço, motion) que a feature usa ou acrescenta, lidos do CSS de tokens real do projeto; token novo também reescreve `.morph/context/design-system.md` (§4).
|
|
43
|
+
3. `1-design/prototipos/{tela}.html` por tela nova ou alterada — autossuficiente, tokens reais,
|
|
44
|
+
desktop e celular (folha inferior, zona do polegar, 44px) lado a lado em moldura de aparelho,
|
|
45
|
+
controles animado/estático/pausar e `prefers-reduced-motion`. Laço de autocrítica: sirva a pasta
|
|
46
|
+
por HTTP local (o Playwright MCP recusa `file:`), print em 1280 e em 390 (`{tela}-1280.png`,
|
|
47
|
+
`{tela}-390.png` ao lado do HTML), avalie (hierarquia, contraste, ritmo, celular, "parece template?"),
|
|
48
|
+
corrija e repita até passar.
|
|
49
|
+
4. `mockups.md` — um `## Tela: <nome>` por tela nova ou alterada, com a fatia que a entrega, a linha
|
|
50
|
+
`**Protótipo:** 1-design/prototipos/{tela}.html` e a tabela `### Checklist de tela` que o
|
|
51
|
+
`advance --design` já escreveu em `1-design/mockups.md`, cada item decidido.
|
|
52
|
+
5. `components.md` — componentes novos e reusados, com props e estados.
|
|
53
|
+
6. `flows.md` — navegação entre as telas.
|
|
43
54
|
|
|
44
55
|
Relatório por artefato em `1-design/reports/[artefato]-report.md`: o que foi feito (2-3 frases),
|
|
45
|
-
o artefato, as decisões de design e por quê, o que ficou aberto
|
|
46
|
-
|
|
47
|
-
|
|
56
|
+
o artefato, as decisões de design e por quê, o que ficou aberto; o do protótipo lista as rodadas
|
|
57
|
+
do laço e o que cada uma corrigiu. É o retorno; a mensagem final é cortesia.
|
|
58
|
+
Bash só para consulta (`morph-spec standards --find`, `npx`, screenshot, `git log/diff`) e para o
|
|
59
|
+
servidor estático do protótipo (`npx http-server <pasta> -p <porta>` em background; ao fim, encerre
|
|
60
|
+
esse processo pelo id do background ou pelo PID dono da porta, nunca por nome de executável):
|
|
61
|
+
sem build, teste, `verify`, `approve` ou `advance`.
|
|
62
|
+
Não toque `feature.json`, `state.json`, `plan.md` nem `checks.json`.
|
|
48
63
|
```
|
|
49
64
|
|
|
50
65
|
Ao retomar, **leia primeiro** `1-design/reports/*-report.md`. `design-system.md` é o único output obrigatório: sem ele, o `advance` recusa.
|
|
@@ -69,7 +84,9 @@ Cada ocorrência **nunca fica sem destino**: a fatia do plano que já a cobre (c
|
|
|
69
84
|
morph-spec gate-check {feature} uiux [--json]
|
|
70
85
|
```
|
|
71
86
|
|
|
72
|
-
O checklist é cobrado por código: tela sem a tabela, item ausente ou não decidido, ou nenhuma `## Tela:` **pausa** o gate nomeando tela e item, e `approve`/`advance` com assinatura `auto` recusam pela mesma regra (só o mockup antigo, telas `## S001:`, é isento). Complete o mockup antes de apresentar: não peça aprovação de um design que ainda não decidiu se a lista pagina
|
|
87
|
+
O checklist é cobrado por código: tela sem a tabela, item ausente ou não decidido, ou nenhuma `## Tela:` **pausa** o gate nomeando tela e item, e `approve`/`advance` com assinatura `auto` recusam pela mesma regra (só o mockup antigo, telas `## S001:`, é isento). Com o checklist completo, cada tela ainda deve o protótipo: sem a linha `**Protótipo:**`, o HTML ou um dos prints de 1280/390, o gate **pausa** nomeando a tela e o arquivo. Complete o mockup antes de apresentar: não peça aprovação de um design que ainda não decidiu se a lista pagina, nem de um que ninguém renderizou.
|
|
88
|
+
|
|
89
|
+
**Apresente o design aberto, não descrito.** Antes da pergunta do gate, abra cada protótipo no navegador do usuário (sirva `1-design/prototipos/` por HTTP local e abra a URL: `start` no Windows, `open` no macOS, `xdg-open` no Linux) e cite a direção escolhida de `direcao.md` em uma frase. Divergência de design system vista aqui: `--signals '{"designSystemDivergence":true}'`.
|
|
73
90
|
|
|
74
91
|
**`pause === true`**: `AskUserQuestion`, header "Gate uiux":
|
|
75
92
|
|