@linimin/pi-letscook 0.1.37 → 0.1.40

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.
@@ -2,6 +2,9 @@
2
2
  set -euo pipefail
3
3
 
4
4
  PKG_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
5
+ pi() {
6
+ command pi --no-extensions "$@"
7
+ }
5
8
  TMPDIR="$(mktemp -d)"
6
9
  trap 'rm -rf "$TMPDIR"' EXIT
7
10
 
@@ -2,6 +2,9 @@
2
2
  set -euo pipefail
3
3
 
4
4
  PKG_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
5
+ pi() {
6
+ command pi --no-extensions "$@"
7
+ }
5
8
  TMPDIR="$(mktemp -d)"
6
9
  trap 'rm -rf "$TMPDIR"' EXIT
7
10
 
@@ -47,7 +50,13 @@ PY
47
50
  cd "$TMPDIR"
48
51
  git init -q
49
52
 
50
- pi -e "$PKG_ROOT" -p "/cook smoke-test mission" >"$TMPDIR/pi-completion-refocus-bootstrap.out" 2>"$TMPDIR/pi-completion-refocus-bootstrap.err" &
53
+ BOOTSTRAP_SESSION="$TMPDIR/session-bootstrap.jsonl"
54
+ BOOTSTRAP_DISCUSSION=$'Mission: Smoke-test mission.\nScope:\n- Bootstrap a completion workflow for the refocus regression fixture.\nConstraints:\n- Use supported bare /cook discussion flow only.\nAcceptance:\n- Materialize canonical state for active-workflow refocus tests.'
55
+ write_session "$BOOTSTRAP_SESSION" "$TMPDIR" "$BOOTSTRAP_DISCUSSION"
56
+
57
+ PI_COMPLETION_CONTEXT_PROPOSAL_ACTION=accept \
58
+ PI_COMPLETION_DISABLE_CONTEXT_PROPOSAL_ANALYST=1 \
59
+ pi --session "$BOOTSTRAP_SESSION" -e "$PKG_ROOT" -p "/cook" >"$TMPDIR/pi-completion-refocus-bootstrap.out" 2>"$TMPDIR/pi-completion-refocus-bootstrap.err" &
51
60
  PI_PID=$!
52
61
  for _ in $(seq 1 60); do
53
62
  if [[ -f .agent/profile.json && -f .agent/state.json && -f .agent/plan.json && -f .agent/active-slice.json ]]; then
@@ -73,45 +82,78 @@ print(state['mission_anchor'])
73
82
  PY
74
83
  )"
75
84
 
76
- CHOOSER_SNAPSHOT="$TMPDIR/existing-workflow-chooser.json"
85
+ INLINE_REJECTION_ROUTING="$TMPDIR/inline-arg-routing.json"
86
+ INLINE_REJECTION_PROPOSAL="$TMPDIR/inline-arg-proposal.json"
87
+ INLINE_REJECTION_CHOOSER="$TMPDIR/inline-arg-chooser.json"
88
+ INLINE_REJECTION_BASELINE="$TMPDIR/inline-arg-before.json"
89
+ python3 - "$INLINE_REJECTION_BASELINE" <<'PY'
90
+ import json
91
+ import sys
92
+ from pathlib import Path
93
+
94
+ tracked = [
95
+ Path('.agent/mission.md'),
96
+ Path('.agent/profile.json'),
97
+ Path('.agent/state.json'),
98
+ Path('.agent/plan.json'),
99
+ Path('.agent/active-slice.json'),
100
+ Path('.agent/verification-evidence.json'),
101
+ ]
102
+ Path(sys.argv[1]).write_text(json.dumps({path.name: path.read_text() for path in tracked}, indent=2) + '\n')
103
+ PY
104
+
77
105
  PI_COMPLETION_EXISTING_WORKFLOW_ACTION=cancel \
78
- PI_COMPLETION_TEST_EXISTING_WORKFLOW_CHOOSER_PATH="$CHOOSER_SNAPSHOT" \
106
+ PI_COMPLETION_TEST_ACTIVE_WORKFLOW_ROUTING_PATH="$INLINE_REJECTION_ROUTING" \
107
+ PI_COMPLETION_TEST_CONTEXT_PROPOSAL_PATH="$INLINE_REJECTION_PROPOSAL" \
108
+ PI_COMPLETION_TEST_EXISTING_WORKFLOW_CHOOSER_PATH="$INLINE_REJECTION_CHOOSER" \
79
109
  PI_COMPLETION_SKIP_DRIVER_KICKOFF=1 \
80
110
  pi -e "$PKG_ROOT" -p "/cook replacement mission that should stay in the main chat" \
81
- >"$TMPDIR/pi-completion-refocus-cancel.out" 2>"$TMPDIR/pi-completion-refocus-cancel.err"
111
+ >"$TMPDIR/pi-completion-refocus-inline-arg.out" 2>"$TMPDIR/pi-completion-refocus-inline-arg.err"
82
112
 
83
- python3 - "$CHOOSER_SNAPSHOT" "$TMPDIR/pi-completion-refocus-cancel.out" "$TMPDIR/pi-completion-refocus-cancel.err" "$INITIAL_MISSION" <<'PY'
113
+ python3 - "$TMPDIR/pi-completion-refocus-inline-arg.out" "$TMPDIR/pi-completion-refocus-inline-arg.err" "$INLINE_REJECTION_ROUTING" "$INLINE_REJECTION_PROPOSAL" "$INLINE_REJECTION_CHOOSER" "$INITIAL_MISSION" "$INLINE_REJECTION_BASELINE" <<'PY'
84
114
  import json
85
115
  import sys
86
116
  from pathlib import Path
87
117
 
88
- chooser = json.loads(Path(sys.argv[1]).read_text())
89
- output = Path(sys.argv[2]).read_text() + Path(sys.argv[3]).read_text()
90
- initial_mission = sys.argv[4]
91
- state = json.loads(Path('.agent/state.json').read_text())
92
- plan = json.loads(Path('.agent/plan.json').read_text())
93
- active = json.loads(Path('.agent/active-slice.json').read_text())
94
-
95
- assert state['mission_anchor'] == initial_mission, 'cancelled chooser should keep the current mission anchor'
96
- assert plan['mission_anchor'] == initial_mission, 'cancelled chooser should keep plan.json unchanged'
97
- assert active['mission_anchor'] == initial_mission, 'cancelled chooser should keep active-slice.json unchanged'
98
- assert chooser['title'].startswith('Existing completion workflow found'), 'chooser snapshot should describe the existing-workflow prompt'
99
- assert chooser['choices'][0].startswith('Continue current workflow'), 'chooser should keep the continue option'
100
- assert chooser['choices'][1].startswith('Abandon current workflow and start this new one'), 'chooser should keep the explicit-goal refocus option'
101
- assert 'Start/Cancel confirmation' in chooser['choices'][1], 'chooser should mention the approval-only replacement confirmation'
102
- assert chooser['choices'][2].startswith('Cancel'), 'chooser should keep the cancel option'
103
- assert 'Discuss changes in the main chat and rerun /cook.' in chooser['choices'][2], 'chooser cancel copy should redirect users back to the main chat and rerun /cook'
104
- assert 'Discuss changes in the main chat and rerun /cook.' in output, 'chooser cancel output should redirect users back to the main chat and rerun /cook'
118
+ output = Path(sys.argv[1]).read_text() + Path(sys.argv[2]).read_text()
119
+ routing = Path(sys.argv[3])
120
+ proposal = Path(sys.argv[4])
121
+ chooser = Path(sys.argv[5])
122
+ initial_mission = sys.argv[6]
123
+ before = json.loads(Path(sys.argv[7]).read_text())
124
+ tracked = [
125
+ Path('.agent/mission.md'),
126
+ Path('.agent/profile.json'),
127
+ Path('.agent/state.json'),
128
+ Path('.agent/plan.json'),
129
+ Path('.agent/active-slice.json'),
130
+ Path('.agent/verification-evidence.json'),
131
+ ]
132
+ current_state = json.loads(before['state.json'])
133
+ assert current_state['mission_anchor'] == initial_mission, 'active inline /cook args should start from the current mission anchor'
134
+ assert 'Inline /cook arguments are no longer supported.' in output, 'active inline /cook args should explain the hard rejection'
135
+ assert 'Clarify the mission in the main chat and rerun bare /cook.' in output, 'active inline /cook args should redirect users back to main chat plus bare /cook'
136
+ assert not routing.exists(), 'active inline /cook args should not run active-workflow routing'
137
+ assert not proposal.exists(), 'active inline /cook args should not open proposal confirmation'
138
+ assert not chooser.exists(), 'active inline /cook args should not open the existing-workflow chooser'
139
+ after = {path.name: path.read_text() for path in tracked}
140
+ assert before == after, 'active inline /cook args should leave canonical files unchanged'
105
141
  PY
106
142
 
107
- EXPLICIT_ROUTING_SNAPSHOT="$TMPDIR/explicit-goal-routing.json"
143
+ SESSION_INITIAL_REFOCUS="$TMPDIR/session-initial-bare-refocus.jsonl"
144
+ INITIAL_REFOCUS_DISCUSSION=$'Mission: Remove completion status line, keep widget.\nScope:\n- Replace the initial smoke-test workflow with the widget mission.\nConstraints:\n- Keep the approval-only Start/Cancel refocus gate.\nAcceptance:\n- Rewrite canonical state only after the replacement mission is approved.'
145
+ INITIAL_REFOCUS_ROUTING="$TMPDIR/initial-bare-refocus-routing.json"
146
+ write_session "$SESSION_INITIAL_REFOCUS" "$TMPDIR" "$INITIAL_REFOCUS_DISCUSSION"
147
+
148
+ PI_COMPLETION_DISABLE_CONTEXT_PROPOSAL_ANALYST=1 \
108
149
  PI_COMPLETION_EXISTING_WORKFLOW_ACTION=refocus \
109
- PI_COMPLETION_TEST_ACTIVE_WORKFLOW_ROUTING_PATH="$EXPLICIT_ROUTING_SNAPSHOT" \
150
+ PI_COMPLETION_CONTEXT_PROPOSAL_ACTION=accept \
151
+ PI_COMPLETION_TEST_ACTIVE_WORKFLOW_ROUTING_PATH="$INITIAL_REFOCUS_ROUTING" \
110
152
  PI_COMPLETION_SKIP_DRIVER_KICKOFF=1 \
111
- pi -e "$PKG_ROOT" -p "/cook Remove completion status line, keep widget" \
153
+ pi --session "$SESSION_INITIAL_REFOCUS" -e "$PKG_ROOT" -p "/cook" \
112
154
  >"$TMPDIR/pi-completion-refocus.out" 2>"$TMPDIR/pi-completion-refocus.err"
113
155
 
114
- python3 - "$EXPLICIT_ROUTING_SNAPSHOT" <<'PY'
156
+ python3 - "$INITIAL_REFOCUS_ROUTING" <<'PY'
115
157
  import json
116
158
  import sys
117
159
  from pathlib import Path
@@ -144,10 +186,12 @@ assert state['next_mandatory_role'] == 'completion-regrounder', 'next_mandatory_
144
186
  assert state['continuation_reason'].startswith('User refocused workflow via /cook:'), 'continuation_reason should record the refocus'
145
187
  assert plan['plan_basis'] == 'user_refocus', 'plan.json plan_basis should be user_refocus after refocus'
146
188
  assert active['status'] == 'idle', 'active-slice.json status should reset to idle after refocus'
147
- assert routing['mode'] == 'explicit', 'explicit /cook <goal> should use explicit active-workflow routing mode'
148
- assert routing['action'] == 'refocus', 'explicit /cook <goal> should classify as refocus when the mission changes'
149
- assert routing['reason'] == 'explicit_goal', 'explicit /cook <goal> should record the explicit-goal routing reason'
150
- assert routing['proposedMissionAnchor'] == new_anchor, 'explicit routing snapshot should expose the replacement mission anchor'
189
+ assert routing['mode'] == 'bare', 'supported refocus should use bare active-workflow routing mode'
190
+ assert 'explicitGoal' not in routing, 'supported bare refocus should not expose removed explicit-goal shim fields'
191
+ assert 'explicitGoalProvided' not in routing, 'supported bare refocus should not expose removed explicit-goal shim fields'
192
+ assert routing['action'] == 'refocus', 'supported bare /cook should classify as refocus when the mission changes'
193
+ assert routing['reason'] == 'clear_refocus', 'supported bare /cook should record the clear-refocus routing reason'
194
+ assert routing['proposedMissionAnchor'] == new_anchor, 'bare refocus routing snapshot should expose the replacement mission anchor'
151
195
  PY
152
196
 
153
197
  UPDATED_MISSION="$(python3 - <<'PY'
@@ -159,7 +203,7 @@ PY
159
203
  )"
160
204
 
161
205
  if [[ "$INITIAL_MISSION" == "$UPDATED_MISSION" ]]; then
162
- echo "expected mission anchor to change during explicit refocus" >&2
206
+ echo "expected mission anchor to change during supported bare refocus" >&2
163
207
  exit 1
164
208
  fi
165
209
 
@@ -198,6 +242,8 @@ assert state['mission_anchor'] == updated_mission, 'chooser cancel should keep t
198
242
  assert plan['mission_anchor'] == updated_mission, 'chooser cancel should keep plan.json unchanged'
199
243
  assert active['mission_anchor'] == updated_mission, 'chooser cancel should keep active-slice.json unchanged'
200
244
  assert routing['mode'] == 'bare', 'bare /cook should snapshot bare active-workflow routing mode'
245
+ assert 'explicitGoal' not in routing, 'bare chooser routing should not expose removed explicit-goal shim fields'
246
+ assert 'explicitGoalProvided' not in routing, 'bare chooser routing should not expose removed explicit-goal shim fields'
201
247
  assert routing['action'] == 'refocus', 'clear structured discussion should classify active bare /cook as refocus'
202
248
  assert routing['reason'] == 'clear_refocus', 'clear structured discussion should record the clear-refocus routing reason'
203
249
  assert routing['currentMissionAnchor'] == updated_mission, 'clear-refocus routing should keep the current mission anchor until the user approves replacement'
@@ -280,6 +326,8 @@ active = json.loads(Path('.agent/active-slice.json').read_text())
280
326
 
281
327
  assert proposal['mission'] == new_anchor, 'accepted bare refocus should preserve the replacement proposal mission'
282
328
  assert routing['mode'] == 'bare', 'accepted bare refocus should keep bare routing mode'
329
+ assert 'explicitGoal' not in routing, 'accepted bare refocus should not expose removed explicit-goal shim fields'
330
+ assert 'explicitGoalProvided' not in routing, 'accepted bare refocus should not expose removed explicit-goal shim fields'
283
331
  assert routing['action'] == 'refocus', 'accepted bare refocus should keep the clear-refocus classification'
284
332
  assert routing['reason'] == 'clear_refocus', 'accepted bare refocus should keep the clear-refocus reason'
285
333
  assert routing['currentMissionAnchor'] == 'Remove completion status line, keep widget.', 'accepted bare refocus should expose the original mission until Start is accepted'
@@ -4,40 +4,74 @@ set -euo pipefail
4
4
  ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
5
5
  cd "$ROOT"
6
6
 
7
- echo "[release-check] running control-plane validation, public /cook parity, startup/refocus/context regressions, canonical evidence artifact, active-slice contract, observability, evaluator calibration, and rubric contract coverage"
7
+ echo "[release-check] running control-plane validation, bare /cook parity, startup/refocus/context regressions, canonical evidence artifact, active-slice contract, observability, evaluator calibration, and rubric contract coverage"
8
8
  bash .agent/verify_completion_control_plane.sh
9
9
 
10
- echo "[release-check] verifying public /cook single-command parity"
10
+ echo "[release-check] verifying public bare /cook parity"
11
11
  python3 - <<'PY'
12
+ import re
12
13
  from pathlib import Path
13
14
 
14
15
  checks = {
15
16
  "README.md": [
16
- "Bare `/cook` is now the primary workflow entrypoint.",
17
- "`/cook <text>` is still supported as a temporary compatibility shim",
17
+ "Bare `/cook` is the only supported workflow entrypoint.",
18
+ "clarify the mission in the main chat before rerunning bare `/cook`",
18
19
  "Matching or unclear discussion resumes from canonical `.agent/**` state.",
19
20
  "approval-only Start/Cancel gate",
20
21
  "Start new workflow from recent discussion",
21
22
  "fails closed instead of guessing",
23
+ "README/CHANGELOG updates still count as concrete repo changes",
24
+ "assistant-produced summaries and plan/spec/design-doc/proposal-only artifacts do not",
25
+ "Assistant/summary artifacts or plan/spec/design-doc/proposal-only context do not refocus the workflow.",
22
26
  ],
23
27
  "CHANGELOG.md": [
24
- "single public discussion-first workflow command",
25
- "temporary compatibility shim",
26
- "approval-only Start/Cancel gate",
27
- "fail-closed ambiguous-discussion behavior",
28
- "release-gated public-parity assertions",
28
+ "bare `/cook` as the only supported workflow entrypoint",
29
+ "clarify the mission before rerunning bare `/cook`",
30
+ "packaged parity now fails closed on the bare-only contract",
31
+ "that old inline-argument path is no longer supported now that bare `/cook` is the only public entrypoint",
32
+ "README/CHANGELOG/docs-only deliverables as concrete repo-change missions",
33
+ "ignore assistant/branch/compaction summary artifacts for startup/refocus readiness",
34
+ "plan/spec/design-doc/proposal-only context without rewriting canonical state",
29
35
  ],
30
36
  "extensions/completion/index.ts": [
31
37
  'description: "Discussion-driven /cook workflow: start, continue, refocus, or start the next round"',
32
- "temporary compatibility shim, pass /cook <text>",
38
+ "Inline /cook arguments are no longer supported. Clarify the mission in the main chat and rerun bare /cook.",
39
+ "Bare /cook failed closed because recent discussion did not contain a clear execution-ready Mission/Scope/Constraints/Acceptance proposal for concrete repo changes. Clarify the concrete repo changes in the main chat and rerun bare /cook.",
33
40
  ],
34
41
  }
35
42
 
43
+ forbidden = {
44
+ "README.md": ["compatibility" + " shim"],
45
+ "CHANGELOG.md": ["compatibility" + " shim"],
46
+ "extensions/completion/index.ts": ["temporary" + " compatibility" + " shim, pass /cook"],
47
+ }
48
+
49
+ public_doc_paths = [
50
+ Path("README.md"),
51
+ Path("CHANGELOG.md"),
52
+ Path("PUBLISHING.md"),
53
+ ]
54
+ inline_cook_pattern = re.compile(r"/cook\s*<[^>]+>")
55
+
36
56
  for path, needles in checks.items():
37
57
  text = Path(path).read_text()
38
58
  for needle in needles:
39
59
  if needle not in text:
40
- raise SystemExit(f"[release-check] missing expected public /cook parity text in {path}: {needle}")
60
+ raise SystemExit(f"[release-check] missing expected bare /cook parity text in {path}: {needle}")
61
+
62
+ for path, needles in forbidden.items():
63
+ text = Path(path).read_text()
64
+ for needle in needles:
65
+ if needle in text:
66
+ raise SystemExit(f"[release-check] found stale compatibility wording in {path}: {needle}")
67
+
68
+ for path in public_doc_paths:
69
+ text = path.read_text()
70
+ match = inline_cook_pattern.search(text)
71
+ if match:
72
+ raise SystemExit(
73
+ f"[release-check] found unsupported inline /cook syntax in {path}: {match.group(0)}"
74
+ )
41
75
  PY
42
76
 
43
77
  npm run smoke-test
@@ -2,23 +2,98 @@
2
2
  set -euo pipefail
3
3
 
4
4
  PKG_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
5
+ pi() {
6
+ command pi --no-extensions "$@"
7
+ }
5
8
  TMPDIR="$(mktemp -d)"
6
9
  trap 'rm -rf "$TMPDIR"' EXIT
7
10
 
11
+ write_session() {
12
+ local session_path="$1"
13
+ local cwd="$2"
14
+ local text="$3"
15
+ python3 - "$session_path" "$cwd" "$text" <<'PY'
16
+ import json
17
+ import sys
18
+ from pathlib import Path
19
+
20
+ session_path = Path(sys.argv[1])
21
+ cwd = sys.argv[2]
22
+ text = sys.argv[3]
23
+ session_path.parent.mkdir(parents=True, exist_ok=True)
24
+ entries = [
25
+ {
26
+ "type": "session",
27
+ "version": 3,
28
+ "id": "11111111-1111-4111-8111-111111111111",
29
+ "timestamp": "2026-01-01T00:00:00.000Z",
30
+ "cwd": cwd,
31
+ },
32
+ {
33
+ "type": "message",
34
+ "id": "a1b2c3d4",
35
+ "parentId": None,
36
+ "timestamp": "2026-01-01T00:00:01.000Z",
37
+ "message": {
38
+ "role": "user",
39
+ "content": text,
40
+ "timestamp": 1767225601000,
41
+ },
42
+ },
43
+ ]
44
+ with session_path.open('w', encoding='utf-8') as fh:
45
+ for entry in entries:
46
+ fh.write(json.dumps(entry, ensure_ascii=False) + "\n")
47
+ PY
48
+ }
49
+
8
50
  ROOT="$TMPDIR/repo"
9
51
  KICKOFF_PROMPT="$TMPDIR/kickoff-prompt.txt"
10
52
  RESUME_PROMPT="$TMPDIR/resume-prompt.txt"
11
53
  UNCLEAR_ROUTING_SNAPSHOT="$TMPDIR/active-unclear-routing.json"
12
54
  UNCLEAR_CHOOSER_SNAPSHOT="$TMPDIR/unexpected-existing-workflow-chooser.json"
13
55
  AUTO_RESUME_PROMPT="$TMPDIR/auto-resume-prompt.txt"
56
+ INLINE_REJECTION_ROUTING_SNAPSHOT="$TMPDIR/inline-arg-routing.json"
57
+ INLINE_REJECTION_PROPOSAL_SNAPSHOT="$TMPDIR/inline-arg-proposal.json"
58
+ INLINE_REJECTION_CHOOSER_SNAPSHOT="$TMPDIR/inline-arg-chooser.json"
59
+ BOOTSTRAP_SESSION="$TMPDIR/session-smoke-bootstrap.jsonl"
60
+ BOOTSTRAP_DISCUSSION=$'Mission: Exercise smoke-test bootstrap.\nScope:\n- Materialize the canonical completion control-plane files.\n- Keep the smoke test on supported bare /cook behavior.\nConstraints:\n- Do not rely on inline /cook arguments.\nAcceptance:\n- Scaffold canonical files and kickoff prompts for the smoke fixture.'
14
61
 
15
62
  mkdir -p "$ROOT"
16
63
  cd "$ROOT"
17
64
  git init -q
18
65
 
19
66
  PI_COMPLETION_SKIP_DRIVER_KICKOFF=1 \
20
- PI_COMPLETION_TEST_DRIVER_PROMPT_PATH="$KICKOFF_PROMPT" \
67
+ PI_COMPLETION_TEST_ACTIVE_WORKFLOW_ROUTING_PATH="$INLINE_REJECTION_ROUTING_SNAPSHOT" \
68
+ PI_COMPLETION_TEST_CONTEXT_PROPOSAL_PATH="$INLINE_REJECTION_PROPOSAL_SNAPSHOT" \
69
+ PI_COMPLETION_TEST_EXISTING_WORKFLOW_CHOOSER_PATH="$INLINE_REJECTION_CHOOSER_SNAPSHOT" \
21
70
  pi -e "$PKG_ROOT" -p "/cook smoke-test mission" \
71
+ >"$TMPDIR/pi-completion-smoke-inline-arg.out" 2>"$TMPDIR/pi-completion-smoke-inline-arg.err"
72
+
73
+ python3 - "$TMPDIR/pi-completion-smoke-inline-arg.out" "$TMPDIR/pi-completion-smoke-inline-arg.err" "$INLINE_REJECTION_ROUTING_SNAPSHOT" "$INLINE_REJECTION_PROPOSAL_SNAPSHOT" "$INLINE_REJECTION_CHOOSER_SNAPSHOT" <<'PY'
74
+ import sys
75
+ from pathlib import Path
76
+
77
+ output = Path(sys.argv[1]).read_text() + Path(sys.argv[2]).read_text()
78
+ routing = Path(sys.argv[3])
79
+ proposal = Path(sys.argv[4])
80
+ chooser = Path(sys.argv[5])
81
+
82
+ assert not Path('.agent').exists(), 'startup inline /cook args should fail closed without creating canonical state'
83
+ assert not routing.exists(), 'startup inline /cook args should not open active-workflow routing'
84
+ assert not proposal.exists(), 'startup inline /cook args should not open the proposal confirmation flow'
85
+ assert not chooser.exists(), 'startup inline /cook args should not open the chooser flow'
86
+ assert 'Inline /cook arguments are no longer supported.' in output, 'startup inline /cook args should explain the hard rejection'
87
+ assert 'Clarify the mission in the main chat and rerun bare /cook.' in output, 'startup inline /cook args should redirect users back to main chat plus bare /cook'
88
+ PY
89
+
90
+ write_session "$BOOTSTRAP_SESSION" "$ROOT" "$BOOTSTRAP_DISCUSSION"
91
+
92
+ PI_COMPLETION_CONTEXT_PROPOSAL_ACTION=accept \
93
+ PI_COMPLETION_DISABLE_CONTEXT_PROPOSAL_ANALYST=1 \
94
+ PI_COMPLETION_SKIP_DRIVER_KICKOFF=1 \
95
+ PI_COMPLETION_TEST_DRIVER_PROMPT_PATH="$KICKOFF_PROMPT" \
96
+ pi --session "$BOOTSTRAP_SESSION" -e "$PKG_ROOT" -p "/cook" \
22
97
  >"$TMPDIR/pi-completion-smoke-bootstrap.out" 2>"$TMPDIR/pi-completion-smoke-bootstrap.err"
23
98
 
24
99
  for file in .agent/profile.json .agent/state.json .agent/plan.json .agent/active-slice.json .agent/verification-evidence.json; do