@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
|
@@ -29,84 +29,18 @@
|
|
|
29
29
|
],
|
|
30
30
|
"templates": [
|
|
31
31
|
{
|
|
32
|
-
"id": "
|
|
32
|
+
"id": "plan",
|
|
33
33
|
"kind": "template",
|
|
34
|
-
"name": "Feature
|
|
35
|
-
"path": "docs/
|
|
36
|
-
"location": "framework",
|
|
37
|
-
"category": "documentation",
|
|
38
|
-
"phase": "proposal",
|
|
39
|
-
"required": true,
|
|
40
|
-
"description": "Feature proposal with overview, problem statement, solution approach, and cost estimates",
|
|
41
|
-
"outputName": "proposal.md",
|
|
42
|
-
"placeholders": [
|
|
43
|
-
"AUTHOR",
|
|
44
|
-
"DATE",
|
|
45
|
-
"STACK"
|
|
46
|
-
],
|
|
47
|
-
"stackSpecific": false,
|
|
48
|
-
"engine": "handlebars",
|
|
49
|
-
"deprecated": false,
|
|
50
|
-
"technology": "handlebars",
|
|
51
|
-
"validatePlaceholders": true
|
|
52
|
-
},
|
|
53
|
-
{
|
|
54
|
-
"id": "spec",
|
|
55
|
-
"kind": "template",
|
|
56
|
-
"name": "Technical Specification",
|
|
57
|
-
"path": "docs/spec.md",
|
|
58
|
-
"location": "framework",
|
|
59
|
-
"category": "documentation",
|
|
60
|
-
"phase": "plan",
|
|
61
|
-
"required": true,
|
|
62
|
-
"description": "Detailed technical spec with architecture, data model, API contracts",
|
|
63
|
-
"outputName": "spec.md",
|
|
64
|
-
"placeholders": [
|
|
65
|
-
"DATE",
|
|
66
|
-
"FEATURE_NAME",
|
|
67
|
-
"STACK"
|
|
68
|
-
],
|
|
69
|
-
"stackSpecific": false,
|
|
70
|
-
"engine": "handlebars",
|
|
71
|
-
"deprecated": false,
|
|
72
|
-
"technology": "handlebars",
|
|
73
|
-
"validatePlaceholders": true
|
|
74
|
-
},
|
|
75
|
-
{
|
|
76
|
-
"id": "decisions",
|
|
77
|
-
"kind": "template",
|
|
78
|
-
"name": "Architecture Decision Records",
|
|
79
|
-
"path": "feature/decisions.md",
|
|
34
|
+
"name": "Feature Plan",
|
|
35
|
+
"path": "docs/plan.md",
|
|
80
36
|
"location": "framework",
|
|
81
37
|
"category": "documentation",
|
|
82
38
|
"phase": "plan",
|
|
83
39
|
"required": true,
|
|
84
|
-
"description": "
|
|
85
|
-
"outputName": "
|
|
40
|
+
"description": "Single source of a feature: problem, scenarios (Cn with proof), decisions (ADRs), reuse, slices (Fn) and errata — parsed by morph-spec plan-check into checks.json",
|
|
41
|
+
"outputName": "plan.md",
|
|
86
42
|
"placeholders": [
|
|
87
|
-
"
|
|
88
|
-
],
|
|
89
|
-
"stackSpecific": false,
|
|
90
|
-
"engine": "handlebars",
|
|
91
|
-
"deprecated": false,
|
|
92
|
-
"technology": "handlebars",
|
|
93
|
-
"validatePlaceholders": true
|
|
94
|
-
},
|
|
95
|
-
{
|
|
96
|
-
"id": "recap",
|
|
97
|
-
"kind": "template",
|
|
98
|
-
"name": "Feature Recap",
|
|
99
|
-
"path": "feature/recap.md",
|
|
100
|
-
"location": "framework",
|
|
101
|
-
"category": "documentation",
|
|
102
|
-
"phase": "implement",
|
|
103
|
-
"required": true,
|
|
104
|
-
"description": "Post-implementation summary with deliverables, metrics, lessons learned",
|
|
105
|
-
"outputName": "recap.md",
|
|
106
|
-
"placeholders": [
|
|
107
|
-
"DATE",
|
|
108
|
-
"FEATURE_NAME",
|
|
109
|
-
"STACK"
|
|
43
|
+
"FEATURE_NAME"
|
|
110
44
|
],
|
|
111
45
|
"stackSpecific": false,
|
|
112
46
|
"engine": "handlebars",
|
|
@@ -132,24 +66,6 @@
|
|
|
132
66
|
"technology": "handlebars",
|
|
133
67
|
"validatePlaceholders": true
|
|
134
68
|
},
|
|
135
|
-
{
|
|
136
|
-
"id": "spec-examples",
|
|
137
|
-
"kind": "template",
|
|
138
|
-
"name": "Spec Examples",
|
|
139
|
-
"path": "examples/spec-examples.md",
|
|
140
|
-
"location": "framework",
|
|
141
|
-
"category": "examples",
|
|
142
|
-
"phase": null,
|
|
143
|
-
"required": false,
|
|
144
|
-
"description": "Example technical specs for reference",
|
|
145
|
-
"outputName": null,
|
|
146
|
-
"placeholders": [],
|
|
147
|
-
"stackSpecific": false,
|
|
148
|
-
"engine": null,
|
|
149
|
-
"deprecated": false,
|
|
150
|
-
"technology": null,
|
|
151
|
-
"validatePlaceholders": true
|
|
152
|
-
},
|
|
153
69
|
{
|
|
154
70
|
"id": "design-system-examples",
|
|
155
71
|
"kind": "template",
|
|
@@ -614,71 +530,6 @@
|
|
|
614
530
|
"technology": "handlebars",
|
|
615
531
|
"validatePlaceholders": true
|
|
616
532
|
},
|
|
617
|
-
{
|
|
618
|
-
"id": "ui-flows",
|
|
619
|
-
"kind": "template",
|
|
620
|
-
"name": "UI Flows",
|
|
621
|
-
"path": "docs/ui-flows.md",
|
|
622
|
-
"location": "framework",
|
|
623
|
-
"category": "documentation",
|
|
624
|
-
"phase": "uiux",
|
|
625
|
-
"required": false,
|
|
626
|
-
"description": "User flows and interaction patterns with state diagrams and edge cases",
|
|
627
|
-
"outputName": "flows.md",
|
|
628
|
-
"placeholders": [
|
|
629
|
-
"DATE",
|
|
630
|
-
"FEATURE_NAME"
|
|
631
|
-
],
|
|
632
|
-
"stackSpecific": false,
|
|
633
|
-
"engine": "handlebars",
|
|
634
|
-
"deprecated": false,
|
|
635
|
-
"technology": "handlebars",
|
|
636
|
-
"validatePlaceholders": true
|
|
637
|
-
},
|
|
638
|
-
{
|
|
639
|
-
"id": "ui-components",
|
|
640
|
-
"kind": "template",
|
|
641
|
-
"name": "UI Components",
|
|
642
|
-
"path": "docs/ui-components.md",
|
|
643
|
-
"location": "framework",
|
|
644
|
-
"category": "documentation",
|
|
645
|
-
"phase": "uiux",
|
|
646
|
-
"required": false,
|
|
647
|
-
"description": "Component specifications mapping UI elements to shadcn/ui components with props and events",
|
|
648
|
-
"outputName": "components.md",
|
|
649
|
-
"placeholders": [
|
|
650
|
-
"DATE",
|
|
651
|
-
"FEATURE_NAME",
|
|
652
|
-
"STACK"
|
|
653
|
-
],
|
|
654
|
-
"stackSpecific": false,
|
|
655
|
-
"engine": "handlebars",
|
|
656
|
-
"deprecated": false,
|
|
657
|
-
"technology": "handlebars",
|
|
658
|
-
"validatePlaceholders": true
|
|
659
|
-
},
|
|
660
|
-
{
|
|
661
|
-
"id": "ui-design-system",
|
|
662
|
-
"kind": "template",
|
|
663
|
-
"name": "UI Design System",
|
|
664
|
-
"path": "docs/ui-design-system.md",
|
|
665
|
-
"location": "framework",
|
|
666
|
-
"category": "documentation",
|
|
667
|
-
"phase": "uiux",
|
|
668
|
-
"required": false,
|
|
669
|
-
"description": "Design system documentation with color palette, typography, spacing, and semantic tokens",
|
|
670
|
-
"outputName": "design-system.md",
|
|
671
|
-
"placeholders": [
|
|
672
|
-
"DATE",
|
|
673
|
-
"FEATURE_NAME",
|
|
674
|
-
"PROJECT_NAME"
|
|
675
|
-
],
|
|
676
|
-
"stackSpecific": false,
|
|
677
|
-
"engine": "handlebars",
|
|
678
|
-
"deprecated": false,
|
|
679
|
-
"technology": "handlebars",
|
|
680
|
-
"validatePlaceholders": true
|
|
681
|
-
},
|
|
682
533
|
{
|
|
683
534
|
"id": "github-workflow-dotnet-build",
|
|
684
535
|
"kind": "template",
|
|
@@ -1460,21 +1311,6 @@
|
|
|
1460
1311
|
"TIMESTAMP"
|
|
1461
1312
|
],
|
|
1462
1313
|
"validatePlaceholders": true
|
|
1463
|
-
},
|
|
1464
|
-
{
|
|
1465
|
-
"id": "tasks-template",
|
|
1466
|
-
"kind": "template",
|
|
1467
|
-
"consumption": "reference",
|
|
1468
|
-
"name": "tasks.json",
|
|
1469
|
-
"path": "tasks.template.json",
|
|
1470
|
-
"category": "context",
|
|
1471
|
-
"phase": null,
|
|
1472
|
-
"outputName": null,
|
|
1473
|
-
"description": "Initial tasks.json scaffold",
|
|
1474
|
-
"engine": "handlebars",
|
|
1475
|
-
"deprecated": false,
|
|
1476
|
-
"placeholders": [],
|
|
1477
|
-
"validatePlaceholders": true
|
|
1478
1314
|
}
|
|
1479
1315
|
]
|
|
1480
1316
|
}
|
|
@@ -183,10 +183,10 @@ internal sealed class Create{{pascalCase FEATURE_NAME}}Endpoint : IApiEndpoint
|
|
|
183
183
|
var result = await handler.HandleAsync(command, cancellationToken);
|
|
184
184
|
return result.Match(
|
|
185
185
|
onSuccess: () => Results.Ok(result.Value),
|
|
186
|
-
onFailure: error =>
|
|
186
|
+
onFailure: error => error.ToHttpResult());
|
|
187
187
|
})
|
|
188
188
|
.WithTags("{{pascalCase FEATURE_NAME}}s")
|
|
189
189
|
.Produces<Create{{pascalCase FEATURE_NAME}}Response>(StatusCodes.Status200OK)
|
|
190
|
-
.
|
|
190
|
+
.ProducesProblem(StatusCodes.Status400BadRequest);
|
|
191
191
|
}
|
|
192
192
|
}
|
|
@@ -11,7 +11,7 @@ namespace {{pascalCase PROJECT_NAME}}.Extensions
|
|
|
11
11
|
|
|
12
12
|
services.AddDbContext<ApplicationDbContext>(options =>
|
|
13
13
|
{
|
|
14
|
-
options.UseNpgsql(configuration.GetConnectionString("
|
|
14
|
+
options.UseNpgsql(configuration.GetConnectionString("DefaultConnection"));
|
|
15
15
|
});
|
|
16
16
|
|
|
17
17
|
return services;
|
|
@@ -25,3 +25,30 @@ public static class ResultExtensions
|
|
|
25
25
|
: onFailure(result.Error);
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
|
+
|
|
29
|
+
public static class ErrorHttpMapping
|
|
30
|
+
{
|
|
31
|
+
public static int StatusCodeFor(ErrorType type) => type switch
|
|
32
|
+
{
|
|
33
|
+
ErrorType.Validation => StatusCodes.Status400BadRequest,
|
|
34
|
+
ErrorType.NotFound => StatusCodes.Status404NotFound,
|
|
35
|
+
ErrorType.Conflict => StatusCodes.Status409Conflict,
|
|
36
|
+
ErrorType.Unauthorized => StatusCodes.Status401Unauthorized,
|
|
37
|
+
ErrorType.Forbidden => StatusCodes.Status403Forbidden,
|
|
38
|
+
ErrorType.Unexpected => StatusCodes.Status500InternalServerError,
|
|
39
|
+
_ => StatusCodes.Status400BadRequest
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
public static IResult ToHttpResult(this Error error)
|
|
43
|
+
{
|
|
44
|
+
Dictionary<string, object?>? extensions = error is ValidationError validation
|
|
45
|
+
? new() { ["errors"] = validation.Errors.Select(e => new { e.Code, e.Description }).ToArray() }
|
|
46
|
+
: null;
|
|
47
|
+
|
|
48
|
+
return Results.Problem(
|
|
49
|
+
title: error.Code,
|
|
50
|
+
detail: error.Description,
|
|
51
|
+
statusCode: StatusCodeFor(error.Type),
|
|
52
|
+
extensions: extensions);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -12,10 +12,10 @@ internal sealed class {{pascalCase SLICE_NAME}}Endpoint : IApiEndpoint
|
|
|
12
12
|
var result = await handler.HandleAsync(command, cancellationToken);
|
|
13
13
|
return result.Match(
|
|
14
14
|
onSuccess: () => Results.Ok(result.Value),
|
|
15
|
-
onFailure: error =>
|
|
15
|
+
onFailure: error => error.ToHttpResult());
|
|
16
16
|
})
|
|
17
17
|
.WithTags(ApiTags.{{pascalCase FEATURE_NAME}}s)
|
|
18
18
|
.Produces<{{pascalCase SLICE_NAME}}Response>(StatusCodes.Status200OK)
|
|
19
|
-
.
|
|
19
|
+
.ProducesProblem(StatusCodes.Status400BadRequest);
|
|
20
20
|
}
|
|
21
21
|
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Plano — {{FEATURE_NAME}}
|
|
2
|
+
|
|
3
|
+
<!-- Fonte única da feature. `morph-spec plan-check {{FEATURE_NAME}}` lê este arquivo e grava 2-plan/checks.json.
|
|
4
|
+
Depois do gate plan, o corpo congela: fato errado sobre o código vai em ## Errata (append-only). -->
|
|
5
|
+
|
|
6
|
+
## Problema
|
|
7
|
+
|
|
8
|
+
<O que dói hoje, para quem, e como se percebe. Duas a cinco frases.>
|
|
9
|
+
|
|
10
|
+
## Fora de escopo
|
|
11
|
+
|
|
12
|
+
- <o que esta feature deliberadamente não faz>
|
|
13
|
+
|
|
14
|
+
## Suposições não confirmadas
|
|
15
|
+
|
|
16
|
+
- <o que foi assumido sem prova; "nenhuma" vale>
|
|
17
|
+
|
|
18
|
+
## Cenários
|
|
19
|
+
|
|
20
|
+
<!-- Um cenário por comportamento observável. `prova:` é teste | e2e | eval | manual.
|
|
21
|
+
Cenário que fala de arquivo, grep ou texto exige a linha "> Por que artefato:" logo abaixo. -->
|
|
22
|
+
|
|
23
|
+
- **C1** — Dado <estado>, quando <ação>, então <resultado observável>.
|
|
24
|
+
prova: teste
|
|
25
|
+
|
|
26
|
+
## Decisões
|
|
27
|
+
|
|
28
|
+
### ADR-001 — <título>
|
|
29
|
+
**Alcance:** feature
|
|
30
|
+
|
|
31
|
+
<Contexto, decisão e consequência. `projeto` quando a decisão vale além desta feature.>
|
|
32
|
+
|
|
33
|
+
### Conflitos com o acervo
|
|
34
|
+
|
|
35
|
+
<!-- ADR do índice (.morph/specs/adrs/) que este plano contradiz: "nenhum", ou a tabela abaixo fora do bloco.
|
|
36
|
+
O finish aplica cada linha: total retira o ADR do índice; parcial o mantém com o escopo onde ainda vale.
|
|
37
|
+
```
|
|
38
|
+
| ADR | Mudança | Escopo em que o antigo ainda vale |
|
|
39
|
+
|---|---|---|
|
|
40
|
+
| {feature}/ADR-{nnn} | parcial | <onde o antigo ainda vale> |
|
|
41
|
+
| {feature}/ADR-{nnn} | total | — |
|
|
42
|
+
```
|
|
43
|
+
-->
|
|
44
|
+
|
|
45
|
+
nenhum
|
|
46
|
+
|
|
47
|
+
## Arquitetura
|
|
48
|
+
|
|
49
|
+
<Onde o código entra, o que conversa com o quê. Diagrama só se ajudar.>
|
|
50
|
+
|
|
51
|
+
## Reuso
|
|
52
|
+
|
|
53
|
+
| conceito | veredito | alvo | why |
|
|
54
|
+
|---|---|---|---|
|
|
55
|
+
| <conceito> | REUSAR | <arquivo ou símbolo existente> | |
|
|
56
|
+
|
|
57
|
+
## Fatias
|
|
58
|
+
|
|
59
|
+
<!-- Uma fatia = uma unidade de entrega (com ou sem dispatch), relatório em 3-implement/reports/Fn.md.
|
|
60
|
+
arquivos ≤ 8; superfície e depende são opcionais; toda Cn é coberta por alguma fatia. -->
|
|
61
|
+
|
|
62
|
+
### F1 — <título>
|
|
63
|
+
- persona: dotnet-senior
|
|
64
|
+
- standards: <id>
|
|
65
|
+
- arquivos: <caminho/a.cs>, <caminho/b.cs>
|
|
66
|
+
- cobre: C1
|
|
67
|
+
|
|
68
|
+
## Contrato de implementação
|
|
69
|
+
|
|
70
|
+
<Assinaturas, records, enums e rotas que as fatias precisam honrar.>
|
|
71
|
+
|
|
72
|
+
## Errata
|
|
@@ -58,15 +58,7 @@ dotnet test --solution Morph.AiKit.sln -c Release --no-build
|
|
|
58
58
|
> do `morph-spec verify`); por isso nenhum chamador repassa a flag. Ao adicionar
|
|
59
59
|
> testes, suba o piso — `test/framework/ai-kit-ci-packaging.test.js` reprova um
|
|
60
60
|
> piso que ficou para trás da contagem de `[Fact]`/`[Theory]`.
|
|
61
|
-
|
|
62
|
-
> linha de comando não sobrescreve o valor do projeto (medido: o recorte verde
|
|
63
|
-
> sai 9 do mesmo jeito), mas a propriedade global do MSBuild sim. Por isso
|
|
64
|
-
> `morph-spec verify {f} {task}` estreita este projeto repassando
|
|
65
|
-
> `"-p:TestingPlatformCommandLineArguments=…"` com o valor do `.csproj` e o piso
|
|
66
|
-
> em 1 — verde sai 0, zero testes segue saindo 8, nada recompila (issue #114).
|
|
67
|
-
> Mantenha o piso **nesse** elemento, literal (sem `Condition`, sem `$(…)`, sem
|
|
68
|
-
> outra declaração da propriedade em `Directory.Build.*`): em qualquer outra
|
|
69
|
-
> forma o recorte volta a rodar o nó inteiro.
|
|
61
|
+
|
|
70
62
|
|
|
71
63
|
> **`dotnet test` precisa rodar COM O CWD DENTRO deste diretório.** O opt-in do
|
|
72
64
|
> Microsoft.Testing.Platform (que `xunit.v3` 4.x usa) vive em `global.json`, e o
|
|
@@ -49,7 +49,7 @@ public sealed class MediaDisclosureTests
|
|
|
49
49
|
Assert.False(
|
|
50
50
|
result.IsSuccess,
|
|
51
51
|
"publicar sem marcacao e o caminho que a obrigacao legal existe para fechar; " +
|
|
52
|
-
"se ele existe, a
|
|
52
|
+
"se ele existe, a prova de midia do Gate 3 esta presa so por prosa");
|
|
53
53
|
Assert.Equal(MediaErrorCode.InvalidTransition, result.Error!.Code);
|
|
54
54
|
Assert.Contains("marcacao", result.Error.Message, StringComparison.OrdinalIgnoreCase);
|
|
55
55
|
}
|
|
@@ -30,16 +30,6 @@
|
|
|
30
30
|
de workflow. Uma unica verdade: nenhum chamador repassa a flag na linha de
|
|
31
31
|
comando, porque repassa-la duplicaria a opcao.
|
|
32
32
|
|
|
33
|
-
Consequencia para o recorte por task (`morph-spec verify {f} {task}`): a
|
|
34
|
-
mesma opcao com valor 1 na linha de comando NAO sobrescreve o valor do
|
|
35
|
-
projeto (medido: o recorte verde sai 9 do mesmo jeito), mas a propriedade
|
|
36
|
-
global do MSBuild sim. O recorte estreita este projeto repassando
|
|
37
|
-
"-p:TestingPlatformCommandLineArguments=" com ESTE valor e o piso em 1
|
|
38
|
-
(issue #114: verde sai 0, zero testes segue saindo 8, nada recompila). Por
|
|
39
|
-
isso o piso fica NESTE elemento, literal: sem Condition, sem $(...), sem
|
|
40
|
-
outra declaracao da propriedade em Directory.Build.* — em qualquer outra
|
|
41
|
-
forma o recorte volta a rodar o no inteiro.
|
|
42
|
-
|
|
43
33
|
O numero e o total de CASOS EXECUTADOS (275), nao de atributos nem de casos
|
|
44
34
|
DESCOBERTOS (276): os [Theory] expandem, e um caso IGNORADO nao conta para o piso — a
|
|
45
35
|
suite descobre 276 e executa 275, porque o semeador da cache exemplar de eval
|
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
"provider": "coolify",
|
|
4
4
|
"access": {
|
|
5
5
|
"method": "ssh",
|
|
6
|
-
"note": "
|
|
6
|
+
"note": "We use no Coolify MCP/CLI — replace sshHost with the real SSH alias for the target VPS and tokenPath with the chmod-600 token file in that user's home. The API is reached only from inside the VPS, at apiBaseUrl; the deploy trigger is POST /deploy?uuid= (GET is refused by Coolify 4.3.23).",
|
|
7
7
|
"sshHost": "REPLACE_WITH_VPS_SSH_ALIAS",
|
|
8
8
|
"apiBaseUrl": "http://localhost:8000/api/v1",
|
|
9
|
-
"tokenPath": "
|
|
9
|
+
"tokenPath": "~/REPLACE_WITH_TOKEN_FILE"
|
|
10
10
|
},
|
|
11
11
|
"application": {
|
|
12
12
|
"uuid": "REPLACE_WITH_COOLIFY_APPLICATION_UUID",
|
|
@@ -45,5 +45,5 @@
|
|
|
45
45
|
"https": true
|
|
46
46
|
}
|
|
47
47
|
],
|
|
48
|
-
"deployCommand": "ssh REPLACE_WITH_VPS_SSH_ALIAS 'T=$(cat
|
|
48
|
+
"deployCommand": "ssh REPLACE_WITH_VPS_SSH_ALIAS 'T=$(cat ~/REPLACE_WITH_TOKEN_FILE); curl -s -X POST -H \"Authorization: Bearer $T\" \"http://localhost:8000/api/v1/deploy?uuid=REPLACE_WITH_COOLIFY_APPLICATION_UUID\"'"
|
|
49
49
|
}
|
|
@@ -39,7 +39,8 @@ infrastructure/github/
|
|
|
39
39
|
- Push to container registry (GHCR or Docker Hub)
|
|
40
40
|
|
|
41
41
|
### Deploy Coolify (`deploy-coolify.yml.hbs`)
|
|
42
|
-
- SSHes into the VPS and calls the local Coolify API (`localhost:8000/api/v1/deploy?uuid=...`) after Docker push
|
|
42
|
+
- SSHes into the VPS and calls the local Coolify API (`POST localhost:8000/api/v1/deploy?uuid=...`) after Docker push; the step fails unless the response carries a `deployment_uuid`
|
|
43
|
+
- The token is read on the VPS from `~/<token-file>` (secret `COOLIFY_TOKEN_FILE` holds the file name) and never leaves the SSH session
|
|
43
44
|
- Runs health check after deployment
|
|
44
45
|
- Supports staging + production environments
|
|
45
46
|
|
|
@@ -25,7 +25,8 @@ jobs:
|
|
|
25
25
|
- name: Trigger Coolify Deploy (via SSH — the Coolify API is not publicly exposed)
|
|
26
26
|
run: |
|
|
27
27
|
ssh -i ~/.ssh/id_ed25519 ${{{{ secrets.COOLIFY_SSH_USER }}}}@${{{{ secrets.COOLIFY_SSH_HOST }}}} \
|
|
28
|
-
'T=$(cat
|
|
28
|
+
'T=$(cat ~/${{{{ secrets.COOLIFY_TOKEN_FILE }}}}); curl -s --fail-with-body -X POST -H "Authorization: Bearer $T" "http://localhost:8000/api/v1/deploy?uuid=${{{{ secrets.COOLIFY_APPLICATION_UUID }}}}"' \
|
|
29
|
+
| grep -q deployment_uuid
|
|
29
30
|
|
|
30
31
|
- name: Health Check
|
|
31
32
|
run: |
|
|
@@ -78,7 +78,7 @@ Backend deliverables typically include:
|
|
|
78
78
|
2. Create migrations before writing service logic
|
|
79
79
|
3. Implement services with proper unit-testable interfaces
|
|
80
80
|
4. Wire up API endpoints last (depends on services)
|
|
81
|
-
5. After every 3
|
|
81
|
+
5. After every 3 slices, write each finished slice's report (`3-implement/reports/F{n}.md`) and run the checkpoint
|
|
82
82
|
6. If blocked (compilation error, migration conflict), document and continue with next unblocked task
|
|
83
83
|
|
|
84
84
|
## Report Back When Done
|
|
@@ -72,7 +72,7 @@ Frontend deliverables typically include:
|
|
|
72
72
|
2. Build reusable sub-components before composing pages
|
|
73
73
|
3. Wire up API calls/services last (after UI is structured)
|
|
74
74
|
4. Test each component with loading + error + empty states
|
|
75
|
-
5. After every 3
|
|
75
|
+
5. After every 3 slices, write each finished slice's report (`3-implement/reports/F{n}.md`) and run the checkpoint
|
|
76
76
|
|
|
77
77
|
## Report Back When Done
|
|
78
78
|
Provide a summary of:
|
|
@@ -32,7 +32,7 @@ You are a **Squad Leader** in the MORPH-SPEC agent hierarchy.
|
|
|
32
32
|
## How to Work
|
|
33
33
|
1. Read your standards carefully before starting
|
|
34
34
|
2. Implement each task in order (respecting dependencies)
|
|
35
|
-
3. After every 3
|
|
35
|
+
3. After every 3 slices, write each finished slice's report (`3-implement/reports/F{n}.md`) and run the checkpoint
|
|
36
36
|
4. If blocked, document the blocker and continue with the next unblocked task
|
|
37
37
|
5. Report completion with: files created, any blockers, checkpoint results
|
|
38
38
|
|
|
@@ -46,11 +46,10 @@ If `.morph/framework/agents.json` is in staged files:
|
|
|
46
46
|
- No duplicate agentIds
|
|
47
47
|
- Valid tier values (1-4)
|
|
48
48
|
|
|
49
|
-
### 4.
|
|
50
|
-
If any
|
|
51
|
-
-
|
|
49
|
+
### 4. Plan Format Validation (if plan.md staged)
|
|
50
|
+
If any `.morph/features/*/2-plan/plan.md` is staged:
|
|
51
|
+
- `morph-spec plan-check <feature>` exits 0 (sections, scenarios with `prova:`, slices that cover them)
|
|
52
52
|
- No placeholder text (`{{TODO}}`, `TBD`, `[PLACEHOLDER]`)
|
|
53
|
-
- Word count > 200 (meaningful spec)
|
|
54
53
|
|
|
55
54
|
### 5. Stack-Specific Validation
|
|
56
55
|
{{#if IS_CSHARP}}
|
package/package.json
CHANGED
package/src/commands/e2e/e2e.js
CHANGED
|
@@ -232,7 +232,7 @@ export async function e2eUpCommand(featureName, options = {}) {
|
|
|
232
232
|
/**
|
|
233
233
|
* Where the app actually landed.
|
|
234
234
|
*
|
|
235
|
-
* The
|
|
235
|
+
* The orchestrator hands this to the verifier instead of letting it guess
|
|
236
236
|
* `localhost:3000` — each feature owns a port block, so the default port is the
|
|
237
237
|
* one address most likely to be wrong. Mirrors what `playwright.config.ts` is
|
|
238
238
|
* asked to do, deliberately: one rule, two readers.
|
|
@@ -331,7 +331,7 @@ export async function e2eDownCommand(featureName, options = {}) {
|
|
|
331
331
|
volumes: Boolean(options.volumes),
|
|
332
332
|
});
|
|
333
333
|
const stampDeleted = deleteStamp(ctx.gitCommonDir, ctx.projectName);
|
|
334
|
-
const cleanup = afterHeavyRun({ projectPath: ctx.cwd, config: readHeavyConfig(ctx.cwd)
|
|
334
|
+
const cleanup = afterHeavyRun({ projectPath: ctx.cwd, config: readHeavyConfig(ctx.cwd) });
|
|
335
335
|
|
|
336
336
|
if (options.json) {
|
|
337
337
|
console.log(JSON.stringify(
|