@linimin/pi-letscook 0.1.68 → 0.1.70
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/.agent/README.md +2 -3
- package/.agent/verify_completion_control_plane.sh +21 -34
- package/CHANGELOG.md +16 -0
- package/README.md +23 -26
- package/agents/completion-bootstrapper.md +1 -2
- package/agents/completion-regrounder.md +10 -16
- package/extensions/completion/driver.ts +69 -136
- package/extensions/completion/index.ts +94 -81
- package/extensions/completion/policy-guards.ts +1 -1
- package/extensions/completion/prompt-surfaces.ts +63 -161
- package/extensions/completion/proposal.ts +26 -61
- package/extensions/completion/role-runner.ts +161 -57
- package/extensions/completion/state-store.ts +43 -85
- package/extensions/completion/types.ts +2 -3
- package/package.json +1 -1
- package/scripts/active-slice-contract-test.sh +21 -0
- package/scripts/canonical-evidence-artifact-test.sh +57 -65
- package/scripts/context-proposal-test.sh +1430 -310
- package/scripts/legacy-cleanup-test.sh +1 -1
- package/scripts/refocus-test.sh +459 -185
- package/scripts/release-check.sh +14 -15
- package/scripts/role-runner-contract-test.sh +4 -2
- package/scripts/smoke-test.sh +36 -78
- package/skills/completion-protocol/SKILL.md +8 -9
- package/skills/completion-protocol/references/completion.md +2 -37
- package/skills/cook-handoff-boundary/SKILL.md +19 -18
package/scripts/release-check.sh
CHANGED
|
@@ -5,42 +5,42 @@ ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
|
5
5
|
cd "$ROOT"
|
|
6
6
|
export PI_COMPLETION_RUNNING_RELEASE_CHECK=1
|
|
7
7
|
|
|
8
|
-
echo "[release-check] running control-plane validation, tracked .agent contract coverage, slice-surface parity,
|
|
8
|
+
echo "[release-check] running control-plane validation, tracked .agent contract coverage, slice-surface parity, explicit-/cook parity, startup/refocus/context regressions, canonical evidence artifact, active-slice contract, observability, legacy cleanup, evaluator calibration, and rubric contract coverage"
|
|
9
9
|
bash .agent/verify_completion_control_plane.sh
|
|
10
10
|
git ls-files --error-unmatch .agent/README.md .agent/mission.md .agent/profile.json .agent/verify_completion_stop.sh .agent/verify_completion_control_plane.sh >/dev/null
|
|
11
11
|
|
|
12
|
-
echo "[release-check] verifying public /cook parity and
|
|
12
|
+
echo "[release-check] verifying public /cook parity and primary-agent-handoff docs/help"
|
|
13
13
|
python3 - <<'PY'
|
|
14
14
|
from pathlib import Path
|
|
15
15
|
|
|
16
16
|
checks = {
|
|
17
17
|
"README.md": [
|
|
18
18
|
"You can still implement directly in ordinary chat when you do not need workflow state.",
|
|
19
|
-
"When you explicitly run `/cook`, it
|
|
20
|
-
"
|
|
21
|
-
"
|
|
19
|
+
"When you explicitly run `/cook`, it first checks for a fresh explicit primary-agent handoff.",
|
|
20
|
+
"If one is missing, it calls a same-entry primary-agent handoff synthesis step from the current task context, then asks you to **Start** or **Cancel** before rewriting canonical workflow state.",
|
|
21
|
+
"Explicit `/cook` capsules are still valid startup intake, but they are no longer the only path because `/cook` can synthesize the primary-agent handoff in the same entry when needed.",
|
|
22
22
|
],
|
|
23
23
|
"CHANGELOG.md": [
|
|
24
|
-
"
|
|
25
|
-
"
|
|
24
|
+
"preserved the confirmed `/cook` startup intent in canonical `.agent/startup-brief.json` so workflow entry is durable before regrounding authors canonical slices",
|
|
25
|
+
"moved workflow-session legitimacy away from in-memory routing activation and legacy `/skill:completion-protocol` prompt dependence toward canonical workflow-session state plus explicit `/cook` entry turns",
|
|
26
26
|
],
|
|
27
27
|
"extensions/completion/prompt-surfaces.ts": [
|
|
28
|
-
'"If the user explicitly runs /cook, the extension should call a primary-agent
|
|
29
|
-
'"Do not expect /cook to infer or guess startup intent from recent discussion alone
|
|
28
|
+
'"If the user explicitly runs /cook, the extension should call a primary-agent handoff synthesis step from the current task context, show Start/Cancel confirmation, and persist the confirmed startup brief into .agent/** without making the user rerun /cook."',
|
|
29
|
+
'"Do not expect /cook to infer or guess startup intent from recent discussion alone; /cook should use explicit primary-agent handoff data, whether it already exists or is synthesized in the same /cook entry."',
|
|
30
30
|
'"In ordinary chat, do not load or follow completion-protocol, and do not call completion_role."',
|
|
31
31
|
],
|
|
32
32
|
"extensions/completion/index.ts": [
|
|
33
|
-
'"/cook failed closed because the
|
|
34
|
-
'description: "/cook workflow:
|
|
35
|
-
'"Do not call completion_role from ordinary chat; it is reserved for
|
|
33
|
+
'"/cook failed closed because the primary-agent handoff step could not prepare a concrete startup handoff from the current task context. Clarify the mission, first slice, or verification intent in the main chat, then rerun /cook."',
|
|
34
|
+
'description: "/cook workflow: start or replace workflow only from an explicit primary-agent handoff, or resume the current workflow from canonical state"',
|
|
35
|
+
'"Do not call completion_role from ordinary chat; it is reserved for active /cook workflow sessions."',
|
|
36
|
+
'`COMPLETION WORKFLOW DRIVER\\nStart or continue the completion workflow for this repo.',
|
|
36
37
|
],
|
|
37
38
|
"extensions/completion/policy-guards.ts": [
|
|
38
|
-
'return "completion_role may only be used from an
|
|
39
|
+
'return "completion_role may only be used from an active /cook workflow session.";',
|
|
39
40
|
],
|
|
40
41
|
"skills/cook-handoff-boundary/SKILL.md": [
|
|
41
42
|
'- load or follow `completion-protocol` while still in ordinary chat',
|
|
42
43
|
'- call `completion_role` before the user has explicitly entered `/cook`',
|
|
43
|
-
'- `/cook` should always synthesize the startup plan fresh in the same entry from current task context',
|
|
44
44
|
],
|
|
45
45
|
"skills/completion-protocol/SKILL.md": [
|
|
46
46
|
'Load this skill only after the user explicitly enters `/cook` and you are operating inside the `completion` workflow as the workflow driver or a completion role.',
|
|
@@ -52,7 +52,6 @@ forbidden = {
|
|
|
52
52
|
"README.md": [
|
|
53
53
|
"asks the primary agent to prepare one in the main chat and leaves canonical state unchanged until you rerun /cook",
|
|
54
54
|
"Explicit `/cook` capsules are the required startup intake for new-workflow, next-round, and replacement entry.",
|
|
55
|
-
"When you explicitly run `/cook`, it first checks for a fresh explicit primary-agent startup-plan preview.",
|
|
56
55
|
],
|
|
57
56
|
"extensions/completion/prompt-surfaces.ts": [
|
|
58
57
|
'"If the user explicitly asks to enter /cook workflow, generate one fresh ```cook_handoff``` capsule in ordinary chat from the primary-agent view of the task, then tell the user to run /cook."',
|
|
@@ -30,9 +30,11 @@ assertIncludes('extensions/completion/role-runner.ts', 'const transcription = ex
|
|
|
30
30
|
assertIncludes('extensions/completion/role-runner.ts', 'env: { ...process.env, PI_COMPLETION_ROLE: params.role },');
|
|
31
31
|
assertIncludes('extensions/completion/role-runner.ts', 'async function runContextProposalAnalystSubprocess(');
|
|
32
32
|
assertIncludes('extensions/completion/role-runner.ts', 'export async function analyzeContextProposalWithAgent(');
|
|
33
|
-
assertIncludes('extensions/completion/
|
|
33
|
+
assertIncludes('extensions/completion/role-runner.ts', 'class CookStartupOverlay extends Container');
|
|
34
|
+
assertIncludes('extensions/completion/role-runner.ts', 'overlay = new CookStartupOverlay(theme, {');
|
|
35
|
+
assertIncludes('extensions/completion/index.ts', 'import { analyzeContextProposalWithAgent, generateCookHandoffWithAgent, runCompletionRole } from "./role-runner";');
|
|
34
36
|
assertIncludes('extensions/completion/index.ts', 'const result = await runCompletionRole({');
|
|
35
|
-
|
|
37
|
+
assertIncludes('extensions/completion/index.ts', 'const raw = await generateCookHandoffWithAgent({');
|
|
36
38
|
assertNotIncludes('extensions/completion/index.ts', 'const systemPromptTemp = await writeTempFile(runCwd, "pi-cook-proposal-analyst-", CONTEXT_PROPOSAL_ANALYST_SYSTEM_PROMPT);');
|
|
37
39
|
assertNotIncludes('extensions/completion/index.ts', 'const invocation = getPiInvocation(args);');
|
|
38
40
|
assertNotIncludes('extensions/completion/index.ts', 'async function loadAgentDefinition(');
|
package/scripts/smoke-test.sh
CHANGED
|
@@ -103,12 +103,13 @@ INLINE_REJECTION_ROUTING_SNAPSHOT="$TMPDIR/inline-arg-routing.json"
|
|
|
103
103
|
INLINE_REJECTION_PROPOSAL_SNAPSHOT="$TMPDIR/inline-arg-proposal.json"
|
|
104
104
|
INLINE_REJECTION_CHOOSER_SNAPSHOT="$TMPDIR/inline-arg-chooser.json"
|
|
105
105
|
BOOTSTRAP_SESSION="$TMPDIR/session-smoke-bootstrap.jsonl"
|
|
106
|
-
|
|
107
|
-
GENERATED_HANDOFF="$(python3 - <<'PY'
|
|
106
|
+
BOOTSTRAP_MESSAGES="$(python3 - <<'PY'
|
|
108
107
|
import json
|
|
109
108
|
capsule = {
|
|
110
109
|
"kind": "cook_handoff",
|
|
111
110
|
"source": "primary_agent",
|
|
111
|
+
"captured_at": "2026-01-01T00:00:02.000Z",
|
|
112
|
+
"source_turn_id": "m0002",
|
|
112
113
|
"mission": "Exercise smoke-test bootstrap.",
|
|
113
114
|
"scope": [
|
|
114
115
|
"Materialize the canonical completion control-plane files.",
|
|
@@ -118,14 +119,14 @@ capsule = {
|
|
|
118
119
|
"Keep startup proposal confirmation approval-only."
|
|
119
120
|
],
|
|
120
121
|
"acceptance": [
|
|
121
|
-
"
|
|
122
|
+
"Write the workflow control-plane files under .agent, including profile.json, state.json, active-slice.json, verification-evidence.json, and the slice backlog file, for the smoke fixture.",
|
|
122
123
|
"Keep scripts/smoke-test.sh and kickoff-prompt coverage truthful for packaged bootstrap."
|
|
123
124
|
],
|
|
124
125
|
"risks": [
|
|
125
|
-
"Smoke-test bootstrap should stay anchored to
|
|
126
|
+
"Smoke-test bootstrap should stay anchored to the fresh explicit handoff."
|
|
126
127
|
],
|
|
127
128
|
"notes": [
|
|
128
|
-
"Keep the smoke fixture aligned with the shipped
|
|
129
|
+
"Keep the smoke fixture aligned with the shipped explicit-handoff-only startup contract."
|
|
129
130
|
],
|
|
130
131
|
"handoff_kind": "implementation_workflow_handoff",
|
|
131
132
|
"first_slice_goal": "Scaffold canonical completion files and verify the packaged startup contract.",
|
|
@@ -139,12 +140,16 @@ capsule = {
|
|
|
139
140
|
"verification_commands": [
|
|
140
141
|
"npm run smoke-test"
|
|
141
142
|
],
|
|
142
|
-
"why_this_slice_first": "The packaged
|
|
143
|
+
"why_this_slice_first": "The packaged explicit-handoff startup path must work before later workflow verification can run.",
|
|
143
144
|
"task_type": "completion-workflow",
|
|
144
145
|
"evaluation_profile": "completion-rubric-v1",
|
|
145
|
-
"why_cook_now": "The startup
|
|
146
|
+
"why_cook_now": "The startup handoff is concrete enough to bootstrap canonical workflow files."
|
|
146
147
|
}
|
|
147
|
-
|
|
148
|
+
messages = [
|
|
149
|
+
{"role": "user", "content": "Please prepare the packaged smoke-test bootstrap path and tell me when it is ready for /cook."},
|
|
150
|
+
{"role": "assistant", "content": "This bootstrap path is ready for /cook. Run /cook to confirm the startup brief.\n\n```cook_handoff\n" + json.dumps(capsule, ensure_ascii=False, indent=2) + "\n```"},
|
|
151
|
+
]
|
|
152
|
+
print(json.dumps(messages, ensure_ascii=False))
|
|
148
153
|
PY
|
|
149
154
|
)"
|
|
150
155
|
|
|
@@ -170,21 +175,21 @@ chooser = Path(sys.argv[5])
|
|
|
170
175
|
|
|
171
176
|
assert not Path('.agent').exists(), 'startup /cook inline-args rejection should leave canonical state untouched'
|
|
172
177
|
assert not routing.exists(), 'startup /cook inline-args rejection should not open active-workflow routing before a workflow exists'
|
|
173
|
-
assert not proposal.exists(), 'startup /cook inline-args rejection should not emit a startup-
|
|
178
|
+
assert not proposal.exists(), 'startup /cook inline-args rejection should not emit a startup-brief proposal snapshot'
|
|
174
179
|
assert not chooser.exists(), 'startup /cook inline-args rejection should not open the existing-workflow chooser before a workflow exists'
|
|
175
180
|
assert '/cook no longer accepts inline arguments.' in output, 'startup /cook inline-args rejection should explain the bare-only entry contract'
|
|
176
181
|
PY
|
|
177
182
|
|
|
178
|
-
|
|
183
|
+
write_session_messages "$BOOTSTRAP_SESSION" "$ROOT" "$BOOTSTRAP_MESSAGES"
|
|
179
184
|
|
|
180
185
|
PI_COMPLETION_CONTEXT_PROPOSAL_ACTION=accept \
|
|
181
|
-
|
|
186
|
+
PI_COMPLETION_DISABLE_CONTEXT_PROPOSAL_ANALYST=1 \
|
|
182
187
|
PI_COMPLETION_SKIP_DRIVER_KICKOFF=1 \
|
|
183
188
|
PI_COMPLETION_TEST_DRIVER_PROMPT_PATH="$KICKOFF_PROMPT" \
|
|
184
189
|
pi --session "$BOOTSTRAP_SESSION" -e "$PKG_ROOT" -p "/cook" \
|
|
185
190
|
>"$TMPDIR/pi-completion-smoke-bootstrap.out" 2>"$TMPDIR/pi-completion-smoke-bootstrap.err"
|
|
186
191
|
|
|
187
|
-
for file in .agent/profile.json .agent/state.json .agent/startup-
|
|
192
|
+
for file in .agent/profile.json .agent/state.json .agent/startup-brief.json .agent/plan.json .agent/active-slice.json .agent/verification-evidence.json; do
|
|
188
193
|
[[ -f "$file" ]] || { echo "missing canonical bootstrap file: $file" >&2; exit 1; }
|
|
189
194
|
done
|
|
190
195
|
|
|
@@ -204,8 +209,7 @@ profile = json.loads(Path('.agent/profile.json').read_text())
|
|
|
204
209
|
state = json.loads(Path('.agent/state.json').read_text())
|
|
205
210
|
plan = json.loads(Path('.agent/plan.json').read_text())
|
|
206
211
|
active = json.loads(Path('.agent/active-slice.json').read_text())
|
|
207
|
-
|
|
208
|
-
startup_plan_md = Path('.agent/startup-plan.md').read_text()
|
|
212
|
+
startup_brief = json.loads(Path('.agent/startup-brief.json').read_text())
|
|
209
213
|
evidence = json.loads(Path('.agent/verification-evidence.json').read_text())
|
|
210
214
|
kickoff = Path(sys.argv[1]).read_text()
|
|
211
215
|
|
|
@@ -219,28 +223,28 @@ assert active['task_type'] == expected_task_type, 'active-slice.json task_type m
|
|
|
219
223
|
assert active['evaluation_profile'] == expected_eval_profile, 'active-slice.json evaluation_profile mismatch after bootstrap'
|
|
220
224
|
assert active['implementation_surfaces'] == [], 'active-slice.json should scaffold empty implementation_surfaces'
|
|
221
225
|
assert active['verification_commands'] == [], 'active-slice.json should scaffold empty verification_commands'
|
|
226
|
+
assert state['workflow_entry_status'] == 'active', 'state.json should mark workflow entry active after /cook Start'
|
|
227
|
+
assert state['workflow_entry_source'] == '/cook', 'state.json should record /cook as workflow entry source'
|
|
228
|
+
assert state['startup_brief_path'] == '.agent/startup-brief.json', 'state.json should point to startup-brief.json'
|
|
229
|
+
assert isinstance(state['workflow_session_id'], str) and state['workflow_session_id'], 'state.json should record a workflow session id'
|
|
222
230
|
brief = state['advisory_startup_brief']
|
|
223
231
|
assert brief['kind'] == 'startup_brief', 'state.json should preserve the confirmed startup brief as advisory intake'
|
|
224
|
-
assert brief['source'] == '
|
|
232
|
+
assert brief['source'] == 'primary_agent_handoff', 'smoke bootstrap should record the explicit handoff source in advisory intake'
|
|
225
233
|
assert brief['mission'] == state['mission_anchor'], 'advisory startup brief mission should match the canonical mission anchor after bootstrap'
|
|
226
234
|
assert brief['scope'] == ['Materialize the canonical completion control-plane files.', 'Keep the smoke test on supported /cook startup behavior.'], 'advisory startup brief should preserve scope items'
|
|
227
235
|
assert brief['constraints'] == ['Keep startup proposal confirmation approval-only.'], 'advisory startup brief should preserve constraints'
|
|
228
|
-
assert startup_plan['artifact_type'] == 'completion-startup-plan', 'startup-plan.json should persist the approved startup plan canonically'
|
|
229
|
-
assert startup_plan['mission_anchor'] == state['mission_anchor'], 'startup-plan.json mission anchor should match canonical workflow state'
|
|
230
|
-
assert startup_plan['source'] == 'deferred_primary_agent_handoff', 'startup-plan.json should preserve the same-entry primary-agent startup source'
|
|
231
|
-
assert startup_plan['scope'] == brief['scope'], 'startup-plan.json should preserve approved scope items'
|
|
232
|
-
assert startup_plan['constraints'] == brief['constraints'], 'startup-plan.json should preserve approved constraints'
|
|
233
|
-
assert startup_plan['planned_surfaces'] == ['.agent/README.md', 'scripts/smoke-test.sh'], 'startup-plan.json should preserve planned surfaces derived from startup hints'
|
|
234
|
-
assert startup_plan['verification_intent'] == ['npm run smoke-test'], 'startup-plan.json should preserve verification intent derived from startup hints'
|
|
235
|
-
assert '## Planned surfaces' in startup_plan_md, 'startup-plan.md should render planned surfaces as a readable section'
|
|
236
|
-
assert '.agent/README.md' in startup_plan_md and 'scripts/smoke-test.sh' in startup_plan_md, 'startup-plan.md should mirror planned surfaces'
|
|
237
236
|
assert brief['acceptance'] == [
|
|
238
|
-
'
|
|
237
|
+
'Write the workflow control-plane files under .agent, including profile.json, state.json, active-slice.json, verification-evidence.json, and the slice backlog file, for the smoke fixture.',
|
|
239
238
|
'Keep scripts/smoke-test.sh and kickoff-prompt coverage truthful for packaged bootstrap.'
|
|
240
239
|
], 'advisory startup brief should preserve acceptance'
|
|
241
|
-
assert brief['risks'] == ['Smoke-test bootstrap should stay anchored to
|
|
240
|
+
assert brief['risks'] == ['Smoke-test bootstrap should stay anchored to the fresh explicit handoff.'], 'advisory startup brief should preserve handoff risks'
|
|
242
241
|
assert 'First slice goal: Scaffold canonical completion files and verify the packaged startup contract.' in brief['notes'], 'advisory startup brief should preserve the first_slice_goal in notes'
|
|
243
242
|
assert 'Verification commands: npm run smoke-test' in brief['notes'], 'advisory startup brief should preserve verification_commands in notes'
|
|
243
|
+
assert startup_brief['artifact_type'] == 'completion-startup-brief', 'startup-brief.json artifact_type mismatch after bootstrap'
|
|
244
|
+
assert startup_brief['mission'] == state['mission_anchor'], 'startup-brief.json mission should match the canonical mission anchor after bootstrap'
|
|
245
|
+
assert startup_brief['task_type'] == expected_task_type, 'startup-brief.json task_type mismatch after bootstrap'
|
|
246
|
+
assert startup_brief['evaluation_profile'] == expected_eval_profile, 'startup-brief.json evaluation_profile mismatch after bootstrap'
|
|
247
|
+
assert startup_brief['acceptance'] == brief['acceptance'], 'startup-brief.json should preserve the confirmed acceptance list'
|
|
244
248
|
assert evidence['artifact_type'] == 'completion-verification-evidence', 'verification-evidence.json artifact_type mismatch after bootstrap'
|
|
245
249
|
assert evidence['subject_type'] == 'none', 'verification-evidence.json should scaffold idle subject_type'
|
|
246
250
|
assert evidence['verification_commands'] == [], 'verification-evidence.json should scaffold empty verification_commands'
|
|
@@ -248,6 +252,7 @@ assert evidence['outcome'] == 'not_recorded', 'verification-evidence.json should
|
|
|
248
252
|
assert 'Canonical routing profile:' in kickoff, 'kickoff prompt should expose canonical routing profile'
|
|
249
253
|
assert f'- task_type: {expected_task_type}' in kickoff, 'kickoff prompt missing canonical task_type'
|
|
250
254
|
assert f'- evaluation_profile: {expected_eval_profile}' in kickoff, 'kickoff prompt missing canonical evaluation_profile'
|
|
255
|
+
assert f'- workflow_session_id: {state["workflow_session_id"]}' in kickoff, 'kickoff prompt should expose canonical workflow_session_id'
|
|
251
256
|
PY
|
|
252
257
|
|
|
253
258
|
rm -f "$ORDINARY_SYSTEM_REMINDER" "$ORDINARY_HANDOFF_REMINDER" "$ORDINARY_AUTO_RESUME_PROMPT"
|
|
@@ -277,9 +282,8 @@ assert 'Do not proactively tell the user to run /cook' in handoff_text, 'ordinar
|
|
|
277
282
|
assert '/cook is optional workflow mode' in handoff_text, 'ordinary handoff reminder should position /cook as optional workflow mode'
|
|
278
283
|
assert 'In ordinary chat, do not load or follow completion-protocol, and do not call completion_role.' in handoff_text, 'ordinary handoff reminder should forbid workflow-role routing before explicit /cook'
|
|
279
284
|
assert 'If the user wants direct implementation now, stay in ordinary chat and help directly instead of blocking on /cook.' in handoff_text, 'ordinary handoff reminder should avoid blocking implementation on /cook'
|
|
280
|
-
assert 'the extension should call a primary-agent
|
|
285
|
+
assert 'the extension should call a primary-agent handoff synthesis step from the current task context' in handoff_text, 'ordinary handoff reminder should describe same-entry primary-agent handoff synthesis for /cook'
|
|
281
286
|
assert 'Do not expect /cook to infer or guess startup intent from recent discussion alone' in handoff_text, 'ordinary handoff reminder should forbid /cook-side guessing'
|
|
282
|
-
assert 'the approved startup plan should be written into .agent and then handed to completion-regrounder' in handoff_text, 'ordinary handoff reminder should mention startup-plan persistence and regrounder slice derivation'
|
|
283
287
|
assert 'do not silently rewrite discussion into canonical workflow state' in handoff_text, 'ordinary handoff reminder should preserve non-canonical ordinary-chat behavior'
|
|
284
288
|
assert not auto_resume.exists(), 'ordinary non-/cook turn should not queue auto-resume before /cook activation'
|
|
285
289
|
assert 'Skipped completion workflow auto-resume prompt (test mode)' not in output, 'ordinary non-/cook turn should not attempt auto-resume'
|
|
@@ -309,10 +313,10 @@ assert f'- task_type: {expected_task_type}' in resume, 'resume prompt missing ca
|
|
|
309
313
|
assert f'- evaluation_profile: {expected_eval_profile}' in resume, 'resume prompt missing canonical evaluation_profile'
|
|
310
314
|
assert routing['mode'] == 'bare', 'active bare /cook should snapshot bare routing mode'
|
|
311
315
|
assert routing['action'] == 'continue', 'no-discussion active bare /cook should resume from canonical state without a concrete replacement mission'
|
|
312
|
-
assert routing['reason'] == '
|
|
316
|
+
assert routing['reason'] == 'missing_explicit_handoff', 'no-discussion active bare /cook should explain that resume happened because no fresh explicit handoff existed'
|
|
313
317
|
assert routing['currentMissionAnchor'] == state['mission_anchor'], 'resume routing snapshot should keep the current mission anchor'
|
|
314
318
|
assert routing['proposedMissionAnchor'] is None, 'no-discussion active bare /cook should not propose a replacement mission'
|
|
315
|
-
assert not chooser_path.exists(), 'active bare /cook resume should not open the chooser without a
|
|
319
|
+
assert not chooser_path.exists(), 'active bare /cook resume should not open the chooser without a fresh explicit handoff'
|
|
316
320
|
PY
|
|
317
321
|
|
|
318
322
|
PI_COMPLETION_SKIP_DRIVER_KICKOFF=1 \
|
|
@@ -329,10 +333,12 @@ expected_task_type = 'completion-workflow'
|
|
|
329
333
|
expected_eval_profile = 'completion-rubric-v1'
|
|
330
334
|
auto_resume = Path(sys.argv[1]).read_text()
|
|
331
335
|
|
|
336
|
+
state = __import__('json').loads(Path('.agent/state.json').read_text())
|
|
332
337
|
assert 'Resume the completion workflow from canonical state.' in auto_resume, 'auto-resume prompt should use the canonical resume workflow prompt'
|
|
333
338
|
assert 'Canonical routing profile:' in auto_resume, 'auto-resume prompt should expose canonical routing profile'
|
|
334
339
|
assert f'- task_type: {expected_task_type}' in auto_resume, 'auto-resume prompt missing canonical task_type'
|
|
335
340
|
assert f'- evaluation_profile: {expected_eval_profile}' in auto_resume, 'auto-resume prompt missing canonical evaluation_profile'
|
|
341
|
+
assert f'- workflow_session_id: {state["workflow_session_id"]}' in auto_resume, 'auto-resume prompt should expose canonical workflow_session_id'
|
|
336
342
|
PY
|
|
337
343
|
|
|
338
344
|
python3 - <<'PY'
|
|
@@ -383,54 +389,6 @@ active['evaluation_profile'] = profile['evaluation_profile']
|
|
|
383
389
|
active_path.write_text(json.dumps(active, indent=2) + '\n')
|
|
384
390
|
PY
|
|
385
391
|
|
|
386
|
-
python3 - <<'PY'
|
|
387
|
-
import json
|
|
388
|
-
from pathlib import Path
|
|
389
|
-
path = Path('.agent/startup-plan.json')
|
|
390
|
-
startup = json.loads(path.read_text())
|
|
391
|
-
startup.pop('task_type', None)
|
|
392
|
-
path.write_text(json.dumps(startup, indent=2) + '\n')
|
|
393
|
-
PY
|
|
394
|
-
|
|
395
|
-
if bash .agent/verify_completion_control_plane.sh >/dev/null 2>&1; then
|
|
396
|
-
echo "expected control-plane verification to fail when startup-plan.json omits task_type" >&2
|
|
397
|
-
exit 1
|
|
398
|
-
fi
|
|
399
|
-
|
|
400
|
-
python3 - <<'PY'
|
|
401
|
-
import json
|
|
402
|
-
from pathlib import Path
|
|
403
|
-
profile = json.loads(Path('.agent/profile.json').read_text())
|
|
404
|
-
startup_path = Path('.agent/startup-plan.json')
|
|
405
|
-
startup = json.loads(startup_path.read_text())
|
|
406
|
-
startup['task_type'] = profile['task_type']
|
|
407
|
-
startup_path.write_text(json.dumps(startup, indent=2) + '\n')
|
|
408
|
-
PY
|
|
409
|
-
|
|
410
|
-
python3 - <<'PY'
|
|
411
|
-
import json
|
|
412
|
-
from pathlib import Path
|
|
413
|
-
path = Path('.agent/startup-plan.json')
|
|
414
|
-
startup = json.loads(path.read_text())
|
|
415
|
-
startup['mission_anchor'] = 'drifted-startup-plan-mission'
|
|
416
|
-
path.write_text(json.dumps(startup, indent=2) + '\n')
|
|
417
|
-
PY
|
|
418
|
-
|
|
419
|
-
if bash .agent/verify_completion_control_plane.sh >/dev/null 2>&1; then
|
|
420
|
-
echo "expected control-plane verification to fail when startup-plan.json mission_anchor drifts from canonical workflow state" >&2
|
|
421
|
-
exit 1
|
|
422
|
-
fi
|
|
423
|
-
|
|
424
|
-
python3 - <<'PY'
|
|
425
|
-
import json
|
|
426
|
-
from pathlib import Path
|
|
427
|
-
state = json.loads(Path('.agent/state.json').read_text())
|
|
428
|
-
startup_path = Path('.agent/startup-plan.json')
|
|
429
|
-
startup = json.loads(startup_path.read_text())
|
|
430
|
-
startup['mission_anchor'] = state['mission_anchor']
|
|
431
|
-
startup_path.write_text(json.dumps(startup, indent=2) + '\n')
|
|
432
|
-
PY
|
|
433
|
-
|
|
434
392
|
python3 - <<'PY'
|
|
435
393
|
import json
|
|
436
394
|
from pathlib import Path
|
|
@@ -21,9 +21,8 @@ This skill defines shared protocol facts only. Role-specific behavior belongs in
|
|
|
21
21
|
## Shared Rules
|
|
22
22
|
|
|
23
23
|
- Current repo truth beats stale notes, stale summaries, and conversation memory.
|
|
24
|
-
- `startup-
|
|
25
|
-
- `
|
|
26
|
-
- `plan.json` is the persistent machine-readable slice backlog. Rebuild it during every re-grounding wave from repo truth plus the approved startup plan, and keep it truthful after every committed slice.
|
|
24
|
+
- `startup-brief.json` is the persistent machine-readable record of the confirmed `/cook` startup intent. It is canonical workflow intake, not the canonical slice plan.
|
|
25
|
+
- `plan.json` is the persistent machine-readable slice backlog. Rebuild it during every re-grounding wave and keep it truthful after every committed slice.
|
|
27
26
|
- `state.json` is the persistent machine-readable workflow controller. Keep `current_phase`, `continuation_policy`, `continuation_reason`, `next_mandatory_role`, and `next_mandatory_action` truthful after every transition.
|
|
28
27
|
- Every slice in `plan.json` must have non-empty `acceptance_criteria` — concrete, verifiable conditions that define done. A slice without acceptance criteria is invalid and must not be selected.
|
|
29
28
|
- Acceptance criteria are immutable after lock except for removing a criterion already satisfied with evidence or adding a missing criterion discovered during implementation.
|
|
@@ -78,7 +77,7 @@ If the workflow driver detects that the next mandatory action belongs to a compl
|
|
|
78
77
|
|
|
79
78
|
1. If tracked protocol contract files are missing or first-time onboarding is required, invoke `completion-bootstrapper`.
|
|
80
79
|
2. If canonical `.agent` execution state is missing, invalid, contradictory, stale, or ambiguous after compaction or recovery, invoke `completion-regrounder`.
|
|
81
|
-
3. If no slice is selected, invoke `completion-regrounder` to
|
|
80
|
+
3. If no slice is selected, invoke `completion-regrounder` to reconcile `.agent/plan.json` and return the next exact handoff payload.
|
|
82
81
|
4. If a slice is `selected` or `in_progress` and no new slice commit exists yet, invoke `completion-implementer`.
|
|
83
82
|
5. If the latest committed slice lacks a review result, invoke `completion-reviewer`.
|
|
84
83
|
6. If the latest committed slice lacks an audit result, invoke `completion-auditor`.
|
|
@@ -101,8 +100,7 @@ Tracked repo-contract files:
|
|
|
101
100
|
Ignored canonical execution-state files:
|
|
102
101
|
|
|
103
102
|
- `.agent/state.json`
|
|
104
|
-
- `.agent/startup-
|
|
105
|
-
- `.agent/startup-plan.md`
|
|
103
|
+
- `.agent/startup-brief.json`
|
|
106
104
|
- `.agent/plan.json`
|
|
107
105
|
- `.agent/active-slice.json`
|
|
108
106
|
- `.agent/slice-history.jsonl`
|
|
@@ -118,7 +116,7 @@ Read these when making completion decisions:
|
|
|
118
116
|
- `.agent/README.md`
|
|
119
117
|
- `.agent/profile.json`
|
|
120
118
|
- `.agent/state.json`
|
|
121
|
-
- `.agent/startup-
|
|
119
|
+
- `.agent/startup-brief.json`
|
|
122
120
|
- `.agent/plan.json`
|
|
123
121
|
- `.agent/active-slice.json`
|
|
124
122
|
- `.agent/slice-history.jsonl`
|
|
@@ -145,7 +143,6 @@ Canonical truth remains in `.agent/**`.
|
|
|
145
143
|
After context compaction, suspected memory loss, stalled-role recovery, or any ambiguous completion state, the workflow driver must re-read:
|
|
146
144
|
|
|
147
145
|
- `.agent/state.json`
|
|
148
|
-
- `.agent/startup-plan.json`
|
|
149
146
|
- `.agent/plan.json`
|
|
150
147
|
- `.agent/active-slice.json`
|
|
151
148
|
- `.agent/verification-evidence.json`
|
|
@@ -161,9 +158,11 @@ The workflow driver must invoke `completion-regrounder` before continuing whenev
|
|
|
161
158
|
|
|
162
159
|
The exact implementer handoff now includes implementation-scope surfaces and expected verification commands in addition to the locked slice goal, acceptance, notes, and before-slice counters.
|
|
163
160
|
|
|
161
|
+
At workflow start, treat `.agent/startup-brief.json` as the confirmed intent anchor that regrounding must reconcile against current repo truth before selecting slices.
|
|
162
|
+
|
|
164
163
|
The workflow driver must not continue implementation, review, audit, or stop evaluation from compacted conversation memory alone.
|
|
165
164
|
|
|
166
|
-
After compaction or recovery, `completion-implementer` must also re-read canonical `.agent/state.json`, `.agent/
|
|
165
|
+
After compaction or recovery, `completion-implementer` must also re-read canonical `.agent/state.json`, `.agent/plan.json`, `.agent/active-slice.json`, and `.agent/verification-evidence.json` before resuming work. If `.agent/active-slice.json` still contains a truthful exact handoff snapshot, continue from canonical state rather than asking the user to resend the original caller payload.
|
|
167
166
|
|
|
168
167
|
## Shared Report Header
|
|
169
168
|
|
|
@@ -13,8 +13,6 @@
|
|
|
13
13
|
## Ignored Canonical Execution State
|
|
14
14
|
|
|
15
15
|
- `.agent/state.json`
|
|
16
|
-
- `.agent/startup-plan.json`
|
|
17
|
-
- `.agent/startup-plan.md`
|
|
18
16
|
- `.agent/plan.json`
|
|
19
17
|
- `.agent/active-slice.json`
|
|
20
18
|
- `.agent/slice-history.jsonl`
|
|
@@ -30,7 +28,6 @@ Read these when making completion decisions:
|
|
|
30
28
|
- `.agent/README.md`
|
|
31
29
|
- `.agent/profile.json`
|
|
32
30
|
- `.agent/state.json`
|
|
33
|
-
- `.agent/startup-plan.json`
|
|
34
31
|
- `.agent/plan.json`
|
|
35
32
|
- `.agent/active-slice.json`
|
|
36
33
|
- `.agent/slice-history.jsonl`
|
|
@@ -133,37 +130,6 @@ Rules:
|
|
|
133
130
|
4. `continuation_policy == paused` means the user explicitly paused the workflow.
|
|
134
131
|
5. `continuation_policy == done` means canonical final stop reconciliation is complete and the workflow may stop.
|
|
135
132
|
|
|
136
|
-
## Fixed Startup Plan Model
|
|
137
|
-
|
|
138
|
-
`startup-plan.json` carries the approved workflow startup plan captured at `/cook`.
|
|
139
|
-
|
|
140
|
-
Required fields:
|
|
141
|
-
|
|
142
|
-
- `schema_version`
|
|
143
|
-
- `artifact_type` where the value is `completion-startup-plan`
|
|
144
|
-
- `status` where the value is `approved`
|
|
145
|
-
- `source`
|
|
146
|
-
- `captured_at`
|
|
147
|
-
- `mission_anchor`
|
|
148
|
-
- `goal_text`
|
|
149
|
-
- `task_type`
|
|
150
|
-
- `evaluation_profile`
|
|
151
|
-
- `scope`
|
|
152
|
-
- `constraints`
|
|
153
|
-
- `acceptance`
|
|
154
|
-
- `risks`
|
|
155
|
-
- `notes`
|
|
156
|
-
- `planned_surfaces`
|
|
157
|
-
- `verification_intent`
|
|
158
|
-
- `sequencing_hints`
|
|
159
|
-
|
|
160
|
-
Rules:
|
|
161
|
-
|
|
162
|
-
1. `startup-plan.json` is canonical startup intake, not canonical slice selection.
|
|
163
|
-
2. `completion-regrounder` must treat `startup-plan.json` as planning input, reconcile it against current repo truth, and derive canonical slices in `plan.json`.
|
|
164
|
-
3. `startup-plan.json` must stay aligned with the current canonical mission anchor in `.agent/state.json`, `.agent/plan.json`, and `.agent/active-slice.json` until a later `/cook` refocus or next-round startup rewrites it.
|
|
165
|
-
4. `startup-plan.md` is the human-readable rendering of the same approved startup plan and must remain in parity with `startup-plan.json`.
|
|
166
|
-
|
|
167
133
|
`plan.json` carries the ordered persistent slice backlog.
|
|
168
134
|
|
|
169
135
|
Required fields:
|
|
@@ -372,7 +338,7 @@ It must not, while a slice is selected or in progress:
|
|
|
372
338
|
|
|
373
339
|
1. If tracked protocol contract files are missing or first-time onboarding is required, invoke `completion-bootstrapper`.
|
|
374
340
|
2. If canonical `.agent` execution state is missing, stale, invalid, contradictory, or ambiguous after compaction or recovery, invoke `completion-regrounder` first.
|
|
375
|
-
3. If no slice is selected, invoke `completion-regrounder` to
|
|
341
|
+
3. If no slice is selected, invoke `completion-regrounder` to reconcile `.agent/plan.json` and return the next exact handoff payload.
|
|
376
342
|
4. If a slice is `selected` or `in_progress` and no new commit exists for it yet, invoke `completion-implementer`.
|
|
377
343
|
5. If the latest committed slice lacks review, invoke `completion-reviewer`.
|
|
378
344
|
6. If the latest committed slice lacks audit, invoke `completion-auditor`.
|
|
@@ -385,7 +351,6 @@ It must not, while a slice is selected or in progress:
|
|
|
385
351
|
After context compaction, suspected memory loss, stalled-role recovery, or any ambiguous completion state, the workflow root must re-read:
|
|
386
352
|
|
|
387
353
|
- `.agent/state.json`
|
|
388
|
-
- `.agent/startup-plan.json`
|
|
389
354
|
- `.agent/plan.json`
|
|
390
355
|
- `.agent/active-slice.json`
|
|
391
356
|
- `.agent/verification-evidence.json`
|
|
@@ -401,7 +366,7 @@ The workflow root must invoke `completion-regrounder` before continuing whenever
|
|
|
401
366
|
|
|
402
367
|
The workflow root must not continue implementation, review, audit, or stop evaluation from compacted conversation memory alone.
|
|
403
368
|
|
|
404
|
-
After compaction or recovery, `completion-implementer` must also re-read canonical `.agent/state.json`, `.agent/
|
|
369
|
+
After compaction or recovery, `completion-implementer` must also re-read canonical `.agent/state.json`, `.agent/plan.json`, `.agent/active-slice.json`, and `.agent/verification-evidence.json` before resuming work. If `.agent/active-slice.json` still contains a truthful exact handoff snapshot, continue from canonical state rather than asking the user to resend the original caller payload.
|
|
405
370
|
|
|
406
371
|
## Default Priority Policy
|
|
407
372
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: cook-handoff-boundary
|
|
3
|
-
description: Ordinary-chat contract for treating `/cook` as an optional workflow mode while requiring `/cook` to
|
|
3
|
+
description: Ordinary-chat contract for treating `/cook` as an optional workflow mode while requiring `/cook` to use primary-agent-authored handoff data instead of guessing from recent discussion.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# /cook Handoff Boundary
|
|
@@ -58,20 +58,22 @@ But even in those cases:
|
|
|
58
58
|
|
|
59
59
|
If the user explicitly runs or clearly chooses `/cook` workflow mode, the system behavior should be:
|
|
60
60
|
|
|
61
|
-
1.
|
|
62
|
-
2.
|
|
63
|
-
3.
|
|
61
|
+
1. check for a fresh explicit primary-agent `cook_handoff`
|
|
62
|
+
2. if none exists, call a primary-agent handoff synthesis step immediately from the current task context
|
|
63
|
+
3. use that handoff to show Start / Cancel confirmation in the same `/cook` entry
|
|
64
|
+
4. after Start, persist a canonical startup brief in `.agent/**` and treat workflow entry as active
|
|
65
|
+
5. let `completion-regrounder` turn that startup brief plus repo truth into canonical slices
|
|
64
66
|
|
|
65
67
|
That means:
|
|
66
68
|
|
|
67
|
-
- `/cook` must not infer or guess
|
|
68
|
-
- `/cook` should
|
|
69
|
-
- `/cook` should
|
|
70
|
-
- `/cook` should not require a manual rerun just to consume a
|
|
69
|
+
- `/cook` must not infer or guess the startup slice from recent discussion alone
|
|
70
|
+
- `/cook` should use primary-agent-authored handoff data
|
|
71
|
+
- `/cook` should persist the confirmed startup brief before regrounding begins
|
|
72
|
+
- `/cook` should not require a manual rerun just to consume a handoff it can synthesize immediately from the primary-agent view
|
|
71
73
|
|
|
72
74
|
## Optional Preview Behavior
|
|
73
75
|
|
|
74
|
-
Only if the user explicitly asks for a preview startup
|
|
76
|
+
Only if the user explicitly asks for a preview startup brief or handoff capsule in ordinary chat may the primary agent provide one.
|
|
75
77
|
|
|
76
78
|
Optional preview capsule format:
|
|
77
79
|
|
|
@@ -82,7 +84,7 @@ Optional preview capsule format:
|
|
|
82
84
|
"source": "primary_agent",
|
|
83
85
|
"captured_at": "<ISO-8601 timestamp>",
|
|
84
86
|
"source_turn_id": "<current assistant turn id>",
|
|
85
|
-
"mission": "<
|
|
87
|
+
"mission": "<startable implementation mission>",
|
|
86
88
|
"scope": ["..."],
|
|
87
89
|
"constraints": ["..."],
|
|
88
90
|
"non_goals": ["..."],
|
|
@@ -105,12 +107,12 @@ Optional preview capsule format:
|
|
|
105
107
|
Notes:
|
|
106
108
|
|
|
107
109
|
- `constraints` may be replaced or supplemented by `non_goals` when clearer.
|
|
108
|
-
- `first_slice_goal`, `first_slice_non_goals`, `implementation_surfaces`, `verification_commands`, and `why_this_slice_first` are
|
|
109
|
-
- Any capsule is
|
|
110
|
+
- `first_slice_goal`, `first_slice_non_goals`, `implementation_surfaces`, `verification_commands`, and `why_this_slice_first` are required for an implementation-ready handoff.
|
|
111
|
+
- Any capsule is startup intake for `/cook` only. It is not canonical `.agent/**` state, not active-slice state, and not a second repo contract source.
|
|
110
112
|
|
|
111
113
|
Suggested wording:
|
|
112
114
|
|
|
113
|
-
> We can continue directly in ordinary chat if you want. If you prefer workflow mode, run `/cook` and it should
|
|
115
|
+
> We can continue directly in ordinary chat if you want. If you prefer workflow mode, run `/cook` and it should use a primary-agent handoff for Start / Cancel confirmation rather than guessing from recent discussion.
|
|
114
116
|
|
|
115
117
|
## Forbidden Behaviors
|
|
116
118
|
|
|
@@ -125,14 +127,13 @@ Before the user explicitly runs `/cook`, the primary agent must not:
|
|
|
125
127
|
|
|
126
128
|
When the user does explicitly choose `/cook`, the system must not:
|
|
127
129
|
|
|
128
|
-
- let `/cook` invent
|
|
129
|
-
- let `/cook` replace missing
|
|
130
|
-
-
|
|
131
|
-
- require a second `/cook` invocation when same-entry primary-agent startup-plan synthesis is possible
|
|
130
|
+
- let `/cook` invent the startup mission from recent discussion alone
|
|
131
|
+
- let `/cook` replace missing handoff data with generic transcript guessing
|
|
132
|
+
- require a second `/cook` invocation when same-entry primary-agent handoff synthesis is possible
|
|
132
133
|
|
|
133
134
|
## Relationship To `completion-protocol`
|
|
134
135
|
|
|
135
|
-
This skill is only about pre-`/cook` ordinary-chat behavior and `/cook`
|
|
136
|
+
This skill is only about pre-`/cook` ordinary-chat behavior and `/cook` handoff expectations.
|
|
136
137
|
|
|
137
138
|
After the user explicitly enters `/cook`, the separate `completion-protocol` skill governs:
|
|
138
139
|
|