@haposoft/cafekit 0.16.0-rc.3 → 0.16.0-rc.5
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/bin/__tests__/change-firewall.semantic-firewall.test.js +2134 -0
- package/bin/__tests__/codex-hooks.test.js +531 -29
- package/bin/__tests__/codex-native.test.js +228 -7
- package/bin/__tests__/develop-contract.test.js +653 -185
- package/bin/__tests__/finalizer-pass-gate.semantic-firewall.test.js +342 -0
- package/bin/__tests__/installer-safety.test.js +39 -0
- package/bin/__tests__/opencode-spec-gate.test.js +24 -16
- package/bin/__tests__/package-inventory.test.js +705 -13
- package/bin/__tests__/release-preflight.semantic-firewall.test.js +578 -0
- package/bin/__tests__/review-receipt-c2.semantic-firewall.test.js +378 -0
- package/bin/__tests__/specs-v2-execution-closeout.test.js +468 -0
- package/bin/__tests__/specs-v2-policy-and-scaffold.test.js +665 -0
- package/bin/__tests__/specs-v2-validator-grounder-contract.test.js +1132 -0
- package/bin/__tests__/test-runtime-dependency-closure.cjs +182 -0
- package/bin/__tests__/validator-grounding.test.js +2013 -221
- package/bin/lib/managed-writer.js +12 -3
- package/bin/phases/codex-runtime.js +17 -1
- package/package.json +5 -2
- package/src/claude/CLAUDE.md +6 -0
- package/src/claude/agents/code-auditor.md +20 -0
- package/src/claude/agents/spec-maker.md +143 -99
- package/src/claude/hooks/__tests__/completion-authority.test.js +321 -58
- package/src/claude/hooks/__tests__/privacy-block.test.js +254 -0
- package/src/claude/hooks/__tests__/semantic-review-authority.test.js +257 -0
- package/src/claude/hooks/__tests__/spec-gate.test.js +115 -40
- package/src/claude/hooks/completion-authority-check.cjs +37 -288
- package/src/claude/hooks/completion-authority-state.cjs +10 -8
- package/src/claude/hooks/completion-authority.cjs +13 -7
- package/src/claude/hooks/docs-sync.cjs +5 -2
- package/src/claude/hooks/lib/privacy-command-analysis.cjs +393 -0
- package/src/claude/hooks/lib/runtime-path-safety.cjs +119 -0
- package/src/claude/hooks/privacy-block.cjs +99 -28
- package/src/claude/hooks/semantic-review-authority.cjs +152 -0
- package/src/claude/hooks/spec-gate.cjs +47 -117
- package/src/claude/hooks/spec-state.cjs +8 -2
- package/src/claude/migration-manifest.json +9 -1
- package/src/claude/rules/state-sync.md +52 -21
- package/src/claude/rules/workflow.md +17 -9
- package/src/claude/scripts/change-firewall.cjs +1748 -0
- package/src/claude/scripts/spec-authoring-digest.cjs +151 -0
- package/src/claude/scripts/spec-authoring-validation.cjs +126 -0
- package/src/claude/scripts/spec-final-state.cjs +290 -0
- package/src/claude/scripts/spec-ground.cjs +571 -173
- package/src/claude/scripts/spec-readiness.cjs +425 -0
- package/src/claude/scripts/spec-receipt.cjs +162 -0
- package/src/claude/scripts/spec-resolver.cjs +67 -16
- package/src/claude/scripts/spec-scaffold.cjs +1594 -139
- package/src/claude/scripts/spec-semantic-model.cjs +396 -0
- package/src/claude/scripts/validate-spec-output.cjs +3110 -218
- package/src/claude/scripts/workflow-policy.cjs +501 -183
- package/src/claude/settings/settings.json +4 -0
- package/src/claude/skills/code-review/SKILL.md +12 -3
- package/src/claude/skills/code-review/references/spec-compliance-review.md +10 -2
- package/src/claude/skills/code-review/references/verification-gate.md +13 -0
- package/src/claude/skills/develop/SKILL.md +47 -60
- package/src/claude/skills/develop/references/parallel-waves.md +9 -6
- package/src/claude/skills/develop/references/quality-gate.md +19 -12
- package/src/claude/skills/specs/SKILL.md +183 -177
- package/src/claude/skills/specs/references/ask-user-question-gates.md +27 -18
- package/src/claude/skills/specs/references/cross-spec-dependency.md +8 -4
- package/src/claude/skills/specs/references/research-strategy.md +4 -1
- package/src/claude/skills/specs/references/review.md +214 -262
- package/src/claude/skills/specs/references/scope-inquiry.md +18 -5
- package/src/claude/skills/specs/rules/design-discovery-full.md +33 -81
- package/src/claude/skills/specs/rules/design-discovery-light.md +21 -42
- package/src/claude/skills/specs/rules/design-principles.md +136 -180
- package/src/claude/skills/specs/rules/design-review.md +42 -97
- package/src/claude/skills/specs/rules/ears-format.md +42 -50
- package/src/claude/skills/specs/rules/phase-decision-matrix.md +42 -41
- package/src/claude/skills/specs/rules/task-scoring-rubric.md +2 -1
- package/src/claude/skills/specs/rules/tasks-generation.md +189 -300
- package/src/claude/skills/specs/templates/design.md +49 -263
- package/src/claude/skills/specs/templates/requirements.md +26 -36
- package/src/claude/skills/specs/templates/research.md +9 -98
- package/src/claude/skills/specs/templates/spec-state.json +35 -85
- package/src/claude/skills/specs/templates/task.md +30 -102
- package/src/claude/skills/sync/SKILL.md +33 -10
- package/src/claude/skills/sync/references/sync-protocols.md +31 -13
- package/src/claude/skills/test/SKILL.md +17 -7
- package/src/codex/AGENTS.md +6 -0
- package/src/codex/hooks/completion-authority-check.cjs +43 -240
- package/src/codex/hooks/completion-authority-state.cjs +10 -8
- package/src/codex/hooks/completion-authority.cjs +13 -7
- package/src/codex/hooks/lib/hook-context.cjs +16 -2
- package/src/codex/hooks/lib/privacy-command-analysis.cjs +3 -0
- package/src/codex/hooks/lib/privacy-state.cjs +61 -38
- package/src/codex/hooks/lib/runtime-path-safety.cjs +3 -0
- package/src/codex/hooks/lib/spec-receipt.cjs +72 -134
- package/src/codex/hooks/lib/spec-utils.cjs +56 -5
- package/src/codex/hooks/privacy-approval.cjs +6 -2
- package/src/codex/hooks/privacy-block.cjs +94 -15
- package/src/codex/hooks/semantic-review-authority.cjs +130 -0
- package/src/codex/hooks/spec-gate.cjs +49 -34
- package/src/codex/hooks/spec-state.cjs +10 -3
- package/src/codex/hooks/state.cjs +2 -0
- package/src/codex/hooks.json +6 -1
- package/src/codex/rules/state-sync.md +47 -27
- package/src/common/AGENTS.md +1 -1
|
@@ -9,8 +9,13 @@ const {
|
|
|
9
9
|
logCrash,
|
|
10
10
|
readPayload
|
|
11
11
|
} = require('./lib/hook-context.cjs');
|
|
12
|
-
const {
|
|
12
|
+
const {
|
|
13
|
+
checkFeatureReceipt,
|
|
14
|
+
checkReceiptDetails,
|
|
15
|
+
loadSharedPolicy,
|
|
16
|
+
} = require('./lib/spec-receipt.cjs');
|
|
13
17
|
const { taskStatusMap } = require('./lib/spec-utils.cjs');
|
|
18
|
+
const FINAL_STATE = require('./completion-authority-check.cjs');
|
|
14
19
|
|
|
15
20
|
function emitBlock(reason) {
|
|
16
21
|
process.stdout.write(`${JSON.stringify({ decision: 'block', reason })}\n`);
|
|
@@ -26,22 +31,6 @@ function sessionIdentity(payload) {
|
|
|
26
31
|
return candidates.find((value) => typeof value === 'string' && value.trim() !== '') || null;
|
|
27
32
|
}
|
|
28
33
|
|
|
29
|
-
function readReceiptBody(featureDir, taskPath) {
|
|
30
|
-
const featureRoot = path.resolve(featureDir);
|
|
31
|
-
const target = path.resolve(featureRoot, taskPath);
|
|
32
|
-
const relative = path.relative(featureRoot, target);
|
|
33
|
-
if (relative === '..' || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative)) return null;
|
|
34
|
-
try {
|
|
35
|
-
const canonicalFeature = fs.realpathSync(featureRoot);
|
|
36
|
-
const canonicalTarget = fs.realpathSync(target);
|
|
37
|
-
const canonicalRelative = path.relative(canonicalFeature, canonicalTarget);
|
|
38
|
-
if (canonicalRelative === '..' || canonicalRelative.startsWith(`..${path.sep}`) || path.isAbsolute(canonicalRelative)) return null;
|
|
39
|
-
return evidenceBody(fs.readFileSync(canonicalTarget, 'utf8'));
|
|
40
|
-
} catch (_) {
|
|
41
|
-
return null;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
34
|
try {
|
|
46
35
|
const payload = readPayload();
|
|
47
36
|
if (payload.stop_hook_active === true) process.exit(0);
|
|
@@ -56,12 +45,15 @@ try {
|
|
|
56
45
|
if (typeof POLICY.completionDecisionForSpec !== 'function') {
|
|
57
46
|
throw new Error('shared workflow policy lacks completion authority functions');
|
|
58
47
|
}
|
|
59
|
-
const
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
48
|
+
const resolver = require('./lib/spec-utils.cjs');
|
|
49
|
+
const resolved = FINAL_STATE.resolveCandidate({
|
|
50
|
+
resolver,
|
|
51
|
+
projectRoot,
|
|
52
|
+
runtime,
|
|
53
|
+
payload,
|
|
54
|
+
});
|
|
63
55
|
if (!resolved) process.exit(0);
|
|
64
|
-
if (resolved.error === 'multiple_active') {
|
|
56
|
+
if (resolved.error === 'multiple_active' || resolved.error === 'multiple_persisted') {
|
|
65
57
|
process.stdout.write(`${JSON.stringify({
|
|
66
58
|
decision: 'block',
|
|
67
59
|
reason: `Completion gate: multiple active specs detected (${resolved.candidates.join(', ')}). Provide explicit feature target or resolve ambiguity before completing tasks.`
|
|
@@ -84,6 +76,22 @@ try {
|
|
|
84
76
|
}
|
|
85
77
|
if (resolved.error) process.exit(0);
|
|
86
78
|
const active = resolved;
|
|
79
|
+
const lifecyclePhase = active.spec.current_phase || active.spec.phase;
|
|
80
|
+
const explicitCloseout = ['done', 'completed', 'complete'].includes(active.spec.status)
|
|
81
|
+
|| ['closeout', 'completion', 'completed', 'complete'].includes(lifecyclePhase);
|
|
82
|
+
if (active.spec.schema_version === '2.1') {
|
|
83
|
+
const finalState = FINAL_STATE.evaluateCloseout({
|
|
84
|
+
policy: POLICY,
|
|
85
|
+
projectRoot,
|
|
86
|
+
runtime,
|
|
87
|
+
payload: { ...payload, session_id: sessionIdentity(payload) },
|
|
88
|
+
});
|
|
89
|
+
if (!finalState.ok) {
|
|
90
|
+
emitBlock(`Completion gate: ${finalState.reason}`);
|
|
91
|
+
process.exit(0);
|
|
92
|
+
}
|
|
93
|
+
if (finalState.active) process.exit(0);
|
|
94
|
+
}
|
|
87
95
|
const runtimeContext = POLICY.deriveRuntimeContext({
|
|
88
96
|
projectRoot,
|
|
89
97
|
specsRoot: active.specsDir,
|
|
@@ -146,21 +154,28 @@ try {
|
|
|
146
154
|
const receiptBodies = new Map();
|
|
147
155
|
const failures = allDoneTasks
|
|
148
156
|
.map((taskPath) => {
|
|
149
|
-
const
|
|
150
|
-
if (body
|
|
157
|
+
const proof = checkReceiptDetails(featureDir, taskPath, registry[taskPath], runtimeContext);
|
|
158
|
+
if (proof.body) receiptBodies.set(taskPath, proof.body);
|
|
151
159
|
return {
|
|
152
160
|
taskPath,
|
|
153
|
-
failures:
|
|
161
|
+
failures: proof.failures
|
|
154
162
|
};
|
|
155
163
|
})
|
|
156
164
|
.filter((result) => result.failures.length);
|
|
157
165
|
|
|
158
|
-
const
|
|
159
|
-
const
|
|
166
|
+
const featureCloseoutRequired = explicitCloseout && allDoneTasks.length > 0;
|
|
167
|
+
const featureReceipt = featureCloseoutRequired
|
|
168
|
+
? checkFeatureReceipt(featureDir, runtimeContext)
|
|
169
|
+
: null;
|
|
170
|
+
if (featureReceipt && featureReceipt.failures.length) {
|
|
171
|
+
failures.push({ taskPath: 'feature-receipt.md', failures: featureReceipt.failures });
|
|
172
|
+
}
|
|
173
|
+
const completion = featureCloseoutRequired && featureReceipt?.failures.length === 0
|
|
174
|
+
&& Object.prototype.hasOwnProperty.call(active.spec, 'workflow_policy')
|
|
160
175
|
? POLICY.completionDecisionForSpec(active.spec, {
|
|
161
176
|
runtimeContext,
|
|
162
|
-
executionReceipt:
|
|
163
|
-
taskContext:
|
|
177
|
+
executionReceipt: featureReceipt.body,
|
|
178
|
+
taskContext: {},
|
|
164
179
|
})
|
|
165
180
|
: null;
|
|
166
181
|
|
|
@@ -178,14 +193,14 @@ try {
|
|
|
178
193
|
if (!failures.length && !completionBlocked) process.exit(0);
|
|
179
194
|
const lines = [
|
|
180
195
|
failures.length > 0
|
|
181
|
-
? `Completion gate: ${failures.length}
|
|
196
|
+
? `Completion gate: ${failures.length} done task(s) lack a verification receipt.`
|
|
182
197
|
: 'Completion gate: workflow completion proof is incomplete.'
|
|
183
198
|
];
|
|
184
199
|
for (const result of failures) {
|
|
185
|
-
lines.push(
|
|
186
|
-
|
|
187
|
-
`
|
|
188
|
-
|
|
200
|
+
lines.push(`- \`${result.taskPath}\`: failed check(s) ${result.failures.join(', ')}`);
|
|
201
|
+
lines.push(result.taskPath === 'feature-receipt.md'
|
|
202
|
+
? ` Run final integration proof, then write \`specs/${active.featureName}/feature-receipt.md\`.`
|
|
203
|
+
: ` Write canonical proof to \`specs/${active.featureName}/receipts/${path.posix.basename(result.taskPath)}\`; legacy \`## Evidence\` remains read-compatible.`);
|
|
189
204
|
}
|
|
190
205
|
if (completionBlocked) {
|
|
191
206
|
lines.push(`- Completion decision unfinished: ${completion.blocker || 'required workflow proof is missing.'}`);
|
|
@@ -10,7 +10,7 @@ const {
|
|
|
10
10
|
logCrash,
|
|
11
11
|
readPayload
|
|
12
12
|
} = require('./lib/hook-context.cjs');
|
|
13
|
-
const { loadSharedPolicy } = require('./lib/spec-receipt.cjs');
|
|
13
|
+
const { loadSharedPolicy, loadSharedReceipt } = require('./lib/spec-receipt.cjs');
|
|
14
14
|
|
|
15
15
|
function emitControlledFailure(reason) {
|
|
16
16
|
process.stdout.write(`> ⚠️ Spec tollgate unavailable: ${reason}. Repair the installed workflow policy before continuing.\n`);
|
|
@@ -34,6 +34,9 @@ try {
|
|
|
34
34
|
process.exit(0);
|
|
35
35
|
}
|
|
36
36
|
const POLICY = loaded.policy;
|
|
37
|
+
const receiptLoaded = loadSharedReceipt();
|
|
38
|
+
if (!receiptLoaded.receipt) throw receiptLoaded.error;
|
|
39
|
+
const RECEIPT = receiptLoaded.receipt;
|
|
37
40
|
const { projectRoot, runtime } = getHookContext(payload);
|
|
38
41
|
if (runtime.spec?.tollgate === false) process.exit(0);
|
|
39
42
|
const { resolveActiveSpec } = require('./lib/spec-utils.cjs');
|
|
@@ -81,6 +84,8 @@ try {
|
|
|
81
84
|
(task?.status || 'pending') === 'pending'
|
|
82
85
|
&& (task?.dependencies || []).every((dependency) => statuses.get(dependency) === 'done')
|
|
83
86
|
));
|
|
87
|
+
const featureDir = path.join(active.specsDir, active.featureName);
|
|
88
|
+
const featureReceiptPresent = RECEIPT.safeRead(featureDir, 'feature-receipt.md').status === 'ok';
|
|
84
89
|
const stateKey = JSON.stringify({
|
|
85
90
|
project_root: runtimeContext.project_root,
|
|
86
91
|
specs_root: runtimeContext.specs_root,
|
|
@@ -94,6 +99,7 @@ try {
|
|
|
94
99
|
phase,
|
|
95
100
|
done: counts.done || 0,
|
|
96
101
|
total: tasks.length,
|
|
102
|
+
feature_receipt_present: featureReceiptPresent,
|
|
97
103
|
});
|
|
98
104
|
const cache = cacheFile(projectRoot, runtimeContext.runtime_session);
|
|
99
105
|
let previous = '';
|
|
@@ -117,9 +123,10 @@ try {
|
|
|
117
123
|
lines.push(`- Flash verification pending: ${flashTasks.map((taskPath) => `\`${taskPath}\``).join(', ')}. A PASS proof keeps the persisted task in_progress until explicit sync-finalize.`);
|
|
118
124
|
}
|
|
119
125
|
lines.push(
|
|
120
|
-
'- Sync `spec.json` and
|
|
126
|
+
'- Sync `spec.json` and task Markdown status only after verified work; task proof belongs in `receipts/<task-basename>.md`.',
|
|
127
|
+
`- Create \`feature-receipt.md\` once after final integration proof${featureReceiptPresent ? ' (present)' : ' (not required before closeout)'}.`,
|
|
121
128
|
`- Validate with \`node .codex/scripts/validate-spec-output.cjs specs/${active.featureName}\`.`,
|
|
122
|
-
'-
|
|
129
|
+
'- Hooks revalidate receipt bytes but never grant approval.'
|
|
123
130
|
);
|
|
124
131
|
process.stdout.write(`${lines.join('\n')}\n`);
|
|
125
132
|
} catch (error) {
|
|
@@ -140,6 +140,7 @@ try {
|
|
|
140
140
|
refreshGit(data, projectRoot);
|
|
141
141
|
writeData(dir, data);
|
|
142
142
|
});
|
|
143
|
+
process.stdout.write('{}\n');
|
|
143
144
|
process.exit(0);
|
|
144
145
|
}
|
|
145
146
|
|
|
@@ -151,6 +152,7 @@ try {
|
|
|
151
152
|
writeData(dir, data);
|
|
152
153
|
archive(dir);
|
|
153
154
|
});
|
|
155
|
+
process.stdout.write('{}\n');
|
|
154
156
|
}
|
|
155
157
|
} catch (error) {
|
|
156
158
|
logCrash('state', error);
|
package/src/codex/hooks.json
CHANGED
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
],
|
|
64
64
|
"PreToolUse": [
|
|
65
65
|
{
|
|
66
|
-
"matcher": "Bash|apply_patch|Edit|Write|Read|Glob|Grep|mcp__
|
|
66
|
+
"matcher": "Bash|exec_command|apply_patch|Edit|Write|Read|Glob|Grep|mcp__.*|shell",
|
|
67
67
|
"hooks": [
|
|
68
68
|
{
|
|
69
69
|
"type": "command",
|
|
@@ -120,6 +120,11 @@
|
|
|
120
120
|
{
|
|
121
121
|
"matcher": "*",
|
|
122
122
|
"hooks": [
|
|
123
|
+
{
|
|
124
|
+
"type": "command",
|
|
125
|
+
"command": "node \"$(git rev-parse --show-toplevel)/.codex/hooks/semantic-review-authority.cjs\"",
|
|
126
|
+
"commandWindows": "node \".codex/hooks/semantic-review-authority.cjs\""
|
|
127
|
+
},
|
|
123
128
|
{
|
|
124
129
|
"type": "command",
|
|
125
130
|
"command": "node \"$(git rev-parse --show-toplevel)/.codex/hooks/state.cjs\"",
|
|
@@ -1,41 +1,61 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Specs v2.1 state synchronization
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## Authority layers
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
`spec.json` is machine semantic authority. Requirements, design, conditional
|
|
6
|
+
research, and conditional task Markdown are human projections. Host state may
|
|
7
|
+
record authority or integrity, but it never supplies product semantics.
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
+
Planning depth and assurance level remain independent. Route artifacts before
|
|
10
|
+
discovery: None persists no spec; Compact and Full persist the bounded core;
|
|
11
|
+
research and tasks remain absent unless their semantic triggers exist.
|
|
9
12
|
|
|
10
|
-
##
|
|
13
|
+
## Canonical lifecycle
|
|
11
14
|
|
|
12
|
-
|
|
15
|
+
The feature lifecycle is exactly `in_progress`, `paused`, `blocked`, or `done`.
|
|
16
|
+
Authoring state is independently `draft`, `validated`, or `absent`. New 2.1
|
|
17
|
+
artifacts never emit legacy lifecycle aliases.
|
|
13
18
|
|
|
14
|
-
|
|
19
|
+
Technical readiness is not lifecycle completion. `ready_for_implementation`
|
|
20
|
+
may change only through the installed machine finalization path after every
|
|
21
|
+
routed artifact, projection, semantic review, grounding check, and deterministic
|
|
22
|
+
gate passes. The author cannot directly declare readiness, authority, approval,
|
|
23
|
+
review capability, execution proof, or closeout.
|
|
15
24
|
|
|
16
|
-
|
|
17
|
-
`task_files`, status, timestamps, and the matching `task_registry` entry accurate.
|
|
18
|
-
2. Update the matching task Markdown status, checkboxes, completion criteria,
|
|
19
|
-
and `## Evidence` receipt from the current verification run.
|
|
20
|
-
3. Update native plan or task state when the active Codex session provides it,
|
|
21
|
-
but never use chat-only state as a substitute for the files above.
|
|
25
|
+
## Projection sync
|
|
22
26
|
|
|
23
|
-
|
|
27
|
+
After a semantic Markdown edit:
|
|
24
28
|
|
|
25
|
-
1.
|
|
26
|
-
2.
|
|
27
|
-
3.
|
|
29
|
+
1. invoke the explicit installed machine semantic-sync step to promote `semantic_model`;
|
|
30
|
+
2. regenerate or reconcile every affected Markdown projection;
|
|
31
|
+
3. verify requirements, decisions, anchors, task registry, typed boundaries,
|
|
32
|
+
and verification refs round-trip without loss; and
|
|
33
|
+
4. rerun applicable deterministic validation and grounding checks.
|
|
28
34
|
|
|
29
|
-
|
|
30
|
-
|
|
35
|
+
For Codex, the isolated promotion is
|
|
36
|
+
`node .codex/scripts/spec-scaffold.cjs <feature> --sync-semantic-model`.
|
|
31
37
|
|
|
32
|
-
|
|
38
|
+
Task Markdown exists only for typed ownership, dependency, transition, proof,
|
|
39
|
+
or parallel topology. Its status and dependencies project the matching
|
|
40
|
+
`task_registry` entry. Its Verification Plan is prospective, never execution
|
|
41
|
+
proof. Typed `coordination.boundaries` alone define topology; legacy trigger
|
|
42
|
+
fields, priority markers, related-file lists, and prose do not.
|
|
33
43
|
|
|
34
|
-
|
|
44
|
+
## Lifecycle updates
|
|
35
45
|
|
|
36
|
-
- `
|
|
37
|
-
-
|
|
38
|
-
- a
|
|
46
|
+
- Active work uses `in_progress`.
|
|
47
|
+
- A deliberate resumable stop uses `paused` with the exact remaining decision.
|
|
48
|
+
- An external or semantic blocker uses `blocked` with a concrete cause.
|
|
49
|
+
- Task state changes update the registry and matching projection together only
|
|
50
|
+
from observed work and verification.
|
|
51
|
+
- Feature `done` is reserved for final-state authority after implementation
|
|
52
|
+
closeout; authoring or readiness cannot produce it.
|
|
39
53
|
|
|
40
|
-
|
|
41
|
-
|
|
54
|
+
State synchronization never fabricates commands, PASS results, timestamps,
|
|
55
|
+
receipts, completed work, reviewer identity, or user approval. When execution
|
|
56
|
+
evidence is absent, preserve unfinished state and report the missing proof.
|
|
57
|
+
Never hand-author the `semantic_model` shape or treat an unsynchronized Markdown
|
|
58
|
+
edit as machine authority.
|
|
59
|
+
|
|
60
|
+
Codex-native plan or task state may mirror physical state when available, but
|
|
61
|
+
it is never a substitute for `spec.json` or authority to advance lifecycle.
|
package/src/common/AGENTS.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
## Shared CafeKit instructions
|
|
4
4
|
|
|
5
5
|
- Deliver exactly what was asked. Do not expand, polish, or add optional work beyond the request. Match existing code style and structure.
|
|
6
|
-
- For
|
|
6
|
+
- For Specs v2.1, treat `spec.json` as machine authority and Markdown as human projections. Keep task status and plan synchronized with `task_registry`; derive ownership, dependencies, transitions, proof, and parallelism only from typed `coordination.boundaries`. Never invent proof, readiness, approval, or audit state.
|
|
7
7
|
- `NO_TESTS` and `0 tests + exit 0` do not pass when the task requires automated tests.
|
|
8
8
|
- When a hook blocks an action, that is an instruction boundary — do not work around it.
|
|
9
9
|
- Use conventional commits. Do not add AI attribution unless requested.
|