@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
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* tasks-validator.js — minimal hook-side schema validation for tasks.json.
|
|
3
|
-
*
|
|
4
|
-
* Mirrors VALID_STATUS / VALID_EFFORT from src/lib/tasks/tasks-json-parser.js.
|
|
5
|
-
* Hooks are installed standalone into target projects (.morph/framework/hooks/),
|
|
6
|
-
* so they cannot import from src/ — the enum lives here, duplicated on purpose
|
|
7
|
-
* and covered by tests on both sides.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
export const VALID_TASK_STATUS = ['pending', 'in_progress', 'done', 'skipped', 'blocked'];
|
|
11
|
-
export const VALID_TASK_EFFORT = ['S', 'M', 'L', 'XL'];
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Validate the parts of a tasks.json document that hooks care about:
|
|
15
|
-
* a tasks[] array whose entries carry a valid status (and effort, when set).
|
|
16
|
-
* The production failure this guards: a leaf agent writing status "completed"
|
|
17
|
-
* (not in the enum) without any validation.
|
|
18
|
-
*
|
|
19
|
-
* @param {object} doc - parsed tasks.json
|
|
20
|
-
* @returns {{ valid: boolean, errors: string[] }}
|
|
21
|
-
*/
|
|
22
|
-
/** Human-readable type name for error messages ('array', not 'object'). */
|
|
23
|
-
function typeName(value) {
|
|
24
|
-
return Array.isArray(value) ? 'array' : typeof value;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export function validateTasksDoc(doc) {
|
|
28
|
-
if (!doc || typeof doc !== 'object' || !Array.isArray(doc.tasks)) {
|
|
29
|
-
return { valid: false, errors: ['tasks.json must be an object with a tasks[] array'] };
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const errors = [];
|
|
33
|
-
for (const task of doc.tasks) {
|
|
34
|
-
const id = task?.id ?? '?';
|
|
35
|
-
if (!VALID_TASK_STATUS.includes(task?.status)) {
|
|
36
|
-
errors.push(`task '${id}': invalid status '${task?.status}' (valid: ${VALID_TASK_STATUS.join(', ')})`);
|
|
37
|
-
}
|
|
38
|
-
if (task?.effort !== undefined && !VALID_TASK_EFFORT.includes(task.effort)) {
|
|
39
|
-
errors.push(`task '${id}': invalid effort '${task.effort}' (valid: ${VALID_TASK_EFFORT.join(', ')})`);
|
|
40
|
-
}
|
|
41
|
-
// Mutable-field type checks with the exact field/value in the message —
|
|
42
|
-
// a malformed notes/outputs used to surface as the misleading generic
|
|
43
|
-
// "notes is empty" downstream (MORPH_GHLBrain 2026-07-11).
|
|
44
|
-
if (task?.notes !== undefined && typeof task.notes !== 'string') {
|
|
45
|
-
errors.push(`task '${id}': 'notes' must be a string (got ${typeName(task.notes)})`);
|
|
46
|
-
}
|
|
47
|
-
if (task?.outputs !== undefined) {
|
|
48
|
-
if (!Array.isArray(task.outputs)) {
|
|
49
|
-
errors.push(`task '${id}': 'outputs' must be an array of path strings (got ${typeName(task.outputs)})`);
|
|
50
|
-
} else {
|
|
51
|
-
task.outputs.forEach((entry, i) => {
|
|
52
|
-
if (typeof entry !== 'string') {
|
|
53
|
-
errors.push(`task '${id}': outputs[${i}] must be a string path (got ${typeName(entry)})`);
|
|
54
|
-
}
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
return { valid: errors.length === 0, errors };
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Planned-vs-real outputs divergence: tasks whose `outputs` changed relative
|
|
64
|
-
* to the previous document but whose `notes` is still empty. The divergence
|
|
65
|
-
* itself is legitimate (outputs is a mutable progress field) — shipping it
|
|
66
|
-
* without an explanatory note is what gets flagged.
|
|
67
|
-
*
|
|
68
|
-
* @param {object} oldDoc - parsed previous tasks.json
|
|
69
|
-
* @param {object} newDoc - parsed proposed tasks.json
|
|
70
|
-
* @returns {string[]} human-readable violation messages (empty = OK)
|
|
71
|
-
*/
|
|
72
|
-
/** Compact outputs rendering for messages, capped so huge arrays stay readable. */
|
|
73
|
-
function fmtOutputs(outputs) {
|
|
74
|
-
const s = JSON.stringify(outputs ?? []);
|
|
75
|
-
return s.length > 120 ? s.slice(0, 117) + '...' : s;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
export function outputsDivergenceViolations(oldDoc, newDoc) {
|
|
79
|
-
const violations = [];
|
|
80
|
-
const oldById = new Map((oldDoc?.tasks ?? []).map(t => [t.id, t]));
|
|
81
|
-
|
|
82
|
-
for (const task of newDoc?.tasks ?? []) {
|
|
83
|
-
const old = oldById.get(task.id);
|
|
84
|
-
if (!old) continue;
|
|
85
|
-
const outputsChanged =
|
|
86
|
-
JSON.stringify(old.outputs ?? []) !== JSON.stringify(task.outputs ?? []);
|
|
87
|
-
if (!outputsChanged) continue;
|
|
88
|
-
|
|
89
|
-
// A filled string note explains the divergence — done.
|
|
90
|
-
if (typeof task.notes === 'string' && task.notes.trim().length > 0) continue;
|
|
91
|
-
|
|
92
|
-
// Root-cause specific messages: a malformed notes value is a DIFFERENT
|
|
93
|
-
// failure than a missing one — claiming "notes is empty" when the agent
|
|
94
|
-
// just wrote an array reads as a false positive and burns a retry cycle.
|
|
95
|
-
if (task.notes !== undefined && typeof task.notes !== 'string') {
|
|
96
|
-
violations.push(
|
|
97
|
-
`task '${task.id}': outputs diverged from the plan and 'notes' is not a string ` +
|
|
98
|
-
`(got ${typeName(task.notes)}) — write the explanation as a single string in 'notes'`
|
|
99
|
-
);
|
|
100
|
-
continue;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
violations.push(
|
|
104
|
-
`task '${task.id}': outputs diverged from the plan ` +
|
|
105
|
-
`(${fmtOutputs(old.outputs)} → ${fmtOutputs(task.outputs)}) but 'notes' is empty — ` +
|
|
106
|
-
`record why in 'notes' in the same edit. ` +
|
|
107
|
-
`Deletions and annotations belong in 'notes', not in 'outputs' (outputs = produced paths only).`
|
|
108
|
-
);
|
|
109
|
-
}
|
|
110
|
-
return violations;
|
|
111
|
-
}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"id": "backend",
|
|
3
|
-
"version": "1.1.0",
|
|
4
|
-
"description": "Backend-focused rubric. Higher weight on architecture, security, and package health. Deterministic-validator weights for the verify validators node; the score is informational — the node fails on validator errors.",
|
|
5
|
-
"categories": {
|
|
6
|
-
"functionality": {
|
|
7
|
-
"weight": 0.25,
|
|
8
|
-
"validators": ["contract-compliance"],
|
|
9
|
-
"description": "Core feature correctness and contract compliance"
|
|
10
|
-
},
|
|
11
|
-
"code_quality": {
|
|
12
|
-
"weight": 0.25,
|
|
13
|
-
"validators": ["architecture", "reuse", "code-budget"],
|
|
14
|
-
"description": "Architecture patterns, dependency direction, code structure, reuse of what the codebase already has, and comment and test budget"
|
|
15
|
-
},
|
|
16
|
-
"design_ui": {
|
|
17
|
-
"weight": 0.05,
|
|
18
|
-
"validators": ["design-system", "css", "contrast", "nextjs-component"],
|
|
19
|
-
"description": "Design system compliance (minimal weight for backend projects)"
|
|
20
|
-
},
|
|
21
|
-
"security": {
|
|
22
|
-
"weight": 0.15,
|
|
23
|
-
"validators": [],
|
|
24
|
-
"description": "Security posture (agent-evaluated, no automated validator)"
|
|
25
|
-
},
|
|
26
|
-
"packages": {
|
|
27
|
-
"weight": 0.20,
|
|
28
|
-
"validators": ["packages"],
|
|
29
|
-
"description": "Dependency health, version compatibility, and deprecated packages"
|
|
30
|
-
},
|
|
31
|
-
"maf_compliance": {
|
|
32
|
-
"weight": 0.10,
|
|
33
|
-
"validators": [],
|
|
34
|
-
"description": "MAF agent compliance (agent-evaluated, applies only when the feature touches AI agents): Microsoft.Agents.AI GA packages used; Model Registry alias referenced not hardcoded models; structured output for pipelined agents; prompts from DB not hardcoded; no Semantic Kernel; no hosted agent services."
|
|
35
|
-
}
|
|
36
|
-
},
|
|
37
|
-
"thresholds": {
|
|
38
|
-
"approve": 9.0,
|
|
39
|
-
"retry": 6.0
|
|
40
|
-
}
|
|
41
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"id": "default",
|
|
3
|
-
"version": "1.1.0",
|
|
4
|
-
"description": "Default rubric for general-purpose projects. Balanced weights across all categories. Deterministic-validator weights for the verify validators node; the score is informational — the node fails on validator errors.",
|
|
5
|
-
"categories": {
|
|
6
|
-
"functionality": {
|
|
7
|
-
"weight": 0.30,
|
|
8
|
-
"validators": ["contract-compliance"],
|
|
9
|
-
"description": "Core feature correctness and contract compliance"
|
|
10
|
-
},
|
|
11
|
-
"code_quality": {
|
|
12
|
-
"weight": 0.25,
|
|
13
|
-
"validators": ["architecture", "reuse", "code-budget"],
|
|
14
|
-
"description": "Architecture patterns, code structure, reuse of what the codebase already has, and comment and test budget"
|
|
15
|
-
},
|
|
16
|
-
"design_ui": {
|
|
17
|
-
"weight": 0.15,
|
|
18
|
-
"validators": ["design-system", "css", "contrast", "nextjs-component"],
|
|
19
|
-
"description": "Design system compliance, CSS quality, and UI correctness"
|
|
20
|
-
},
|
|
21
|
-
"security": {
|
|
22
|
-
"weight": 0.15,
|
|
23
|
-
"validators": [],
|
|
24
|
-
"description": "Security posture (agent-evaluated, no automated validator)"
|
|
25
|
-
},
|
|
26
|
-
"packages": {
|
|
27
|
-
"weight": 0.15,
|
|
28
|
-
"validators": ["packages"],
|
|
29
|
-
"description": "Dependency health and compatibility"
|
|
30
|
-
}
|
|
31
|
-
},
|
|
32
|
-
"thresholds": {
|
|
33
|
-
"approve": 9.0,
|
|
34
|
-
"retry": 6.0
|
|
35
|
-
}
|
|
36
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"id": "frontend",
|
|
3
|
-
"version": "1.1.0",
|
|
4
|
-
"description": "Frontend-focused rubric. Higher weight on design system compliance and UI quality. Deterministic-validator weights for the verify validators node; the score is informational — the node fails on validator errors.",
|
|
5
|
-
"categories": {
|
|
6
|
-
"functionality": {
|
|
7
|
-
"weight": 0.25,
|
|
8
|
-
"validators": ["contract-compliance"],
|
|
9
|
-
"description": "Core feature correctness and contract compliance"
|
|
10
|
-
},
|
|
11
|
-
"code_quality": {
|
|
12
|
-
"weight": 0.15,
|
|
13
|
-
"validators": ["architecture", "reuse", "code-budget"],
|
|
14
|
-
"description": "Architecture patterns, code structure, reuse of what the codebase already has, and comment and test budget"
|
|
15
|
-
},
|
|
16
|
-
"design_ui": {
|
|
17
|
-
"weight": 0.35,
|
|
18
|
-
"validators": ["design-system", "css", "contrast", "nextjs-component"],
|
|
19
|
-
"description": "Design system compliance, CSS quality, contrast ratios, and component correctness"
|
|
20
|
-
},
|
|
21
|
-
"security": {
|
|
22
|
-
"weight": 0.10,
|
|
23
|
-
"validators": [],
|
|
24
|
-
"description": "Security posture (agent-evaluated, no automated validator)"
|
|
25
|
-
},
|
|
26
|
-
"packages": {
|
|
27
|
-
"weight": 0.15,
|
|
28
|
-
"validators": ["packages"],
|
|
29
|
-
"description": "Dependency health and compatibility"
|
|
30
|
-
}
|
|
31
|
-
},
|
|
32
|
-
"thresholds": {
|
|
33
|
-
"approve": 9.0,
|
|
34
|
-
"retry": 6.0
|
|
35
|
-
}
|
|
36
|
-
}
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
stacks:
|
|
3
|
-
- "*"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# MORPH-SPEC Task Tracking
|
|
7
|
-
|
|
8
|
-
> Progress lives in `tasks.json` — nowhere else. There is no CLI command to mark a task done and
|
|
9
|
-
> no session-level checklist to keep in sync: this file IS the record of what happened.
|
|
10
|
-
|
|
11
|
-
## Persisting Progress to `tasks.json`
|
|
12
|
-
|
|
13
|
-
To record task progress for the feature, write `.morph/features/{feature}/2-plan/tasks.json`,
|
|
14
|
-
touching ONLY the mutable fields:
|
|
15
|
-
|
|
16
|
-
- `status` — `pending` → `in_progress` → `done` (também: `skipped`, `blocked`)
|
|
17
|
-
- `outputs` — the files the task produced
|
|
18
|
-
- `notes` — free-text record (deviations, context, resolved blockers)
|
|
19
|
-
|
|
20
|
-
> **O status terminal é `done`.** `completed` **não existe** no enum de
|
|
21
|
-
> `.morph/framework/schemas/tasks.schema.json` — é vocabulário de outro sistema, e o hook
|
|
22
|
-
> `protect-spec-files` rejeita a gravação.
|
|
23
|
-
|
|
24
|
-
The plan contract — `title`, `description`, `dependencies`, `effort`, `doneCriteria`,
|
|
25
|
-
`group`, `agent`, `standards` — is frozen after Gate 2. Any attempt to change it is
|
|
26
|
-
blocked by the `protect-spec-files` hook. `agent` (persona id, no `morph-` prefix)
|
|
27
|
-
and `standards` (paths pinned by morph-plan) are optional — legacy plans without
|
|
28
|
-
them remain valid.
|
|
29
|
-
|
|
30
|
-
Use the `Write` tool (whole-file rewrite) OR the `Edit` tool — `Edit` is allowed
|
|
31
|
-
as long as it touches only `status`, `outputs`, and `notes`. State is then synced
|
|
32
|
-
automatically by the `state-sync` PostToolUse hook; you do not call a CLI to mark
|
|
33
|
-
output.
|
|
34
|
-
|
|
35
|
-
Update each task as you go — `in_progress` when you pick it up, `done` when it is finished —
|
|
36
|
-
rather than batching every write to the end of the phase. `morph-spec status`, `dag`, `verify`
|
|
37
|
-
and the dashboard all read this file, so a stale `tasks.json` is a blind orchestrator.
|
|
38
|
-
|
|
39
|
-
## Deviation Tracking
|
|
40
|
-
|
|
41
|
-
When completing a task differently than originally planned, record the reason in the
|
|
42
|
-
task's `notes` field. `notes` is **uma única string** (o schema declara
|
|
43
|
-
`"notes": { "type": "string" }`) — para registrar mais de um desvio, separe-os com
|
|
44
|
-
`;` ou `\n` dentro da mesma string. Um array é **rejeitado** pelo validador, com a
|
|
45
|
-
mensagem `'notes' must be a string`.
|
|
46
|
-
|
|
47
|
-
```json
|
|
48
|
-
{
|
|
49
|
-
"id": "T3",
|
|
50
|
-
"status": "done",
|
|
51
|
-
"outputs": ["Features/User/Update/Handler.cs"],
|
|
52
|
-
"notes": "deviation: split validation into a separate validator for testability; blocker-resolved: EF migration conflict fixed by regenerating the snapshot"
|
|
53
|
-
}
|
|
54
|
-
```
|
|
@@ -1,244 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
stacks:
|
|
3
|
-
- "*"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# MORPH-SPEC Workflow Rules
|
|
7
|
-
|
|
8
|
-
> Always-active rules for all MORPH-SPEC managed projects.
|
|
9
|
-
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
## Spec-First Mandate
|
|
13
|
-
|
|
14
|
-
**NEVER skip to code without a specification.** Every feature must progress through phases:
|
|
15
|
-
|
|
16
|
-
1. **Proposal** — Problem statement + scope + risks (`0-proposal/proposal.md`). No acceptance criteria: verifiable behaviour lives in the use cases.
|
|
17
|
-
2. **UI/UX Design** (optional, UI-heavy) — Design system + mockups + flows. The phase id is `uiux` (that is the gate name); the folder is `1-design/`
|
|
18
|
-
3. **Plan** — Use cases first, then technical spec + tasks (`2-plan/usecases/UC-{nn}-{slug}.md`, `spec.md`, `tasks.json`). Each use case post-condition must be observable in a test and reaches the task's `doneCriteria` verbatim.
|
|
19
|
-
4. **Implement** — Code + recap (`3-implement/recap.md`)
|
|
20
|
-
5. **Review** — Review report + Gate 3 (`4-review/review-report.md`)
|
|
21
|
-
|
|
22
|
-
---
|
|
23
|
-
|
|
24
|
-
## Phase Sequence
|
|
25
|
-
|
|
26
|
-
```
|
|
27
|
-
proposal → [uiux] → plan → implement → review
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
Use `morph-spec status {feature}` to see current phase and pending approval gates.
|
|
31
|
-
|
|
32
|
-
---
|
|
33
|
-
|
|
34
|
-
## Phase Commands
|
|
35
|
-
|
|
36
|
-
| Command | Purpose |
|
|
37
|
-
|---------|---------|
|
|
38
|
-
| `/morph-proposal {feature}` | Business understanding + plan — pauses at Gate 1 and Gate 2 |
|
|
39
|
-
| `/morph-apply {feature}` | Autonomous execution + review — pauses at Gate 3 |
|
|
40
|
-
| `/morph-status` | Feature dashboard |
|
|
41
|
-
|
|
42
|
-
The full slash-command and CLI surface lives in the resident `.claude/CLAUDE.md` and in
|
|
43
|
-
`.morph/framework/CLI.md` — this table only carries the three phase entry points.
|
|
44
|
-
|
|
45
|
-
---
|
|
46
|
-
|
|
47
|
-
## State & Outputs
|
|
48
|
-
|
|
49
|
-
| Path | Notes |
|
|
50
|
-
|------|-------|
|
|
51
|
-
| `.morph/features/{feature}/feature.json` | **Authoritative + committed** feature state. Write it through the CLI (`create`, `score`, `gate-check`, `approve`) — a hand Edit collides with the `state-sync` hook |
|
|
52
|
-
| `.morph/state.json` | **READ-ONLY** — thin, gitignored index rebuilt from `feature.json` on load; kept in sync by the `state-sync` hook |
|
|
53
|
-
| `.morph/features/{feature}/{phase}/` | Feature outputs organized by phase |
|
|
54
|
-
| `.morph/framework/` | **READ-ONLY** — framework files managed by morph-spec |
|
|
55
|
-
| `.morph/config/config.json` | Project configuration (editable) |
|
|
56
|
-
|
|
57
|
-
### output types
|
|
58
|
-
|
|
59
|
-
The canonical filename and phase folder of every output type are fixed by
|
|
60
|
-
morph-spec itself — the concrete paths are in the table below. State sync is
|
|
61
|
-
handled automatically by the `state-sync.js` PostToolUse hook: write the file
|
|
62
|
-
at the right path and it is recorded; the agent does not call any CLI to
|
|
63
|
-
register an output.
|
|
64
|
-
|
|
65
|
-
---
|
|
66
|
-
|
|
67
|
-
## Output Paths
|
|
68
|
-
|
|
69
|
-
All outputs go in `.morph/features/{feature}/`:
|
|
70
|
-
|
|
71
|
-
| Phase | Path |
|
|
72
|
-
|-------|------|
|
|
73
|
-
| Proposal | `0-proposal/proposal.md`, `stack-scan.md` |
|
|
74
|
-
| Design (optional) | `1-design/design-system.md`, `mockups.md`, `components.md`, `flows.md` |
|
|
75
|
-
| Plan | `2-plan/usecases/`, `spec.md`, `tasks.json`, `decisions.md` |
|
|
76
|
-
| Implement | `3-implement/recap.md` + source code; `3-implement/evidencias/{taskId}.md` (condicional — task cujo `doneCriteria` julga saída de LLM) |
|
|
77
|
-
| Review | `4-review/review-report.md` |
|
|
78
|
-
|
|
79
|
-
---
|
|
80
|
-
|
|
81
|
-
## Formato obrigatório do `3-implement/recap.md`
|
|
82
|
-
|
|
83
|
-
> Esta exigência é **cobrada por hook** (`validate-completion`, no Stop). Ela está aqui, na regra
|
|
84
|
-
> sempre-ativa, e não só na skill `morph-implement`: descobrir o formato quando o hook dispara
|
|
85
|
-
> significa reescrever o recap depois de a fase já estar dada por encerrada.
|
|
86
|
-
|
|
87
|
-
**Para CADA task com `status: "done"` em `tasks.json`**, o recap precisa de um bloco próprio:
|
|
88
|
-
|
|
89
|
-
1. um heading `## T{N}` (o hook casa `^## T\d+` — uma linha de tabela `| T1 | … | done |` conta
|
|
90
|
-
como menção, **não** como bloco);
|
|
91
|
-
2. uma linha `**Standard:** {standard-id}` **dentro de 12 linhas** do heading. Sem standard que
|
|
92
|
-
cubra o caso, registre a decisão em `decisions.md` e cite
|
|
93
|
-
`**Standard:** ad-hoc (see decisions.md ADR-{N})`.
|
|
94
|
-
|
|
95
|
-
```markdown
|
|
96
|
-
## T{N} — {title}
|
|
97
|
-
|
|
98
|
-
**Standard:** {standard-id} (`.morph/framework/standards/{path}.md`)
|
|
99
|
-
**Persona:** {mecanismo real usado}
|
|
100
|
-
**Files:**
|
|
101
|
-
- `{path}`
|
|
102
|
-
|
|
103
|
-
{2-3 frases sobre o que foi feito}
|
|
104
|
-
|
|
105
|
-
**Issues encontrados:** {breve descrição ou "nenhum"}
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
O `validate-completion` também acusa **drift**: uma task que aparece como concluída no recap mas
|
|
109
|
-
ainda está `pending`/`in_progress` no `tasks.json`. Template completo e regras de exceção em
|
|
110
|
-
`morph-implement` §6.
|
|
111
|
-
|
|
112
|
-
---
|
|
113
|
-
|
|
114
|
-
## Checkpoints
|
|
115
|
-
|
|
116
|
-
Run a checkpoint every 3 completed tasks:
|
|
117
|
-
- Validate architecture compliance
|
|
118
|
-
- Check package versions
|
|
119
|
-
- Scan for security issues
|
|
120
|
-
- Verify design system adherence (UI features)
|
|
121
|
-
|
|
122
|
-
---
|
|
123
|
-
|
|
124
|
-
## Approval Gates
|
|
125
|
-
|
|
126
|
-
Before completing any phase, verify pending approval gates:
|
|
127
|
-
- `morph-spec approval-status <feature>` — check which gates are pending
|
|
128
|
-
- `morph-spec approve <feature> <gate>` — approve a gate (`proposal`, `plan`, `review`; `uiux` if applicable)
|
|
129
|
-
- `morph-spec advance <feature>` — approve the current gate AND scaffold the next phase folder in one step
|
|
130
|
-
- Gates must be approved before advancing to the next phase
|
|
131
|
-
|
|
132
|
-
---
|
|
133
|
-
|
|
134
|
-
## Protected Files
|
|
135
|
-
|
|
136
|
-
**NEVER directly edit:**
|
|
137
|
-
- `.morph/state.json` — Managed by CLI only
|
|
138
|
-
- `.morph/framework/**` — Read-only framework content
|
|
139
|
-
|
|
140
|
-
---
|
|
141
|
-
|
|
142
|
-
## Test File Policy
|
|
143
|
-
|
|
144
|
-
When a test fails, always follow this order:
|
|
145
|
-
|
|
146
|
-
1. **Analyze first** — determine if the IMPLEMENTATION is wrong or the TEST SPEC is wrong
|
|
147
|
-
2. **Fix implementation first** — the test is the spec; trust it by default
|
|
148
|
-
3. **Only modify a test file if the test expectation itself is incorrect** — wrong expected value, wrong behavior modeled
|
|
149
|
-
4. **Before modifying any test file, explain WHY the test spec is wrong** — what the correct behavior is and why the test doesn't model it
|
|
150
|
-
|
|
151
|
-
Do not modify test files to make a failing test pass when the implementation is the actual problem.
|
|
152
|
-
|
|
153
|
-
---
|
|
154
|
-
|
|
155
|
-
## Context Maintenance
|
|
156
|
-
|
|
157
|
-
After making structural changes (new packages, dependencies, project config changes), update the project context:
|
|
158
|
-
- Edit `.morph/context/README.md` — update Tech Stack, Architecture, Key Integrations sections
|
|
159
|
-
- Any `.morph/context/*.md`: **rewrite the body, never stack** — the section that described the old fact now describes the new one (a value that still holds somewhere says where); a changelog keeps only date and reason
|
|
160
|
-
- Update `.morph/config/config.json` — update stack, architecture, integrations, paths
|
|
161
|
-
- Structural changes include: package.json, .csproj, next.config.*, tsconfig.json, docker-compose.yml
|
|
162
|
-
|
|
163
|
-
---
|
|
164
|
-
|
|
165
|
-
## Spec-Driven Task Execution (implement phase)
|
|
166
|
-
|
|
167
|
-
BEFORE implementing ANY task during the implement phase:
|
|
168
|
-
|
|
169
|
-
1. **Read tasks.json** → identify the current task object (`id`, `description`, `doneCriteria`, `dependencies`)
|
|
170
|
-
2. **Read spec.md** → the FR sections that the task `description` references
|
|
171
|
-
3. **Read the contracts** → the DTOs/interfaces are defined inside `spec.md` (v5 keeps contracts in the spec, not separate files)
|
|
172
|
-
4. Only then begin implementation
|
|
173
|
-
|
|
174
|
-
This is **NON-NEGOTIABLE**. The spec is the source of truth. Code that doesn't match the spec is a bug.
|
|
175
|
-
|
|
176
|
-
Every task in `tasks.json` MUST reference its FR(s) in the `description` field so the link to the spec is explicit:
|
|
177
|
-
```json
|
|
178
|
-
{
|
|
179
|
-
"id": "T1",
|
|
180
|
-
"title": "Create user endpoint",
|
|
181
|
-
"description": "Implement user CRUD (FR001) and input validation (FR003). Contracts: CreateUserRequest, CreateUserResponse, UserErrors.",
|
|
182
|
-
"dependencies": [],
|
|
183
|
-
"effort": "M",
|
|
184
|
-
"doneCriteria": "POST /users creates a user and rejects invalid input",
|
|
185
|
-
"status": "pending",
|
|
186
|
-
"outputs": ["Features/UserFeature/Create/Handler.cs", "Validator.cs", "Endpoint.cs"],
|
|
187
|
-
"group": "backend"
|
|
188
|
-
}
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
---
|
|
192
|
-
|
|
193
|
-
## Debugging
|
|
194
|
-
|
|
195
|
-
When a bug or unexpected behavior shows up mid-task, find the **root cause before proposing a
|
|
196
|
-
fix** — never a patch on the symptom. This is MANDATORY:
|
|
197
|
-
|
|
198
|
-
1. Reproduce it and read the full error, not the first line.
|
|
199
|
-
2. For a known .NET/Next.js error, run `/morph-troubleshoot <keywords>` first.
|
|
200
|
-
3. One hypothesis at a time, each tested by the smallest check that could refute it.
|
|
201
|
-
4. After three failed fixes, stop and question the design instead of trying a fourth.
|
|
202
|
-
5. Confirm the fix with the same check that reproduced the bug; add a test only when no existing one covers that behavior.
|
|
203
|
-
|
|
204
|
-
Everything else that a rule like this might list is owned by the flow itself, and duplicating it
|
|
205
|
-
here would put a second, staler copy in permanent context:
|
|
206
|
-
|
|
207
|
-
| Concern | Where it actually lives |
|
|
208
|
-
|---------|-------------------------|
|
|
209
|
-
| How many tests to write | The test budget in `morph-plan` §5: one test per postcondition, same-behavior cases in one table, no test that only pins text |
|
|
210
|
-
| Verifying a task before `status: "done"` | `morph-spec verify {feature} [task]` (build + tests + validators + e2e) green, and each `doneCriteria` with the test or `file:line` that proves it |
|
|
211
|
-
| Parallel dispatch | `morph-spec dag {feature}` decides sequential vs parallel; execution and isolation rules are in `morph-apply` §2/§3b |
|
|
212
|
-
| Closing the phase / opening the PR | `morph-review` for Gate 3, then `morph-spec finish {feature} --pr\|--merge` |
|
|
213
|
-
|
|
214
|
-
---
|
|
215
|
-
|
|
216
|
-
## Scope Escalation
|
|
217
|
-
|
|
218
|
-
The plan contract frozen at Gate 2 — `spec.md` and the immutable `tasks.json`
|
|
219
|
-
fields listed in `morph-task-tracking.md` — is enforced by the `protect-spec-files` hook. When a
|
|
220
|
-
task turns out to be bigger than estimated, three different situations resolve three different ways:
|
|
221
|
-
|
|
222
|
-
| Situation | Path |
|
|
223
|
-
|-----------|------|
|
|
224
|
-
| **Small addition**, still inside the task's scope | Record it in the task's `notes` (a mutable field) — no gate to revoke, no contract to amend |
|
|
225
|
-
| **Error of fact**: the spec asserts something about the code that the code contradicts, with no scope change | Append an `## Errata` block at the END of the file. Body untouched, append-only, accepted by `protect-spec-files` **without revoking the gate** — freezing the CONTRACT is not freezing an ERROR OF FACT (MORPH.md §3) |
|
|
226
|
-
| **The scope itself changed**: the contract no longer describes the work | `morph-spec unapprove {feature} plan --reason "..."`, amend the plan, then re-approve. There is no shortcut around the gate for this one |
|
|
227
|
-
|
|
228
|
-
Scope ambiguity the plan does not cover is **not** an escalation: record it in
|
|
229
|
-
`decisions.md`, resolve it the conservative way, and keep going — only pause if it is genuinely
|
|
230
|
-
blocking (`morph-implement` §5).
|
|
231
|
-
|
|
232
|
-
**Never** implement extra functionality within a task without registering it — `notes` for small
|
|
233
|
-
additions, gate revocation for anything that changes the plan contract.
|
|
234
|
-
|
|
235
|
-
---
|
|
236
|
-
|
|
237
|
-
## Context Window Tip
|
|
238
|
-
|
|
239
|
-
When using 3+ MCPs, add `"experimental": { "mcpCliMode": true }` to `.claude/settings.json`.
|
|
240
|
-
MCP tools load on-demand instead of all at startup — keeps context clean for actual work.
|
|
241
|
-
|
|
242
|
-
---
|
|
243
|
-
|
|
244
|
-
*MORPH-SPEC by Polymorphism Tech*
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
-
"title": "MORPH-SPEC tasks.json",
|
|
4
|
-
"description": "Structured task list for a morph-spec feature. Replaces tasks.md.",
|
|
5
|
-
"type": "object",
|
|
6
|
-
"required": ["version", "feature", "tasks"],
|
|
7
|
-
"properties": {
|
|
8
|
-
"version": { "type": "string", "const": "1.0" },
|
|
9
|
-
"feature": { "type": "string", "minLength": 1 },
|
|
10
|
-
"tasks": {
|
|
11
|
-
"type": "array",
|
|
12
|
-
"items": {
|
|
13
|
-
"type": "object",
|
|
14
|
-
"required": ["id", "title", "description", "dependencies", "effort", "doneCriteria", "status"],
|
|
15
|
-
"properties": {
|
|
16
|
-
"id": { "type": "string", "pattern": "^T\\d+$" },
|
|
17
|
-
"title": { "type": "string", "minLength": 1 },
|
|
18
|
-
"description": { "type": "string", "minLength": 1 },
|
|
19
|
-
"dependencies": {
|
|
20
|
-
"type": "array",
|
|
21
|
-
"items": { "type": "string", "pattern": "^T\\d+$" }
|
|
22
|
-
},
|
|
23
|
-
"effort": { "type": "string", "enum": ["S", "M", "L", "XL"] },
|
|
24
|
-
"doneCriteria": { "type": "string", "minLength": 1 },
|
|
25
|
-
"status": { "type": "string", "enum": ["pending", "in_progress", "done", "skipped", "blocked"] },
|
|
26
|
-
"outputs": { "type": "array", "items": { "type": "string" } },
|
|
27
|
-
"notes": { "type": "string" },
|
|
28
|
-
"group": { "type": "string", "enum": ["backend", "frontend", "tests", "infra", "docs"] },
|
|
29
|
-
"usecase": {
|
|
30
|
-
"type": "string",
|
|
31
|
-
"pattern": "^UC-\\d+$",
|
|
32
|
-
"description": "ID of the use case this task realizes (2-plan/usecases/UC-{nn}-{slug}.md). Optional: technical tasks with no observable behaviour have none."
|
|
33
|
-
},
|
|
34
|
-
"agent": {
|
|
35
|
-
"type": "string",
|
|
36
|
-
"minLength": 1,
|
|
37
|
-
"description": "Persona id assigned by morph-plan for this task — the bare framework/agents.json id, no 'morph-' prefix (e.g. \"dotnet-senior\"). Optional. Part of the plan contract: frozen after Gate 2."
|
|
38
|
-
},
|
|
39
|
-
"reuse": {
|
|
40
|
-
"type": "array",
|
|
41
|
-
"description": "Veredito de reuso por conceito que ESTA task introduz, carimbado por morph-plan. Optional. Part of the plan contract: frozen after Gate 2.",
|
|
42
|
-
"items": {
|
|
43
|
-
"type": "object",
|
|
44
|
-
"required": ["concept", "verdict"],
|
|
45
|
-
"properties": {
|
|
46
|
-
"concept": {
|
|
47
|
-
"type": "string",
|
|
48
|
-
"minLength": 1,
|
|
49
|
-
"description": "Nome do conceito/símbolo, como ele aparecerá no código (ex.: \"SimpleBuilding\")."
|
|
50
|
-
},
|
|
51
|
-
"verdict": {
|
|
52
|
-
"type": "string",
|
|
53
|
-
"enum": ["REUSAR", "ESTENDER", "CRIAR"],
|
|
54
|
-
"description": "REUSAR: usar o que existe. ESTENDER: partir do que existe. CRIAR: nada cobre o caso — exige `why`."
|
|
55
|
-
},
|
|
56
|
-
"target": {
|
|
57
|
-
"type": "string",
|
|
58
|
-
"description": "Path (ou path:símbolo) do que será reusado/estendido. Vazio ou ausente em CRIAR."
|
|
59
|
-
},
|
|
60
|
-
"why": {
|
|
61
|
-
"type": "string",
|
|
62
|
-
"description": "Uma linha: por que nada existente cobre o caso. Exigido em CRIAR."
|
|
63
|
-
}
|
|
64
|
-
},
|
|
65
|
-
"additionalProperties": false
|
|
66
|
-
}
|
|
67
|
-
},
|
|
68
|
-
"standards": {
|
|
69
|
-
"type": "array",
|
|
70
|
-
"items": { "type": "string", "minLength": 1 },
|
|
71
|
-
"description": "Standards pinned by morph-plan for this task, as PATHS relative to the framework root (e.g. \"standards/backend/dotnet/vsa-handler-patterns.md\"). Optional. Part of the plan contract: frozen after Gate 2. NOT the same vocabulary as agents.json's top-level `standards` field, which lists IDs (e.g. \"backend-dotnet-vsa-handler-patterns\", no slashes/extension) — same field name, different shape; do not treat one as the other."
|
|
72
|
-
}
|
|
73
|
-
},
|
|
74
|
-
"additionalProperties": false
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
},
|
|
78
|
-
"additionalProperties": false
|
|
79
|
-
}
|