@polymorphism-tech/morph-spec 7.1.1 → 7.3.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/README.md +2 -2
- package/claude-plugin.json +1 -1
- package/docs/CHEATSHEET.md +1 -1
- package/docs/QUICKSTART.md +1 -1
- package/framework/CLAUDE.md +4 -2
- package/framework/MORPH.md +3 -3
- package/framework/commands/morph-apply.md +1 -1
- package/framework/commands/morph-proposal.md +1 -1
- package/framework/hooks/README.md +1 -1
- package/framework/hooks/claude-code/core/protect-spec-files.js +193 -72
- package/framework/hooks/claude-code/core/validate-completion.js +136 -136
- package/framework/hooks/shared/phase-utils.js +10 -0
- package/framework/phases.json +1 -1
- package/framework/rules/morph-workflow.md +16 -9
- package/framework/skills/README.md +1 -1
- package/framework/skills/core/morph-apply/SKILL.md +1 -0
- package/framework/skills/core/morph-brainstorming/SKILL.md +1 -0
- package/framework/skills/core/morph-eval/SKILL.md +1 -0
- package/framework/skills/core/morph-implement/SKILL.md +7 -0
- package/framework/skills/core/morph-plan/SKILL.md +1 -0
- package/framework/skills/core/morph-proposal/SKILL.md +1 -0
- package/framework/skills/core/morph-review/SKILL.md +1 -0
- package/framework/skills/core/morph-stack-scan/SKILL.md +1 -0
- package/framework/skills/core/morph-standards/SKILL.md +1 -0
- package/framework/templates/README.md +708 -709
- package/framework/templates/REGISTRY.json +1 -20
- package/framework/templates/context/CONTEXT-FEATURE.md +276 -276
- package/framework/templates/docs/proposal.md +171 -171
- package/framework/templates/feature/recap.md +145 -145
- package/package.json +1 -1
- package/src/commands/project/doctor.js +941 -946
- package/src/commands/project/status.js +373 -376
- package/src/commands/validation/validate-feature.js +315 -287
- package/src/core/paths/output-schema.js +18 -1
- package/src/core/state/state-manager.js +900 -934
- package/src/dashboard/app/App.jsx +29 -31
- package/src/dashboard/app/components/Sidebar.jsx +44 -45
- package/src/dashboard/scanner/index.js +20 -21
- package/src/lib/context/context-builder.js +3 -3
- package/src/lib/generators/context-generator.js +2 -3
- package/src/lib/generators/mandate-generator.js +48 -92
- package/src/lib/generators/metadata-extractor.js +385 -386
- package/src/lib/generators/recap-generator.js +285 -285
- package/src/lib/validators/content/content-validator.js +89 -286
- package/src/lib/validators/content/index.js +0 -1
- package/framework/templates/feature/tasks.md +0 -199
- package/framework/workflows/README.md +0 -1041
- package/framework/workflows/configs/fast-track.json +0 -46
- package/framework/workflows/configs/full.json +0 -64
- package/framework/workflows/configs/quick.json +0 -32
- package/framework/workflows/configs/standard.json +0 -57
- package/framework/workflows/docs/STORY-DRIVEN-DEVELOPMENT.md +0 -392
- package/framework/workflows/docs/design-impl.md +0 -37
- package/framework/workflows/docs/enforcement-pipeline.md +0 -668
- package/framework/workflows/docs/fast-track.md +0 -29
- package/framework/workflows/docs/full-morph.md +0 -69
- package/framework/workflows/docs/standard.md +0 -49
- package/framework/workflows/docs/ui-refresh.md +0 -39
- package/src/commands/state/index.js +0 -7
- package/src/core/workflows/workflow-detector.js +0 -586
- package/src/core/workflows/workflow-router.js +0 -204
- package/src/dashboard/app/pages/Workflows.jsx +0 -346
- package/src/dashboard/scanner/workflows-scanner.js +0 -18
- package/src/lib/phase-chain/phase-validator.js +0 -359
- package/src/lib/validators/content/cross-phase-validator.js +0 -281
- package/src/lib/validators/spec-validator.js +0 -312
|
@@ -1,136 +1,136 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Stop Hook: Phase Transition Alert + Build Check + Session Snapshot
|
|
5
|
-
*
|
|
6
|
-
* Event: Stop
|
|
7
|
-
*
|
|
8
|
-
* 1. Detects transitions into the `implement` phase and recommends /compact.
|
|
9
|
-
* 2. Runs stack-aware build check — warns only on failure (silent on pass).
|
|
10
|
-
* 3. Saves session snapshot for next-session orientation.
|
|
11
|
-
*
|
|
12
|
-
* Phase transition tracking: stores last-seen phase per feature in
|
|
13
|
-
* .morph/memory/phase-watch.json so the alert fires exactly once.
|
|
14
|
-
*
|
|
15
|
-
* Fail-open: exits 0 on any error.
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
import { readFileSync, writeFileSync, existsSync } from 'fs';
|
|
19
|
-
import { join } from 'path';
|
|
20
|
-
import { runBuildCheck } from '../../shared/build-check.js';
|
|
21
|
-
import { saveSessionSnapshot } from '../../shared/session-snapshot.js';
|
|
22
|
-
import {
|
|
23
|
-
stateExists, getActiveFeature, getMostRecentFeature, derivePhaseForFeature,
|
|
24
|
-
} from '../../shared/state-reader.js';
|
|
25
|
-
import { injectContext, pass } from '../../shared/hook-response.js';
|
|
26
|
-
import { logHookActivity, logEvent } from '../../shared/activity-logger.js';
|
|
27
|
-
|
|
28
|
-
// Phases where compaction is strongly recommended before starting
|
|
29
|
-
const COMPACT_TRIGGER_PHASES = new Set(['implement']);
|
|
30
|
-
|
|
31
|
-
// Phases where compaction is suggested when arriving (heavy spec phases)
|
|
32
|
-
const HEAVY_SOURCE_PHASES = new Set(['plan', 'uiux']);
|
|
33
|
-
|
|
34
|
-
try {
|
|
35
|
-
// Prevent infinite loop
|
|
36
|
-
if (process.env.MORPH_STOP_HOOK_ACTIVE === '1') pass();
|
|
37
|
-
|
|
38
|
-
if (!stateExists()) pass();
|
|
39
|
-
|
|
40
|
-
// getActiveFeature() only returns in_progress/draft features.
|
|
41
|
-
// Fall back to the most recently updated feature when all features are 'done'.
|
|
42
|
-
let active = getActiveFeature() || getMostRecentFeature();
|
|
43
|
-
if (!active) pass();
|
|
44
|
-
|
|
45
|
-
const { name, feature } = active;
|
|
46
|
-
const cwd = process.cwd();
|
|
47
|
-
const warnings = [];
|
|
48
|
-
|
|
49
|
-
// ── Phase transition detection ────────────────────────────────────────────
|
|
50
|
-
const currentPhase = feature.phase || derivePhaseForFeature(name, cwd);
|
|
51
|
-
|
|
52
|
-
const watchPath = join(cwd, '.morph', 'memory', 'phase-watch.json');
|
|
53
|
-
let phaseWatch = {};
|
|
54
|
-
try {
|
|
55
|
-
if (existsSync(watchPath)) phaseWatch = JSON.parse(readFileSync(watchPath, 'utf-8'));
|
|
56
|
-
} catch { /* corrupt file — start fresh */ }
|
|
57
|
-
|
|
58
|
-
const lastPhase = phaseWatch[name];
|
|
59
|
-
|
|
60
|
-
// Update stored phase (always, so the alert only fires once per transition)
|
|
61
|
-
try {
|
|
62
|
-
phaseWatch[name] = currentPhase;
|
|
63
|
-
writeFileSync(watchPath, JSON.stringify(phaseWatch, null, 2), 'utf-8');
|
|
64
|
-
} catch { /* non-blocking */ }
|
|
65
|
-
|
|
66
|
-
// Alert when entering implement from a heavy spec phase
|
|
67
|
-
const isPhaseTransition = lastPhase && lastPhase !== currentPhase;
|
|
68
|
-
const enteringImplement = COMPACT_TRIGGER_PHASES.has(currentPhase);
|
|
69
|
-
const comingFromHeavyPhase = HEAVY_SOURCE_PHASES.has(lastPhase);
|
|
70
|
-
|
|
71
|
-
if (isPhaseTransition && enteringImplement && comingFromHeavyPhase) {
|
|
72
|
-
warnings.push(
|
|
73
|
-
`⚡ Phase advanced: ${lastPhase} → implement`,
|
|
74
|
-
``,
|
|
75
|
-
`💡 Recommended before starting implementation:`,
|
|
76
|
-
` Run /compact to free up context — spec.md, mandate.md and tasks.
|
|
77
|
-
` loaded during planning take significant space. A compact now gives`,
|
|
78
|
-
` Claude a clean slate focused on writing code.`,
|
|
79
|
-
``,
|
|
80
|
-
` After /compact, resume with: /morph-apply ${name}`,
|
|
81
|
-
);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// ── Build/typecheck verification ──────────────────────────────────────────
|
|
85
|
-
// Stack-aware build check — advisory warning if build fails.
|
|
86
|
-
// Success is silent (no output on pass).
|
|
87
|
-
try {
|
|
88
|
-
const configPath = join(cwd, '.morph', 'config', 'config.json');
|
|
89
|
-
if (existsSync(configPath)) {
|
|
90
|
-
const config = JSON.parse(readFileSync(configPath, 'utf-8'));
|
|
91
|
-
const stack = config?.project?.stack;
|
|
92
|
-
if (stack && currentPhase === 'implement') {
|
|
93
|
-
const buildResult = runBuildCheck(cwd, stack);
|
|
94
|
-
if (buildResult.status === 'fail') {
|
|
95
|
-
warnings.push('⚠ Build/typecheck failed:');
|
|
96
|
-
warnings.push(buildResult.output);
|
|
97
|
-
warnings.push('Fix build errors before ending session.');
|
|
98
|
-
}
|
|
99
|
-
// pass and skip → silent (success is silent)
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
} catch {
|
|
103
|
-
// Fail-open — build check must never block Stop
|
|
104
|
-
}
|
|
105
|
-
// ────────────────────────────────────────────────────────────────────────
|
|
106
|
-
|
|
107
|
-
// ── Session snapshot ──────────────────────────────────────────────────────
|
|
108
|
-
// Save session state for next session's "getting up to speed" routine.
|
|
109
|
-
try {
|
|
110
|
-
if (active) {
|
|
111
|
-
const { name } = active;
|
|
112
|
-
saveSessionSnapshot({
|
|
113
|
-
feature: name,
|
|
114
|
-
phase: currentPhase,
|
|
115
|
-
buildStatus: 'skip',
|
|
116
|
-
lastEditedFiles: [],
|
|
117
|
-
}, cwd);
|
|
118
|
-
}
|
|
119
|
-
} catch {
|
|
120
|
-
// Fail-open — snapshot save must never block Stop
|
|
121
|
-
}
|
|
122
|
-
// ────────────────────────────────────────────────────────────────────────
|
|
123
|
-
|
|
124
|
-
if (warnings.length === 0) pass();
|
|
125
|
-
|
|
126
|
-
const message = [
|
|
127
|
-
'MORPH-SPEC:',
|
|
128
|
-
...warnings.map(w => ` ${w}`),
|
|
129
|
-
].join('\n');
|
|
130
|
-
|
|
131
|
-
logHookActivity('validate-completion', 'Stop', `warnings(${warnings.length})`);
|
|
132
|
-
logEvent('session_end', { feature: name, phase: currentPhase, warnings: warnings.length });
|
|
133
|
-
injectContext(message);
|
|
134
|
-
} catch {
|
|
135
|
-
process.exit(0);
|
|
136
|
-
}
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Stop Hook: Phase Transition Alert + Build Check + Session Snapshot
|
|
5
|
+
*
|
|
6
|
+
* Event: Stop
|
|
7
|
+
*
|
|
8
|
+
* 1. Detects transitions into the `implement` phase and recommends /compact.
|
|
9
|
+
* 2. Runs stack-aware build check — warns only on failure (silent on pass).
|
|
10
|
+
* 3. Saves session snapshot for next-session orientation.
|
|
11
|
+
*
|
|
12
|
+
* Phase transition tracking: stores last-seen phase per feature in
|
|
13
|
+
* .morph/memory/phase-watch.json so the alert fires exactly once.
|
|
14
|
+
*
|
|
15
|
+
* Fail-open: exits 0 on any error.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { readFileSync, writeFileSync, existsSync } from 'fs';
|
|
19
|
+
import { join } from 'path';
|
|
20
|
+
import { runBuildCheck } from '../../shared/build-check.js';
|
|
21
|
+
import { saveSessionSnapshot } from '../../shared/session-snapshot.js';
|
|
22
|
+
import {
|
|
23
|
+
stateExists, getActiveFeature, getMostRecentFeature, derivePhaseForFeature,
|
|
24
|
+
} from '../../shared/state-reader.js';
|
|
25
|
+
import { injectContext, pass } from '../../shared/hook-response.js';
|
|
26
|
+
import { logHookActivity, logEvent } from '../../shared/activity-logger.js';
|
|
27
|
+
|
|
28
|
+
// Phases where compaction is strongly recommended before starting
|
|
29
|
+
const COMPACT_TRIGGER_PHASES = new Set(['implement']);
|
|
30
|
+
|
|
31
|
+
// Phases where compaction is suggested when arriving (heavy spec phases)
|
|
32
|
+
const HEAVY_SOURCE_PHASES = new Set(['plan', 'uiux']);
|
|
33
|
+
|
|
34
|
+
try {
|
|
35
|
+
// Prevent infinite loop
|
|
36
|
+
if (process.env.MORPH_STOP_HOOK_ACTIVE === '1') pass();
|
|
37
|
+
|
|
38
|
+
if (!stateExists()) pass();
|
|
39
|
+
|
|
40
|
+
// getActiveFeature() only returns in_progress/draft features.
|
|
41
|
+
// Fall back to the most recently updated feature when all features are 'done'.
|
|
42
|
+
let active = getActiveFeature() || getMostRecentFeature();
|
|
43
|
+
if (!active) pass();
|
|
44
|
+
|
|
45
|
+
const { name, feature } = active;
|
|
46
|
+
const cwd = process.cwd();
|
|
47
|
+
const warnings = [];
|
|
48
|
+
|
|
49
|
+
// ── Phase transition detection ────────────────────────────────────────────
|
|
50
|
+
const currentPhase = feature.phase || derivePhaseForFeature(name, cwd);
|
|
51
|
+
|
|
52
|
+
const watchPath = join(cwd, '.morph', 'memory', 'phase-watch.json');
|
|
53
|
+
let phaseWatch = {};
|
|
54
|
+
try {
|
|
55
|
+
if (existsSync(watchPath)) phaseWatch = JSON.parse(readFileSync(watchPath, 'utf-8'));
|
|
56
|
+
} catch { /* corrupt file — start fresh */ }
|
|
57
|
+
|
|
58
|
+
const lastPhase = phaseWatch[name];
|
|
59
|
+
|
|
60
|
+
// Update stored phase (always, so the alert only fires once per transition)
|
|
61
|
+
try {
|
|
62
|
+
phaseWatch[name] = currentPhase;
|
|
63
|
+
writeFileSync(watchPath, JSON.stringify(phaseWatch, null, 2), 'utf-8');
|
|
64
|
+
} catch { /* non-blocking */ }
|
|
65
|
+
|
|
66
|
+
// Alert when entering implement from a heavy spec phase
|
|
67
|
+
const isPhaseTransition = lastPhase && lastPhase !== currentPhase;
|
|
68
|
+
const enteringImplement = COMPACT_TRIGGER_PHASES.has(currentPhase);
|
|
69
|
+
const comingFromHeavyPhase = HEAVY_SOURCE_PHASES.has(lastPhase);
|
|
70
|
+
|
|
71
|
+
if (isPhaseTransition && enteringImplement && comingFromHeavyPhase) {
|
|
72
|
+
warnings.push(
|
|
73
|
+
`⚡ Phase advanced: ${lastPhase} → implement`,
|
|
74
|
+
``,
|
|
75
|
+
`💡 Recommended before starting implementation:`,
|
|
76
|
+
` Run /compact to free up context — spec.md, mandate.md and tasks.json`,
|
|
77
|
+
` loaded during planning take significant space. A compact now gives`,
|
|
78
|
+
` Claude a clean slate focused on writing code.`,
|
|
79
|
+
``,
|
|
80
|
+
` After /compact, resume with: /morph-apply ${name}`,
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// ── Build/typecheck verification ──────────────────────────────────────────
|
|
85
|
+
// Stack-aware build check — advisory warning if build fails.
|
|
86
|
+
// Success is silent (no output on pass).
|
|
87
|
+
try {
|
|
88
|
+
const configPath = join(cwd, '.morph', 'config', 'config.json');
|
|
89
|
+
if (existsSync(configPath)) {
|
|
90
|
+
const config = JSON.parse(readFileSync(configPath, 'utf-8'));
|
|
91
|
+
const stack = config?.project?.stack;
|
|
92
|
+
if (stack && currentPhase === 'implement') {
|
|
93
|
+
const buildResult = runBuildCheck(cwd, stack);
|
|
94
|
+
if (buildResult.status === 'fail') {
|
|
95
|
+
warnings.push('⚠ Build/typecheck failed:');
|
|
96
|
+
warnings.push(buildResult.output);
|
|
97
|
+
warnings.push('Fix build errors before ending session.');
|
|
98
|
+
}
|
|
99
|
+
// pass and skip → silent (success is silent)
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
} catch {
|
|
103
|
+
// Fail-open — build check must never block Stop
|
|
104
|
+
}
|
|
105
|
+
// ────────────────────────────────────────────────────────────────────────
|
|
106
|
+
|
|
107
|
+
// ── Session snapshot ──────────────────────────────────────────────────────
|
|
108
|
+
// Save session state for next session's "getting up to speed" routine.
|
|
109
|
+
try {
|
|
110
|
+
if (active) {
|
|
111
|
+
const { name } = active;
|
|
112
|
+
saveSessionSnapshot({
|
|
113
|
+
feature: name,
|
|
114
|
+
phase: currentPhase,
|
|
115
|
+
buildStatus: 'skip',
|
|
116
|
+
lastEditedFiles: [],
|
|
117
|
+
}, cwd);
|
|
118
|
+
}
|
|
119
|
+
} catch {
|
|
120
|
+
// Fail-open — snapshot save must never block Stop
|
|
121
|
+
}
|
|
122
|
+
// ────────────────────────────────────────────────────────────────────────
|
|
123
|
+
|
|
124
|
+
if (warnings.length === 0) pass();
|
|
125
|
+
|
|
126
|
+
const message = [
|
|
127
|
+
'MORPH-SPEC:',
|
|
128
|
+
...warnings.map(w => ` ${w}`),
|
|
129
|
+
].join('\n');
|
|
130
|
+
|
|
131
|
+
logHookActivity('validate-completion', 'Stop', `warnings(${warnings.length})`);
|
|
132
|
+
logEvent('session_end', { feature: name, phase: currentPhase, warnings: warnings.length });
|
|
133
|
+
injectContext(message);
|
|
134
|
+
} catch {
|
|
135
|
+
process.exit(0);
|
|
136
|
+
}
|
|
@@ -65,6 +65,16 @@ export const PROTECTED_SPEC_FILES = {
|
|
|
65
65
|
'tasks.json': 'plan',
|
|
66
66
|
};
|
|
67
67
|
|
|
68
|
+
/**
|
|
69
|
+
* For protected files that carry mutable progress fields: filename → the
|
|
70
|
+
* top-level array-item fields that may change after the gate is approved.
|
|
71
|
+
* When a protected file is listed here, the protect-spec-files hook does a
|
|
72
|
+
* semantic diff (allowing only these fields to change) instead of a blanket block.
|
|
73
|
+
*/
|
|
74
|
+
export const MUTABLE_SPEC_FIELDS = {
|
|
75
|
+
'tasks.json': ['status', 'outputs', 'notes'],
|
|
76
|
+
};
|
|
77
|
+
|
|
68
78
|
/**
|
|
69
79
|
* Extract feature name from a .morph/features/{feature}/... path
|
|
70
80
|
* @param {string} filePath - File path to analyze
|
package/framework/phases.json
CHANGED
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"goals": [
|
|
44
44
|
"Write spec.md (technical spec)",
|
|
45
45
|
"Write mandate.md (implementation contract with stack defaults + forbidden patterns)",
|
|
46
|
-
"Write tasks.
|
|
46
|
+
"Write tasks.json (ordered task breakdown)"
|
|
47
47
|
],
|
|
48
48
|
"requiredOutputs": ["spec", "mandate", "tasks"],
|
|
49
49
|
"optionalOutputs": ["decisions"],
|
|
@@ -125,19 +125,26 @@ After making structural changes (new packages, dependencies, project config chan
|
|
|
125
125
|
|
|
126
126
|
BEFORE implementing ANY task during the implement phase:
|
|
127
127
|
|
|
128
|
-
1. **Read tasks.
|
|
129
|
-
2. **Read spec.md** → the sections
|
|
130
|
-
3. **Read contracts
|
|
128
|
+
1. **Read tasks.json** → identify the current task object (`id`, `description`, `doneCriteria`, `dependencies`)
|
|
129
|
+
2. **Read spec.md** → the FR sections that the task `description` references
|
|
130
|
+
3. **Read the contracts** → the DTOs/interfaces are defined inside `spec.md` (v5 keeps contracts in the spec, not separate files)
|
|
131
131
|
4. Only then begin implementation
|
|
132
132
|
|
|
133
133
|
This is **NON-NEGOTIABLE**. The spec is the source of truth. Code that doesn't match the spec is a bug.
|
|
134
134
|
|
|
135
|
-
Every task in `tasks.
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
135
|
+
Every task in `tasks.json` MUST reference its FR(s) in the `description` field so the link to the spec is explicit:
|
|
136
|
+
```json
|
|
137
|
+
{
|
|
138
|
+
"id": "T1",
|
|
139
|
+
"title": "Create user endpoint",
|
|
140
|
+
"description": "Implement user CRUD (FR001) and input validation (FR003). Contracts: CreateUserRequest, CreateUserResponse, UserErrors.",
|
|
141
|
+
"dependencies": [],
|
|
142
|
+
"effort": "M",
|
|
143
|
+
"doneCriteria": "POST /users creates a user and rejects invalid input",
|
|
144
|
+
"status": "pending",
|
|
145
|
+
"outputs": ["Features/UserFeature/Create/Handler.cs", "Validator.cs", "Endpoint.cs"],
|
|
146
|
+
"group": "backend"
|
|
147
|
+
}
|
|
141
148
|
```
|
|
142
149
|
|
|
143
150
|
---
|
|
@@ -14,7 +14,7 @@ These are the only skills the harness needs. MORPH.md references them by path.
|
|
|
14
14
|
|----------------------|----------------------------------------------------------------------|----------------|
|
|
15
15
|
| `morph-brainstorming` | Business understanding + brownfield scan → proposal.md (Gate 1) | yes |
|
|
16
16
|
| `morph-stack-scan` | Detect stack drift in existing projects, generate migration-plan.md | yes |
|
|
17
|
-
| `morph-plan` | Produce spec.md + mandate.md + tasks.
|
|
17
|
+
| `morph-plan` | Produce spec.md + mandate.md + tasks.json (Gate 2) | yes |
|
|
18
18
|
| `morph-implement` | Execute each task with standard + persona, auto-advance between tasks| no |
|
|
19
19
|
| `morph-eval` | Score work 0-10 across 4 dimensions, silence on score >= 8 | no |
|
|
20
20
|
| `morph-review` | Final review report with scores + recommendation (Gate 3) | yes |
|
|
@@ -4,6 +4,7 @@ description: Guia a execução de cada tarefa de implementação com standard e
|
|
|
4
4
|
version: core
|
|
5
5
|
when-to-invoke: ao iniciar cada task de implementação listada em tasks.json
|
|
6
6
|
user-invokable: false
|
|
7
|
+
cliVersion: "7.3.0"
|
|
7
8
|
---
|
|
8
9
|
|
|
9
10
|
# morph-implement
|
|
@@ -78,6 +79,12 @@ Ao iniciar cada task de `tasks.json` — antes de escrever qualquer código. Nor
|
|
|
78
79
|
await writeTasksJson(tasksPath, data);
|
|
79
80
|
```
|
|
80
81
|
|
|
82
|
+
`tasks.json` é protegido após o Gate 2, mas os campos de progresso (`status`,
|
|
83
|
+
`outputs`, `notes`) continuam graváveis durante a fase implement. `writeTasksJson`
|
|
84
|
+
grava o arquivo **inteiro** (Write) — esse é o caminho permitido. Nunca use a
|
|
85
|
+
tool `Edit` em `tasks.json` após o Gate 2: o hook `protect-spec-files` bloqueia
|
|
86
|
+
Edit e qualquer mudança em campos de plano (`title`, `dependencies`, `doneCriteria`…).
|
|
87
|
+
|
|
81
88
|
9. Quando invocada por `morph-apply`, retornar o controle à skill orquestradora — ela decide qual task vem em seguida via `getReadyTasks(data)`. Quando invocada manualmente, verificar se há próxima task ready e iniciá-la imediatamente aplicando esta skill desde o passo 1 (auto-advance). Pause apenas se encontrar ambiguidade bloqueante não coberta pelo mandate.
|
|
82
89
|
|
|
83
90
|
## Output esperado
|
|
@@ -4,6 +4,7 @@ description: Orquestra a fase de proposta+plano de uma feature morph-spec. Encad
|
|
|
4
4
|
version: core
|
|
5
5
|
when-to-invoke: ao receber instrução "use /morph-proposal" do usuário, ou ao iniciar uma nova feature
|
|
6
6
|
user-invokable: true
|
|
7
|
+
cliVersion: "7.3.0"
|
|
7
8
|
---
|
|
8
9
|
|
|
9
10
|
# morph-proposal
|
|
@@ -4,6 +4,7 @@ description: Conduz a fase de revisão e produz o review-report.md para o Gate 3
|
|
|
4
4
|
version: core
|
|
5
5
|
when-to-invoke: ao iniciar a fase review, após todas as tasks de tasks.json estarem com status `done`
|
|
6
6
|
user-invokable: true
|
|
7
|
+
cliVersion: "7.3.0"
|
|
7
8
|
---
|
|
8
9
|
|
|
9
10
|
# morph-review
|