@haposoft/cafekit 0.16.7 → 0.18.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 +14 -22
- package/bin/__tests__/codex-hooks-ownership.test.js +2 -2
- package/bin/__tests__/codex-hooks.test.js +0 -36
- package/bin/__tests__/codex-native.test.js +46 -88
- package/bin/__tests__/develop-contract.test.js +26 -57
- package/bin/__tests__/docs-sync-on-demand.test.js +93 -0
- package/bin/__tests__/grok-envelope.test.js +0 -56
- package/bin/__tests__/hook-payload.test.js +4 -6
- package/bin/__tests__/legacy-authority-decoupled.test.js +159 -0
- package/bin/__tests__/legacy-hooks-retired.test.js +221 -0
- package/bin/__tests__/omp-bridge.test.js +20 -17
- package/bin/__tests__/omp-hooks.test.js +0 -19
- package/bin/__tests__/optional-skill-inventory.test.js +112 -4
- package/bin/__tests__/orca-session.test.js +0 -2
- package/bin/__tests__/package-inventory.test.js +100 -541
- package/bin/__tests__/runtime-dir.test.js +0 -3
- package/bin/__tests__/runtime-schema.test.js +3 -2
- package/bin/__tests__/skill-routing-source.test.js +27 -15
- package/bin/__tests__/spec-narrowing.test.js +0 -27
- package/bin/__tests__/specs-v2-execution-closeout.test.js +4 -69
- package/bin/__tests__/ui-ux-skill.test.js +101 -0
- package/bin/__tests__/usage-hook-retired.test.js +114 -0
- package/bin/__tests__/validator-grounding.test.js +9 -28
- package/bin/phases/codex-runtime.js +24 -0
- package/bin/phases/omp-runtime.js +22 -0
- package/package.json +1 -1
- package/src/claude/CLAUDE.md +3 -10
- package/src/claude/agents/brainstormer.md +7 -3
- package/src/claude/agents/code-auditor.md +35 -50
- package/src/claude/agents/debugger.md +5 -79
- package/src/claude/agents/deployer.md +3 -5
- package/src/claude/agents/docs-keeper.md +2 -7
- package/src/claude/agents/implementer.md +6 -9
- package/src/claude/agents/inspector.md +2 -3
- package/src/claude/agents/project-manager.md +7 -15
- package/src/claude/agents/researcher.md +9 -3
- package/src/claude/agents/spec-maker.md +11 -11
- package/src/claude/hooks/__tests__/fixtures/statusline-default.golden +1 -1
- package/src/claude/hooks/__tests__/spec-gate.test.js +74 -3
- package/src/claude/hooks/__tests__/spec-state-touched.test.js +134 -0
- package/src/claude/hooks/__tests__/state.test.js +68 -0
- package/src/claude/hooks/__tests__/statusline.test.js +140 -11
- package/src/claude/hooks/agent.cjs +2 -1
- package/src/claude/hooks/lib/context.cjs +0 -89
- package/src/claude/hooks/lib/hook-payload.cjs +2 -2
- package/src/claude/hooks/rules.cjs +2 -1
- package/src/claude/hooks/session.cjs +0 -1
- package/src/claude/hooks/spec-gate.cjs +17 -28
- package/src/claude/hooks/spec-state.cjs +95 -1
- package/src/claude/hooks/state.cjs +21 -2
- package/src/claude/migration-manifest.json +30 -15
- package/src/claude/rules/ai-dev-rules.md +1 -1
- package/src/claude/rules/hook-protocols.md +8 -15
- package/src/claude/rules/manage-docs.md +9 -23
- package/src/claude/rules/orchestrator.md +3 -4
- package/src/claude/rules/review-audit-self-decision.md +3 -3
- package/src/claude/rules/skill-domain-routing.md +1 -3
- package/src/claude/rules/skill-workflow-routing.md +4 -5
- package/src/claude/rules/state-sync.md +3 -12
- package/src/claude/rules/workflow.md +10 -18
- package/src/claude/runtime.schema.json +5 -3
- package/src/claude/scripts/generate-skill-catalog.cjs +7 -6
- package/src/claude/scripts/provenance.cjs +23 -5
- package/src/claude/scripts/spec-receipt.cjs +24 -7
- package/src/claude/scripts/spec-resolver.cjs +1 -2
- package/src/claude/scripts/validate-spec-output.cjs +5 -32
- package/src/claude/settings/settings.json +1 -32
- package/src/claude/skills/{question → ask}/SKILL.md +9 -75
- package/src/claude/skills/brainstorm/SKILL.md +43 -131
- package/src/claude/skills/code-review/SKILL.md +48 -17
- package/src/claude/skills/code-review/references/spec-compliance-review.md +2 -3
- package/src/claude/skills/code-review/references/verification-gate.md +22 -27
- package/src/claude/skills/debug/SKILL.md +29 -149
- package/src/claude/skills/develop/SKILL.md +27 -36
- package/src/claude/skills/develop/references/parallel-waves.md +0 -8
- package/src/claude/skills/develop/references/quality-gate.md +15 -13
- package/src/claude/skills/docs/SKILL.md +2 -2
- package/src/claude/skills/docs/references/update-workflow.md +1 -1
- package/src/claude/skills/fix/SKILL.md +153 -0
- package/src/claude/skills/{hotfix → fix}/references/diagnosis-protocol.md +2 -2
- package/src/claude/skills/{hotfix → fix}/references/parallel-patterns.md +2 -2
- package/src/claude/skills/{hotfix → fix}/references/prevention-gate.md +3 -3
- package/src/claude/skills/{hotfix → fix}/references/review-cycle.md +1 -1
- package/src/claude/skills/git/SKILL.md +48 -9
- package/src/claude/skills/git/references/commit-protocols.md +35 -16
- package/src/claude/skills/git/references/worktree-blueprint.md +42 -6
- package/src/claude/skills/orca/SKILL.md +9 -8
- package/src/claude/skills/research/SKILL.md +2 -0
- package/src/claude/skills/scout/SKILL.md +61 -0
- package/src/claude/skills/{inspect → scout}/references/internal-inspection.md +26 -10
- package/src/claude/skills/specs/SKILL.md +22 -29
- package/src/claude/skills/specs/references/review.md +8 -6
- package/src/claude/skills/specs/references/templates.md +34 -41
- package/src/claude/skills/sync/SKILL.md +8 -15
- package/src/claude/skills/sync/references/rebind-and-audit.md +59 -0
- package/src/claude/skills/sync/references/sync-protocols.md +4 -13
- package/src/claude/skills/test/SKILL.md +22 -3
- package/src/claude/skills/test/references/execution-strategy.md +83 -0
- package/src/claude/skills/test/references/failure-triage.md +1 -1
- package/src/claude/skills/ui-ux/LICENSE +21 -0
- package/src/claude/skills/ui-ux/SKILL.md +497 -0
- package/src/claude/skills/ui-ux/references/brand-tokens.md +90 -0
- package/src/claude/skills/ui-ux/references/budgets.md +113 -0
- package/src/claude/skills/ui-ux/references/checklist.md +271 -0
- package/src/claude/skills/ui-ux/references/components/accordion.md +246 -0
- package/src/claude/skills/ui-ux/references/components/avatar.md +153 -0
- package/src/claude/skills/ui-ux/references/components/banner.md +43 -0
- package/src/claude/skills/ui-ux/references/components/breadcrumb.md +201 -0
- package/src/claude/skills/ui-ux/references/components/button.md +142 -0
- package/src/claude/skills/ui-ux/references/components/card.md +113 -0
- package/src/claude/skills/ui-ux/references/components/charts.md +376 -0
- package/src/claude/skills/ui-ux/references/components/chat.md +132 -0
- package/src/claude/skills/ui-ux/references/components/choice-controls.md +369 -0
- package/src/claude/skills/ui-ux/references/components/comment-thread.md +17 -0
- package/src/claude/skills/ui-ux/references/components/description-list.md +116 -0
- package/src/claude/skills/ui-ux/references/components/empty-state.md +98 -0
- package/src/claude/skills/ui-ux/references/components/file-upload.md +107 -0
- package/src/claude/skills/ui-ux/references/components/inline-edit.md +128 -0
- package/src/claude/skills/ui-ux/references/components/input.md +161 -0
- package/src/claude/skills/ui-ux/references/components/list-row.md +56 -0
- package/src/claude/skills/ui-ux/references/components/loading.md +198 -0
- package/src/claude/skills/ui-ux/references/components/logo.md +147 -0
- package/src/claude/skills/ui-ux/references/components/otp-input.md +43 -0
- package/src/claude/skills/ui-ux/references/components/quantity-input.md +100 -0
- package/src/claude/skills/ui-ux/references/components/range-slider.md +16 -0
- package/src/claude/skills/ui-ux/references/components/small-controls.md +340 -0
- package/src/claude/skills/ui-ux/references/components/sortable-header.md +86 -0
- package/src/claude/skills/ui-ux/references/components/tag-input.md +14 -0
- package/src/claude/skills/ui-ux/references/components/timeline.md +38 -0
- package/src/claude/skills/ui-ux/references/components/tree.md +30 -0
- package/src/claude/skills/ui-ux/references/design-process.md +650 -0
- package/src/claude/skills/ui-ux/references/layouts/app-kanban.html +303 -0
- package/src/claude/skills/ui-ux/references/layouts/app.md +1369 -0
- package/src/claude/skills/ui-ux/references/layouts/form.md +430 -0
- package/src/claude/skills/ui-ux/references/layouts/overlay.md +552 -0
- package/src/claude/skills/ui-ux/references/layouts/pricing.md +204 -0
- package/src/claude/skills/ui-ux/references/locked-rules.md +35 -0
- package/src/claude/skills/ui-ux/references/principles.md +408 -0
- package/src/claude/skills/ui-ux/references/refactor.md +245 -0
- package/src/claude/skills/ui-ux/references/responsive.md +195 -0
- package/src/claude/skills/ui-ux/references/review.md +528 -0
- package/src/claude/skills/ui-ux/references/rules-color.md +623 -0
- package/src/claude/skills/ui-ux/references/rules-form.md +235 -0
- package/src/claude/skills/ui-ux/references/rules-state.md +680 -0
- package/src/claude/skills/ui-ux/references/rules-type.md +369 -0
- package/src/claude/skills/ui-ux/references/styles.md +311 -0
- package/src/claude/skills/ui-ux/references/system.md +219 -0
- package/src/claude/skills/ui-ux/references/tailwind-v4-traps.md +237 -0
- package/src/claude/skills/ui-ux/references/tokens.css +362 -0
- package/src/claude/skills/ui-ux/scripts/lint-skill.mjs +216 -0
- package/src/claude/skills/ui-ux/scripts/package.json +9 -0
- package/src/claude/skills/ui-ux/scripts/probe.mjs +4447 -0
- package/src/claude/skills/ui-ux-pro-max/SKILL.md +1 -1
- package/src/claude/status.cjs +149 -144
- package/src/codex/AGENTS.md +8 -13
- package/src/codex/hooks/agent.cjs +2 -1
- package/src/codex/hooks/lib/spec-receipt.cjs +2 -2
- package/src/codex/hooks/lib/spec-utils.cjs +0 -7
- package/src/codex/hooks/rules.cjs +2 -1
- package/src/codex/hooks/session.cjs +0 -2
- package/src/codex/hooks/spec-gate.cjs +7 -18
- package/src/codex/hooks.json +0 -20
- package/src/codex/rules/state-sync.md +3 -12
- package/src/common/AGENTS.md +2 -2
- package/src/omp/extensions/cafekit-bridge.mjs +6 -6
- package/src/claude/hooks/__tests__/completion-authority.test.js +0 -990
- package/src/claude/hooks/__tests__/semantic-review-authority.test.js +0 -259
- package/src/claude/hooks/completion-authority-check.cjs +0 -56
- package/src/claude/hooks/completion-authority-state.cjs +0 -527
- package/src/claude/hooks/completion-authority.cjs +0 -163
- package/src/claude/hooks/semantic-review-authority.cjs +0 -154
- package/src/claude/hooks/task-scaffold-guard.cjs +0 -114
- package/src/claude/hooks/usage.cjs +0 -197
- package/src/claude/skills/delegate/SKILL.md +0 -124
- package/src/claude/skills/delegate/references/codex-delegation.md +0 -71
- package/src/claude/skills/delegate/references/grok-delegation.md +0 -84
- package/src/claude/skills/hotfix/SKILL.md +0 -289
- package/src/claude/skills/inspect/SKILL.md +0 -142
- package/src/claude/skills/loop/SKILL.md +0 -114
- package/src/claude/skills/loop/references/bounded-loop-protocol.md +0 -104
- package/src/claude/skills/loop/references/metric-and-guard-contract.md +0 -76
- package/src/claude/skills/route/SKILL.md +0 -94
- package/src/claude/skills/route/references/agent-timing.md +0 -46
- package/src/claude/skills/route/references/chaining-patterns.md +0 -53
- package/src/claude/skills/route/references/task-taxonomy.md +0 -48
- package/src/codex/hooks/completion-authority-check.cjs +0 -67
- package/src/codex/hooks/completion-authority-state.cjs +0 -527
- package/src/codex/hooks/completion-authority.cjs +0 -109
- package/src/codex/hooks/semantic-review-authority.cjs +0 -130
- package/src/codex/hooks/task-scaffold-guard.cjs +0 -63
- /package/src/claude/skills/{question → ask}/templates/question.md +0 -0
- /package/src/claude/skills/{hotfix → fix}/references/escalation-tactics.md +0 -0
- /package/src/claude/skills/{hotfix → fix}/references/workflow-specialized.md +0 -0
|
@@ -70,6 +70,7 @@ try {
|
|
|
70
70
|
const baseDir = cwd;
|
|
71
71
|
const plansPath = path.join(baseDir, runtime.paths?.plans || 'plans');
|
|
72
72
|
const docsPath = path.join(baseDir, runtime.paths?.docs || 'docs');
|
|
73
|
+
const specsPath = path.join(baseDir, runtime.paths?.specs || 'specs');
|
|
73
74
|
const maxLoc = runtime.docs?.maxLoc || 800;
|
|
74
75
|
|
|
75
76
|
const lines = [];
|
|
@@ -84,7 +85,7 @@ try {
|
|
|
84
85
|
|
|
85
86
|
lines.push(
|
|
86
87
|
'## Rules',
|
|
87
|
-
`- Markdown files: Plans → "${plansPath}/" | Docs → "${docsPath}/"`,
|
|
88
|
+
`- Markdown files: Specs → "${specsPath}/" | Plans → "${plansPath}/" | Docs → "${docsPath}/"`,
|
|
88
89
|
'- **DO NOT** create markdown files outside of those directories unless explicitly asked.',
|
|
89
90
|
`- docs.maxLoc: ${maxLoc} lines max per doc file`
|
|
90
91
|
);
|
|
@@ -202,7 +202,6 @@ try {
|
|
|
202
202
|
const envFile = process.env.CLAUDE_ENV_FILE;
|
|
203
203
|
const cwd = projectRoot();
|
|
204
204
|
const runtime = readRuntime(cwd);
|
|
205
|
-
try { require('./completion-authority-state.cjs').clearState(cwd, payload.session_id); } catch { /* old installs remain fail-open */ }
|
|
206
205
|
|
|
207
206
|
// Check CafeKit update in parallel with project detection (async, fail-open).
|
|
208
207
|
const updateCheckPromise = checkCafeKitUpdate(cwd);
|
|
@@ -90,17 +90,17 @@ try {
|
|
|
90
90
|
let POLICY;
|
|
91
91
|
let RESOLVER;
|
|
92
92
|
let RECEIPT;
|
|
93
|
-
let FINAL_STATE;
|
|
94
93
|
try {
|
|
95
94
|
POLICY = require(policyPath);
|
|
95
|
+
// One gate run checks every done receipt against the same checkout; capture it once.
|
|
96
|
+
require(path.join(__dirname, '..', 'scripts', 'provenance.cjs')).enableSnapshotMemo();
|
|
96
97
|
RESOLVER = require(path.join(__dirname, '..', 'scripts', 'spec-resolver.cjs'));
|
|
97
98
|
RECEIPT = require(path.join(__dirname, '..', 'scripts', 'spec-receipt.cjs'));
|
|
98
|
-
FINAL_STATE = require('./completion-authority-check.cjs');
|
|
99
99
|
if (typeof POLICY.validateCanonicalReceipt !== 'function'
|
|
100
100
|
|| typeof POLICY.completionDecisionForSpec !== 'function'
|
|
101
101
|
|| typeof RECEIPT.checkTaskReceipt !== 'function'
|
|
102
102
|
|| typeof RECEIPT.checkWorkflowReceiptSet !== 'function'
|
|
103
|
-
|| typeof
|
|
103
|
+
|| typeof RESOLVER.resolveWorkflowCandidate !== 'function') {
|
|
104
104
|
throw new Error('shared workflow policy lacks completion authority functions');
|
|
105
105
|
}
|
|
106
106
|
} catch (error) {
|
|
@@ -127,9 +127,7 @@ try {
|
|
|
127
127
|
|| (typeof RESOLVER.readActiveFeatureTarget === 'function'
|
|
128
128
|
? RESOLVER.readActiveFeatureTarget({ projectRoot: baseDir, runtime })
|
|
129
129
|
: null);
|
|
130
|
-
let resolved =
|
|
131
|
-
? RESOLVER.resolveWorkflowCandidate({ projectRoot: baseDir, runtime, target, includeCompleted: true })
|
|
132
|
-
: FINAL_STATE.resolveCandidate({ resolver: RESOLVER, projectRoot: baseDir, runtime, payload });
|
|
130
|
+
let resolved = RESOLVER.resolveWorkflowCandidate({ projectRoot: baseDir, runtime, target, includeCompleted: true });
|
|
133
131
|
if (typeof RESOLVER.refineWorkflowGateResolution === 'function') {
|
|
134
132
|
resolved = RESOLVER.refineWorkflowGateResolution(resolved);
|
|
135
133
|
}
|
|
@@ -150,7 +148,7 @@ try {
|
|
|
150
148
|
const lines = [`⚠️ Completion gate: ${checked.failures.length} done task(s) lack a verification receipt.`];
|
|
151
149
|
for (const failure of checked.failures) {
|
|
152
150
|
lines.push(`- \`${failure.featureName}/${failure.taskPath}\`: failed check(s) ${failure.failures.join(', ')}`);
|
|
153
|
-
const hint = typeof RECEIPT.receiptFixHint === 'function' ? RECEIPT.receiptFixHint(failure.failures) : null;
|
|
151
|
+
const hint = typeof RECEIPT.receiptFixHint === 'function' ? RECEIPT.receiptFixHint(failure.failures, failure.body) : null;
|
|
154
152
|
lines.push(` Fix in \`specs/${failure.featureName}/${failure.taskPath}\`: ${hint || 'write a runtime-bound `## Receipt` with the planned command'}.`);
|
|
155
153
|
}
|
|
156
154
|
emitBlock(lines.slice(0, 8).join('\n'));
|
|
@@ -186,19 +184,10 @@ try {
|
|
|
186
184
|
const lifecyclePhase = activeSpec.current_phase || activeSpec.phase;
|
|
187
185
|
const explicitCloseout = ['done', 'completed', 'complete'].includes(activeSpec.status)
|
|
188
186
|
|| ['closeout', 'completion', 'completed', 'complete'].includes(lifecyclePhase);
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
projectRoot: baseDir,
|
|
194
|
-
runtime,
|
|
195
|
-
payload: { ...payload, session_id: sessionIdentity(payload) },
|
|
196
|
-
});
|
|
197
|
-
if (!finalState.ok) {
|
|
198
|
-
emitBlock(`Completion gate: ${finalState.reason}`);
|
|
199
|
-
process.exit(0);
|
|
200
|
-
}
|
|
201
|
-
if (finalState.active) process.exit(0);
|
|
187
|
+
// Legacy 2.1 closeout is retired; a 2.1 packet mid-execution keeps the ordinary receipt checks.
|
|
188
|
+
if (!processWorkflow && activeSpec.schema_version === '2.1' && explicitCloseout) {
|
|
189
|
+
emitBlock('Completion gate: Legacy spec.json closeout is no longer supported; move the packet to plan.md with flat task files');
|
|
190
|
+
process.exit(0);
|
|
202
191
|
}
|
|
203
192
|
const runtimeContext = POLICY.deriveRuntimeContext({
|
|
204
193
|
projectRoot: baseDir,
|
|
@@ -251,12 +240,12 @@ try {
|
|
|
251
240
|
);
|
|
252
241
|
const featureDir = path.join(specsPath, featureName);
|
|
253
242
|
const failures = allDoneTasks
|
|
254
|
-
.map((taskPath) =>
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
})
|
|
243
|
+
.map((taskPath) => {
|
|
244
|
+
const proof = processWorkflow
|
|
245
|
+
? RECEIPT.checkWorkflowTaskReceipt(featureDir, taskPath, runtimeContext, POLICY)
|
|
246
|
+
: RECEIPT.checkTaskReceipt(featureDir, taskPath, taskRegistry[taskPath], runtimeContext, POLICY);
|
|
247
|
+
return { taskPath, fails: proof.failures, body: proof.body };
|
|
248
|
+
})
|
|
260
249
|
.filter((f) => f.fails.length > 0);
|
|
261
250
|
|
|
262
251
|
const featureCloseoutRequired = !processWorkflow && explicitCloseout && allDoneTasks.length > 0;
|
|
@@ -298,12 +287,12 @@ try {
|
|
|
298
287
|
? `⚠️ Completion gate: ${failures.length} done task(s) lack a verification receipt.`
|
|
299
288
|
: '⚠️ Completion gate: workflow completion proof is incomplete.',
|
|
300
289
|
];
|
|
301
|
-
for (const { taskPath, fails } of failures) {
|
|
290
|
+
for (const { taskPath, fails, body } of failures) {
|
|
302
291
|
lines.push(`- \`${taskPath}\`: failed check(s) ${fails.join(', ')}`);
|
|
303
292
|
lines.push(taskPath === 'feature-receipt.md'
|
|
304
293
|
? ` Fix: run final integration proof, then write \`specs/${featureName}/feature-receipt.md\`.`
|
|
305
294
|
: processWorkflow
|
|
306
|
-
? ` Fix in \`specs/${featureName}/${path.posix.basename(taskPath)}\`: ${(typeof RECEIPT.receiptFixHint === 'function' && RECEIPT.receiptFixHint(fails)) || 'write a runtime-bound `## Receipt` with command output'}.`
|
|
295
|
+
? ` Fix in \`specs/${featureName}/${path.posix.basename(taskPath)}\`: ${(typeof RECEIPT.receiptFixHint === 'function' && RECEIPT.receiptFixHint(fails, body)) || 'write a runtime-bound `## Receipt` with command output'}.`
|
|
307
296
|
: ` Fix: write canonical proof to \`specs/${featureName}/receipts/${path.posix.basename(taskPath)}\`; legacy \`## Evidence\` remains read-compatible.`);
|
|
308
297
|
}
|
|
309
298
|
if (completionBlocked) {
|
|
@@ -44,6 +44,40 @@ function canonicalPath(value) {
|
|
|
44
44
|
try { return fs.realpathSync(value); } catch { return null; }
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
/** Real path of `value`, resolving its deepest existing ancestor (the file may not exist yet). */
|
|
48
|
+
function canonicalTarget(value) {
|
|
49
|
+
if (typeof value !== 'string' || !value) return null;
|
|
50
|
+
let current = path.resolve(value);
|
|
51
|
+
const rest = [];
|
|
52
|
+
while (!fs.existsSync(current)) {
|
|
53
|
+
const parent = path.dirname(current);
|
|
54
|
+
if (parent === current) return null;
|
|
55
|
+
rest.unshift(path.basename(current));
|
|
56
|
+
current = parent;
|
|
57
|
+
}
|
|
58
|
+
const real = canonicalPath(current);
|
|
59
|
+
return real ? path.join(real, ...rest) : null;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function escapeRegExp(text) {
|
|
63
|
+
return text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Packets the prompt names: `specs/<name>`, a `/cf:<command> <name>` token, or the bare
|
|
68
|
+
* name when it carries `-`, `_` or a digit. A plain word such as `docs` must use `specs/`,
|
|
69
|
+
* so an ordinary sentence does not touch a packet.
|
|
70
|
+
*/
|
|
71
|
+
function packetsNamedIn(text, names) {
|
|
72
|
+
if (typeof text !== 'string' || !text) return [];
|
|
73
|
+
return names.filter((name) => {
|
|
74
|
+
const n = escapeRegExp(name);
|
|
75
|
+
if (new RegExp(`(^|[^\\w-])specs/${n}(?![\\w-])`).test(text)) return true;
|
|
76
|
+
if (new RegExp(`/cf:[\\w-]+\\s+(?:specs/)?${n}(?![\\w-])`).test(text)) return true;
|
|
77
|
+
return /[-_0-9]/.test(name) && new RegExp(`(^|[^\\w/-])${n}(?![\\w-])`).test(text);
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
47
81
|
try {
|
|
48
82
|
// ── Main ──────────────────────────────────────────────────────────────────
|
|
49
83
|
|
|
@@ -51,7 +85,8 @@ try {
|
|
|
51
85
|
if (!stdin) process.exit(0);
|
|
52
86
|
|
|
53
87
|
const { normalizeHookPayload } = require('./lib/hook-payload.cjs');
|
|
54
|
-
const
|
|
88
|
+
const rawPayload = JSON.parse(stdin);
|
|
89
|
+
const payload = normalizeHookPayload(rawPayload);
|
|
55
90
|
const cwd = payload.cwd || process.cwd();
|
|
56
91
|
|
|
57
92
|
let POLICY;
|
|
@@ -84,6 +119,64 @@ try {
|
|
|
84
119
|
const baseDir = installedRoot || process.env.PROJECT_ROOT || cwd;
|
|
85
120
|
const explicitFeature = payload.featureName || payload.feature || payload.explicitFeature || null;
|
|
86
121
|
const explicitPath = payload.specPath || payload.spec_path || payload.featurePath || null;
|
|
122
|
+
|
|
123
|
+
// ── Per-session touch set (Claude only) ───────────────────────────────────
|
|
124
|
+
// Several sessions can share one checkout. On Claude the tollgate speaks only about a
|
|
125
|
+
// packet this session touched. omp and Codex run their own copies, and grok sends
|
|
126
|
+
// `sessionId` before normalization, so all three keep the old behaviour.
|
|
127
|
+
const claudeSession = rawPayload && typeof rawPayload.session_id === 'string' && rawPayload.session_id
|
|
128
|
+
? rawPayload.session_id
|
|
129
|
+
: null;
|
|
130
|
+
const touchFilter = runtimeDirName() === '.claude' && claudeSession !== null;
|
|
131
|
+
const touchFile = touchFilter
|
|
132
|
+
? path.join(
|
|
133
|
+
require('./lib/hook-state-dir.cjs').hookStateDir(),
|
|
134
|
+
`spec-touched-${require('crypto').createHash('sha256').update(claudeSession).digest('hex')}.json`,
|
|
135
|
+
)
|
|
136
|
+
: null;
|
|
137
|
+
const readTouched = () => {
|
|
138
|
+
try {
|
|
139
|
+
const list = JSON.parse(fs.readFileSync(touchFile, 'utf8'));
|
|
140
|
+
return new Set(Array.isArray(list) ? list : []);
|
|
141
|
+
} catch { return new Set(); }
|
|
142
|
+
};
|
|
143
|
+
const addTouched = (names) => {
|
|
144
|
+
const touched = readTouched();
|
|
145
|
+
const before = touched.size;
|
|
146
|
+
for (const name of names) touched.add(name);
|
|
147
|
+
if (touched.size === before) return;
|
|
148
|
+
try {
|
|
149
|
+
fs.mkdirSync(path.dirname(touchFile), { recursive: true });
|
|
150
|
+
fs.writeFileSync(touchFile, JSON.stringify([...touched].sort()));
|
|
151
|
+
} catch { /* an unwritable state dir only loses the touch */ }
|
|
152
|
+
};
|
|
153
|
+
let specsRoot = null;
|
|
154
|
+
try { specsRoot = RESOLVER.specsDirectory(baseDir, runtime); } catch { /* resolver reports it below */ }
|
|
155
|
+
|
|
156
|
+
if (payload.hook_event_name === 'PostToolUse') {
|
|
157
|
+
// Record only; no resolve, no git, no tollgate cache.
|
|
158
|
+
if (touchFilter && specsRoot && /^(Edit|Write|MultiEdit)$/.test(payload.tool_name || '')) {
|
|
159
|
+
const realRoot = canonicalPath(specsRoot);
|
|
160
|
+
const realTarget = canonicalTarget(payload.tool_input && payload.tool_input.file_path);
|
|
161
|
+
if (realRoot && realTarget) {
|
|
162
|
+
const rel = path.relative(realRoot, realTarget);
|
|
163
|
+
const parts = rel.split(path.sep);
|
|
164
|
+
if (rel && parts[0] !== '..' && !path.isAbsolute(rel) && parts.length > 1) addTouched([parts[0]]);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
process.exit(0);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (touchFilter) {
|
|
171
|
+
let packets = [];
|
|
172
|
+
try {
|
|
173
|
+
packets = fs.readdirSync(specsRoot, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name);
|
|
174
|
+
} catch { /* no specs root */ }
|
|
175
|
+
const named = packetsNamedIn(payload.prompt, packets);
|
|
176
|
+
if (typeof explicitFeature === 'string' && explicitFeature) named.push(explicitFeature);
|
|
177
|
+
if (named.length) addTouched(named);
|
|
178
|
+
}
|
|
179
|
+
|
|
87
180
|
const resolveWorkflow = typeof RESOLVER.resolveWorkflowCandidate === 'function'
|
|
88
181
|
? RESOLVER.resolveWorkflowCandidate
|
|
89
182
|
: RESOLVER.resolveActiveSpec;
|
|
@@ -118,6 +211,7 @@ try {
|
|
|
118
211
|
const activeSpec = resolved.spec || {};
|
|
119
212
|
const processWorkflow = resolved.layoutKind === 'process-v3';
|
|
120
213
|
const featureName = resolved.featureName;
|
|
214
|
+
if (touchFilter && !readTouched().has(featureName)) process.exit(0);
|
|
121
215
|
const specsPath = resolved.specsDir;
|
|
122
216
|
const runtimeContext = POLICY.deriveRuntimeContext({
|
|
123
217
|
projectRoot: baseDir,
|
|
@@ -148,6 +148,21 @@ try {
|
|
|
148
148
|
return data;
|
|
149
149
|
}
|
|
150
150
|
|
|
151
|
+
/**
|
|
152
|
+
* True when latest.md holds something beyond the filler this hook writes itself:
|
|
153
|
+
* headings, HTML comments, the three placeholder bullets and timestamp-only agent results.
|
|
154
|
+
*/
|
|
155
|
+
function hasPriorContent(text) {
|
|
156
|
+
const filler = [
|
|
157
|
+
/^#{1,6}\s/,
|
|
158
|
+
/^<!--.*-->$/,
|
|
159
|
+
/^- \((No completed tasks recorded|All tasks completed|No file changes detected)\)$/,
|
|
160
|
+
/^- Completed at \d{2}:\d{2}:\d{2}$/,
|
|
161
|
+
];
|
|
162
|
+
return text.split('\n').map((line) => line.trim())
|
|
163
|
+
.some((line) => line && !filler.some((pattern) => pattern.test(line)));
|
|
164
|
+
}
|
|
165
|
+
|
|
151
166
|
function buildStateContent(data) {
|
|
152
167
|
const done = data.todos.filter((todo) => todo.status === 'completed' || todo.status === 'done');
|
|
153
168
|
const pending = data.todos.filter((todo) => !['completed', 'done'].includes(todo.status));
|
|
@@ -226,14 +241,18 @@ try {
|
|
|
226
241
|
if (!stdin) process.exit(0);
|
|
227
242
|
|
|
228
243
|
const { normalizeHookPayload } = require('./lib/hook-payload.cjs');
|
|
229
|
-
const
|
|
244
|
+
const rawPayload = JSON.parse(stdin);
|
|
245
|
+
const data = normalizeHookPayload(rawPayload);
|
|
230
246
|
const event = data.hook_event_name || '';
|
|
231
247
|
const cwd = data.cwd || process.cwd();
|
|
232
248
|
const dir = stateDir(cwd);
|
|
233
249
|
|
|
234
250
|
if (event === 'SessionStart') {
|
|
235
251
|
const previous = loadLatest(cwd);
|
|
236
|
-
|
|
252
|
+
// Claude only: grok (camelCase sessionId), omp and Codex keep printing the block.
|
|
253
|
+
const claudeSession = runtimeDirName() === '.claude'
|
|
254
|
+
&& typeof rawPayload.session_id === 'string' && rawPayload.session_id.length > 0;
|
|
255
|
+
if (previous && (!claudeSession || hasPriorContent(previous))) {
|
|
237
256
|
console.log('\n=== Prior Execution Context ===');
|
|
238
257
|
console.log(previous.trim());
|
|
239
258
|
console.log('=== End of Prior Context ===\n');
|
|
@@ -7,23 +7,21 @@
|
|
|
7
7
|
"skills": {
|
|
8
8
|
"required": [
|
|
9
9
|
"agent-browser",
|
|
10
|
+
"ask",
|
|
10
11
|
"brainstorm",
|
|
11
12
|
"chrome-devtools",
|
|
12
13
|
"code-review",
|
|
13
14
|
"debug",
|
|
14
|
-
"delegate",
|
|
15
15
|
"develop",
|
|
16
|
+
"fix",
|
|
16
17
|
"git",
|
|
17
|
-
"hotfix",
|
|
18
|
-
"inspect",
|
|
19
|
-
"loop",
|
|
20
18
|
"orca",
|
|
21
|
-
"question",
|
|
22
19
|
"research",
|
|
23
|
-
"
|
|
20
|
+
"scout",
|
|
24
21
|
"specs",
|
|
25
22
|
"sync",
|
|
26
23
|
"test",
|
|
24
|
+
"ui-ux",
|
|
27
25
|
"ui-ux-pro-max",
|
|
28
26
|
"web-testing"
|
|
29
27
|
],
|
|
@@ -86,7 +84,13 @@
|
|
|
86
84
|
"frontend-design",
|
|
87
85
|
"mobile-development",
|
|
88
86
|
"devops",
|
|
89
|
-
"react-best-practices"
|
|
87
|
+
"react-best-practices",
|
|
88
|
+
"inspect",
|
|
89
|
+
"hotfix",
|
|
90
|
+
"question",
|
|
91
|
+
"loop",
|
|
92
|
+
"route",
|
|
93
|
+
"delegate"
|
|
90
94
|
],
|
|
91
95
|
"agents": {
|
|
92
96
|
"claude": ["agents/god-developer.md"],
|
|
@@ -112,10 +116,27 @@
|
|
|
112
116
|
"skills/specs/rules/ears-format.md",
|
|
113
117
|
"skills/specs/rules/phase-decision-matrix.md",
|
|
114
118
|
"skills/specs/rules/task-scoring-rubric.md",
|
|
115
|
-
"skills/specs/rules/tasks-generation.md"
|
|
119
|
+
"skills/specs/rules/tasks-generation.md",
|
|
120
|
+
"hooks/usage.cjs",
|
|
121
|
+
"hooks/completion-authority.cjs",
|
|
122
|
+
"hooks/completion-authority-check.cjs",
|
|
123
|
+
"hooks/completion-authority-state.cjs",
|
|
124
|
+
"hooks/semantic-review-authority.cjs",
|
|
125
|
+
"hooks/task-scaffold-guard.cjs"
|
|
116
126
|
],
|
|
117
127
|
"settingsHookCommandSubstrings": [
|
|
118
|
-
"hooks/skill-router.cjs"
|
|
128
|
+
"hooks/skill-router.cjs",
|
|
129
|
+
".claude/hooks/usage.cjs",
|
|
130
|
+
".claude/hooks/docs-sync.cjs",
|
|
131
|
+
".claude/hooks/completion-authority.cjs",
|
|
132
|
+
".codex/hooks/completion-authority.cjs",
|
|
133
|
+
".codex\\hooks\\completion-authority.cjs",
|
|
134
|
+
".claude/hooks/semantic-review-authority.cjs",
|
|
135
|
+
".codex/hooks/semantic-review-authority.cjs",
|
|
136
|
+
".codex\\hooks\\semantic-review-authority.cjs",
|
|
137
|
+
".claude/hooks/task-scaffold-guard.cjs",
|
|
138
|
+
".codex/hooks/task-scaffold-guard.cjs",
|
|
139
|
+
".codex\\hooks\\task-scaffold-guard.cjs"
|
|
119
140
|
]
|
|
120
141
|
},
|
|
121
142
|
"runtime": {
|
|
@@ -128,18 +149,12 @@
|
|
|
128
149
|
"hooks/precompact.cjs",
|
|
129
150
|
"hooks/docs-sync.cjs",
|
|
130
151
|
"hooks/agent.cjs",
|
|
131
|
-
"hooks/usage.cjs",
|
|
132
152
|
"hooks/privacy-block.cjs",
|
|
133
153
|
"hooks/secret-output-guardrail.cjs",
|
|
134
154
|
"hooks/inspect-block.cjs",
|
|
135
|
-
"hooks/task-scaffold-guard.cjs",
|
|
136
155
|
"hooks/rules.cjs",
|
|
137
156
|
"hooks/spec-state.cjs",
|
|
138
157
|
"hooks/spec-gate.cjs",
|
|
139
|
-
"hooks/completion-authority.cjs",
|
|
140
|
-
"hooks/completion-authority-check.cjs",
|
|
141
|
-
"hooks/completion-authority-state.cjs",
|
|
142
|
-
"hooks/semantic-review-authority.cjs",
|
|
143
158
|
"hooks/state.cjs",
|
|
144
159
|
"hooks/lib/color.cjs",
|
|
145
160
|
"hooks/lib/parser.cjs",
|
|
@@ -4,28 +4,21 @@ Hooks are instruction boundaries. Do not bypass or work around them.
|
|
|
4
4
|
|
|
5
5
|
## Privacy Block Hook
|
|
6
6
|
|
|
7
|
-
When a tool call
|
|
7
|
+
When a tool call touches a sensitive file, or the hook cannot classify it safely,
|
|
8
|
+
the privacy hook returns a permission decision of `ask` with the reason, and the
|
|
9
|
+
host asks the user to approve or deny that one call. Do not ask again yourself.
|
|
10
|
+
On a host whose hook can only deny, the call is blocked; ask the user instead of
|
|
11
|
+
retrying it another way.
|
|
8
12
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
...
|
|
12
|
-
@@PRIVACY_PROMPT_END@@
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
Required flow:
|
|
16
|
-
|
|
17
|
-
1. Parse the JSON payload from the marker.
|
|
18
|
-
2. Ask the user for approval using the available user-question tool and the prompt/options from the payload.
|
|
19
|
-
3. If approved, retry only the blocked action.
|
|
20
|
-
4. If denied, continue without reading that file or performing that blocked action.
|
|
13
|
+
- If approved, the call runs; do not widen it to other files.
|
|
14
|
+
- If denied, continue without reading that file or performing that blocked action.
|
|
21
15
|
|
|
22
16
|
Never use another command, path, encoding, or side channel to access a privacy-blocked file without explicit approval.
|
|
23
17
|
|
|
24
18
|
## State And Spec Hooks
|
|
25
19
|
|
|
26
20
|
- If a hook reports state drift, run the appropriate sync/audit flow before continuing.
|
|
27
|
-
- If a hook rejects task completion, keep the task `in_progress` or `blocked` until proof exists.
|
|
28
|
-
- Do not mark a task `done` unless the matching task file contains a valid verification receipt.
|
|
21
|
+
- If a hook rejects task completion, keep the task `in_progress` or `blocked` until proof exists; the receipt contract lives in `state-sync.md`.
|
|
29
22
|
|
|
30
23
|
## Hook Failure Handling
|
|
31
24
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Living Documents
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
When the project keeps these core documents in `./docs`, keep them current (a project may have only some of them):
|
|
6
6
|
|
|
7
7
|
| Document | Purpose |
|
|
8
8
|
|----------|---------|
|
|
@@ -14,8 +14,6 @@ The project maintains these core documents in `./docs`:
|
|
|
14
14
|
### Freshness Rule
|
|
15
15
|
|
|
16
16
|
- Before updating any doc, check its last modified date
|
|
17
|
-
- If a doc hasn't been updated in >2 weeks while development is active, flag it for review
|
|
18
|
-
- The `docs-keeper` agent should proactively scan for stale docs during weekly reviews
|
|
19
17
|
|
|
20
18
|
## When to Update
|
|
21
19
|
|
|
@@ -26,7 +24,6 @@ The `docs-keeper` agent is responsible for keeping these documents current. Trig
|
|
|
26
24
|
- A significant feature ships or a critical bug is resolved
|
|
27
25
|
- Security patches are applied or dependencies change
|
|
28
26
|
- Project scope or timeline shifts
|
|
29
|
-
- Weekly progress reviews are due
|
|
30
27
|
|
|
31
28
|
### Update Discipline
|
|
32
29
|
|
|
@@ -43,7 +40,7 @@ Use [Keep a Changelog](https://keepachangelog.com/) convention:
|
|
|
43
40
|
## [version] - YYYY-MM-DD
|
|
44
41
|
|
|
45
42
|
### Added
|
|
46
|
-
- Feature description (#PR-number)
|
|
43
|
+
- Feature description (#PR-number when there is one)
|
|
47
44
|
|
|
48
45
|
### Fixed
|
|
49
46
|
- Bug fix description (#issue-number)
|
|
@@ -74,38 +71,27 @@ specs/
|
|
|
74
71
|
|
|
75
72
|
Task files are direct children beside `plan.md`; do not place them in a task
|
|
76
73
|
subdirectory.
|
|
77
|
-
The plan records the
|
|
74
|
+
The plan records the GATE-SCOPE scope decision, explicit exclusions, acceptance
|
|
78
75
|
criteria, and task mapping. Each task owns one usable outcome, bounded paths,
|
|
79
76
|
dependencies, acceptance, and a runnable Verification Plan.
|
|
80
77
|
|
|
81
78
|
### Gates and execution handoff
|
|
82
79
|
|
|
83
|
-
-
|
|
84
|
-
-
|
|
80
|
+
- GATE-SCOPE: the user chooses EXPAND, KEEP, or CUT before the plan is written.
|
|
81
|
+
- GATE-REVIEW: the user accepts, rejects, or revises deduplicated adversarial findings.
|
|
85
82
|
- Specs stops after planning; implementation begins only through a new explicit
|
|
86
83
|
Develop invocation.
|
|
87
|
-
-
|
|
84
|
+
- GATE-DONE: after execution, current receipts and limitations are shown and the user
|
|
88
85
|
decides whether the feature is complete.
|
|
89
86
|
|
|
90
87
|
### Task state and proof
|
|
91
88
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
`Verification: PASS`, runtime-derived Base and Head values, and non-empty
|
|
95
|
-
fenced current output before the task becomes done.
|
|
89
|
+
Task status, the inline `## Receipt` and its proof contract are defined in
|
|
90
|
+
`state-sync.md`.
|
|
96
91
|
|
|
97
92
|
Sync only observed state with surgical edits. Re-read the changed task after
|
|
98
93
|
every update; never infer missing proof, approval, or readiness. When a done
|
|
99
94
|
task changes user-facing behavior, architecture, API contracts, operations, or
|
|
100
95
|
project status, classify docs impact and update only affected existing docs.
|
|
101
96
|
|
|
102
|
-
Comply with the overarching rules in
|
|
103
|
-
|
|
104
|
-
## Legacy specification layout
|
|
105
|
-
|
|
106
|
-
Existing features containing `spec.json`, nested `tasks/task-R*.md`, or other
|
|
107
|
-
legacy kernel artifacts keep their installed adapters and original layout.
|
|
108
|
-
Preserve `task_registry`, `semantic_model`, `planning_depth`, lane,
|
|
109
|
-
`execution_tier`, machine authority, typed topology, separate receipts, and
|
|
110
|
-
feature closeout files. Do not migrate them as part of unrelated documentation
|
|
111
|
-
work.
|
|
97
|
+
Comply with the overarching rules in `ai-dev-rules.md`.
|
|
@@ -22,10 +22,9 @@ Example prompt:
|
|
|
22
22
|
|
|
23
23
|
## Resource Constraints
|
|
24
24
|
|
|
25
|
-
- Each subagent has
|
|
26
|
-
- Spawning many parallel agents degrades system performance — check available CPU/memory before scaling out. For parallel implementation waves the cap is 3 concurrent agents by default, never more than 5 (each agent carries
|
|
25
|
+
- Each subagent has its own context window — scope tasks to fit comfortably within it
|
|
26
|
+
- Spawning many parallel agents degrades system performance — check available CPU/memory before scaling out. For parallel implementation waves the cap is 3 concurrent agents by default, never more than 5 (each agent carries its own context window)
|
|
27
27
|
- Prefer fewer, well-scoped agents over many overlapping ones
|
|
28
|
-
- Include system resource info (from hook injection) when delegating tasks so subagents can self-regulate
|
|
29
28
|
|
|
30
29
|
---
|
|
31
30
|
|
|
@@ -132,7 +131,7 @@ Docs: [docs path]
|
|
|
132
131
|
|
|
133
132
|
| ❌ Vague | ✅ Precise |
|
|
134
133
|
|----------|-----------|
|
|
135
|
-
| "Pick up where we left off" | "Add the `/users` POST endpoint per `
|
|
134
|
+
| "Pick up where we left off" | "Add the `/users` POST endpoint per `task-02-api.md`" |
|
|
136
135
|
| "Fix the issues we talked about" | "Add null-check in `auth.ts:45` — root cause: missing input validation" |
|
|
137
136
|
| "Explore the codebase" | "Read `src/api/routes.ts`, then add the missing handler" |
|
|
138
137
|
| Dumping 50+ lines of chat history | A 5-line summary with file paths |
|
|
@@ -12,10 +12,10 @@ When rejecting an audit concern, name the verification source briefly.
|
|
|
12
12
|
|
|
13
13
|
## User Decisions
|
|
14
14
|
|
|
15
|
-
Do not silently undo an explicit user decision. This covers the
|
|
16
|
-
|
|
15
|
+
Do not silently undo an explicit user decision. This covers the GATE-SCOPE scope choice,
|
|
16
|
+
GATE-REVIEW finding dispositions, and GATE-DONE completion judgement, along with thresholds,
|
|
17
17
|
selected libraries, feature scope, schema shape, pricing, timelines, compliance
|
|
18
|
-
choices, and UX trade-offs. Those gates are defined in `
|
|
18
|
+
choices, and UX trade-offs. Those gates are defined in `state-sync.md`; this rule
|
|
19
19
|
governs only how a later review may treat them.
|
|
20
20
|
|
|
21
21
|
If an audit suggests reversing a user decision, present:
|
|
@@ -27,6 +27,4 @@ an entry condition for the primary. If zero valid capabilities match, continue
|
|
|
27
27
|
inline when safe or name the gap. If multiple catalog entries expose the same
|
|
28
28
|
public identity, do not auto-route; require explicit user disambiguation.
|
|
29
29
|
|
|
30
|
-
Never infer an optional document capability from this rule.
|
|
31
|
-
explicit-only numeric optimization capability unless the user invokes it with
|
|
32
|
-
its required bounded metric/guard contract.
|
|
30
|
+
Never infer an optional document capability from this rule.
|
|
@@ -9,9 +9,9 @@ workflow.
|
|
|
9
9
|
1. If the user names a valid installed skill, use it directly.
|
|
10
10
|
2. If one obvious low-risk installed skill covers the intent, use it directly.
|
|
11
11
|
3. For direct factual conversation, answer directly or use the installed
|
|
12
|
-
evidence-answer capability; do not
|
|
13
|
-
4. For ambiguous, multi-step, multi-domain, or elevated/high-risk work,
|
|
14
|
-
|
|
12
|
+
evidence-answer capability; do not spawn agents for ceremony.
|
|
13
|
+
4. For ambiguous, multi-step, multi-domain, or elevated/high-risk work, classify
|
|
14
|
+
it yourself and compose the shortest valid chain below.
|
|
15
15
|
|
|
16
16
|
Resolve every abstract link against the current runtime catalog. An absent,
|
|
17
17
|
invalid, folder-mismatched, duplicate, or retired entry is not routable. Continue
|
|
@@ -28,5 +28,4 @@ owner, entry condition, and observable exit per retained link. Diagnosis does
|
|
|
28
28
|
not authorize repair; implementation does not authorize commit, push, deploy,
|
|
29
29
|
publish, or release; no route expands the user's existing authority.
|
|
30
30
|
|
|
31
|
-
Use `skill-domain-routing.md` to resolve domain capability slots.
|
|
32
|
-
optimization capability remains explicit-only and must never be auto-routed.
|
|
31
|
+
Use `skill-domain-routing.md` to resolve domain capability slots.
|
|
@@ -51,19 +51,10 @@ proves only the boundary it executed.
|
|
|
51
51
|
|
|
52
52
|
## Human gates and workflow ownership
|
|
53
53
|
|
|
54
|
-
-
|
|
55
|
-
-
|
|
54
|
+
- GATE-SCOPE records the user's scope decision before the plan is written.
|
|
55
|
+
- GATE-REVIEW records the user's disposition of deduplicated adversarial findings.
|
|
56
56
|
- Develop starts only after a new explicit user invocation and executes one
|
|
57
57
|
unblocked task at a time.
|
|
58
58
|
- Sync changes only observed file state and never starts implementation.
|
|
59
|
-
-
|
|
59
|
+
- GATE-DONE occurs after current receipts and limitations are shown; the user decides
|
|
60
60
|
whether the requested feature is complete.
|
|
61
|
-
|
|
62
|
-
## Legacy compatibility
|
|
63
|
-
|
|
64
|
-
Existing packets containing `spec.json`, nested `tasks/task-R*.md`, or other
|
|
65
|
-
legacy kernel artifacts stay on their installed adapters. Preserve their
|
|
66
|
-
`task_registry`, `semantic_model`, `planning_depth`, lane,
|
|
67
|
-
`execution_tier`, typed topology, separate receipts, and feature closeout
|
|
68
|
-
contract. Do not migrate that machine authority or storage shape while syncing
|
|
69
|
-
an unrelated process-first packet.
|