@linimin/pi-letscook 0.1.66 → 0.1.67
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 +4 -0
- package/.agent/verify_completion_control_plane.sh +34 -0
- package/CHANGELOG.md +9 -0
- package/README.md +26 -21
- package/agents/completion-bootstrapper.md +2 -1
- package/agents/completion-regrounder.md +16 -10
- package/extensions/completion/driver.ts +66 -17
- package/extensions/completion/index.ts +96 -21
- package/extensions/completion/prompt-surfaces.ts +156 -15
- package/extensions/completion/proposal.ts +21 -21
- package/extensions/completion/role-runner.ts +11 -10
- package/extensions/completion/state-store.ts +87 -2
- package/extensions/completion/types.ts +3 -0
- package/package.json +1 -1
- package/scripts/active-slice-contract-test.sh +1 -1
- package/scripts/canonical-evidence-artifact-test.sh +49 -4
- package/scripts/context-proposal-test.sh +57 -58
- package/scripts/refocus-test.sh +17 -17
- package/scripts/release-check.sh +11 -11
- package/scripts/smoke-test.sh +69 -9
- package/skills/completion-protocol/SKILL.md +9 -3
- package/skills/completion-protocol/references/completion.md +37 -2
- package/skills/cook-handoff-boundary/SKILL.md +16 -16
|
@@ -147,7 +147,7 @@ mkdir -p "$ROOT"
|
|
|
147
147
|
cd "$ROOT"
|
|
148
148
|
git init -q
|
|
149
149
|
|
|
150
|
-
# No workflow yet: bare /cook should be able to generate a primary-agent
|
|
150
|
+
# No workflow yet: bare /cook should be able to generate a primary-agent startup plan in the same entry,
|
|
151
151
|
# then continue directly to startup confirmation.
|
|
152
152
|
SESSION_ZERO="$TMPDIR/session-zero.jsonl"
|
|
153
153
|
DISCUSSION_ZERO=$'Mission: Remove the completion status line while keeping the completion widget.
|
|
@@ -178,7 +178,7 @@ capsule = {
|
|
|
178
178
|
"Keep observability regression coverage truthful."
|
|
179
179
|
],
|
|
180
180
|
"risks": [],
|
|
181
|
-
"notes": ["Generated by the primary-agent
|
|
181
|
+
"notes": ["Generated by the primary-agent startup-plan step triggered from /cook."],
|
|
182
182
|
"handoff_kind": "implementation_workflow_handoff",
|
|
183
183
|
"first_slice_goal": "Remove the completion status line while preserving the widget behavior.",
|
|
184
184
|
"first_slice_non_goals": ["Do not reintroduce another status surface."],
|
|
@@ -203,13 +203,13 @@ from pathlib import Path
|
|
|
203
203
|
|
|
204
204
|
output = Path(sys.argv[1]).read_text() + Path(sys.argv[2]).read_text()
|
|
205
205
|
snapshot = Path(sys.argv[3])
|
|
206
|
-
assert Path('.agent').exists(), 'primary-agent
|
|
207
|
-
assert snapshot.exists(), 'primary-agent
|
|
206
|
+
assert Path('.agent').exists(), 'primary-agent startup-plan generation should scaffold canonical state in the same /cook entry'
|
|
207
|
+
assert snapshot.exists(), 'primary-agent startup-plan generation should emit a startup proposal snapshot'
|
|
208
208
|
proposal = json.loads(snapshot.read_text())
|
|
209
209
|
brief = json.loads(Path('.agent/state.json').read_text())['advisory_startup_brief']
|
|
210
|
-
assert proposal['source'] == 'handoff_capsule', 'generated primary-agent
|
|
211
|
-
assert brief['source'] == 'primary_agent_handoff', 'generated primary-agent
|
|
212
|
-
assert 'Initialized completion control plane' in output, 'same-entry primary-agent
|
|
210
|
+
assert proposal['source'] == 'handoff_capsule', 'generated primary-agent startup plan should be consumed as handoff-capsule startup source'
|
|
211
|
+
assert brief['source'] == 'primary_agent_handoff', 'generated primary-agent startup plan should record primary_agent_handoff advisory intake'
|
|
212
|
+
assert 'Initialized completion control plane' in output, 'same-entry primary-agent startup-plan generation should initialize canonical workflow state'
|
|
213
213
|
PY
|
|
214
214
|
|
|
215
215
|
rm -rf .agent
|
|
@@ -258,7 +258,7 @@ output = Path(sys.argv[1]).read_text() + Path(sys.argv[2]).read_text()
|
|
|
258
258
|
snapshot = Path(sys.argv[3])
|
|
259
259
|
assert not Path('.agent').exists(), 'user-authored faux handoff without supporting discussion should still fail closed without writing canonical state'
|
|
260
260
|
assert not snapshot.exists(), 'user-authored faux handoff should not emit a startup proposal snapshot'
|
|
261
|
-
assert '
|
|
261
|
+
assert 'startup-plan step could not prepare a concrete workflow startup plan' in output, 'user-authored faux handoff should fail closed when the startup-plan step yields no plan'
|
|
262
262
|
PY
|
|
263
263
|
|
|
264
264
|
# No workflow yet: malformed or invalid assistant handoff capsules must also fail closed.
|
|
@@ -280,10 +280,10 @@ output = Path(sys.argv[1]).read_text() + Path(sys.argv[2]).read_text()
|
|
|
280
280
|
snapshot = Path(sys.argv[3])
|
|
281
281
|
assert not Path('.agent').exists(), 'invalid assistant handoff without supporting discussion should fail closed without writing canonical state'
|
|
282
282
|
assert not snapshot.exists(), 'invalid assistant handoff should not emit a startup proposal snapshot'
|
|
283
|
-
assert '
|
|
283
|
+
assert 'startup-plan step could not prepare a concrete workflow startup plan' in output, 'invalid assistant handoff should fail closed when no valid startup plan can be prepared'
|
|
284
284
|
PY
|
|
285
285
|
|
|
286
|
-
# No workflow yet: a fresh explicit primary-agent
|
|
286
|
+
# No workflow yet: a fresh explicit primary-agent startup-plan preview should still bootstrap canonical startup state.
|
|
287
287
|
SESSION_ONE="$TMPDIR/session-one.jsonl"
|
|
288
288
|
HANDOFF_SNAPSHOT_ONE="$TMPDIR/context-proposal-explicit-startup.json"
|
|
289
289
|
HANDOFF_MESSAGES_ONE="$(python3 - <<'PY'
|
|
@@ -309,7 +309,7 @@ capsule = {
|
|
|
309
309
|
"Stale widget-removal discussion could broaden the startup plan if the handoff is ignored."
|
|
310
310
|
],
|
|
311
311
|
"notes": [
|
|
312
|
-
"Keep the startup
|
|
312
|
+
"Keep the startup plan aligned with the explicit primary-agent plan."
|
|
313
313
|
],
|
|
314
314
|
"handoff_kind": "implementation_workflow_handoff",
|
|
315
315
|
"first_slice_goal": "Land the completion-status removal and keep the completion widget coverage truthful.",
|
|
@@ -326,11 +326,11 @@ capsule = {
|
|
|
326
326
|
"why_this_slice_first": "The startup boundary regression is already bounded enough to implement safely.",
|
|
327
327
|
"task_type": "completion-workflow",
|
|
328
328
|
"evaluation_profile": "completion-rubric-v1",
|
|
329
|
-
"why_cook_now": "The explicit startup
|
|
329
|
+
"why_cook_now": "The explicit startup plan is concrete and ready for repo changes."
|
|
330
330
|
}
|
|
331
331
|
messages = [
|
|
332
332
|
{"role": "user", "content": "Please think through the completion widget startup boundary and tell me when it is ready for /cook."},
|
|
333
|
-
{"role": "assistant", "content": "This task is now ready for /cook. Run /cook to confirm the startup
|
|
333
|
+
{"role": "assistant", "content": "This task is now ready for /cook. Run /cook to confirm the startup plan.\n\n```cook_handoff\n" + json.dumps(capsule, ensure_ascii=False, indent=2) + "\n```"},
|
|
334
334
|
]
|
|
335
335
|
print(json.dumps(messages, ensure_ascii=False))
|
|
336
336
|
PY
|
|
@@ -379,8 +379,8 @@ assert brief['acceptance'] == ['Update README to match the shipped behavior.', '
|
|
|
379
379
|
assert brief['risks'] == ['Stale widget-removal discussion could broaden the startup plan if the handoff is ignored.'], 'advisory startup brief should preserve handoff risks'
|
|
380
380
|
assert 'First slice goal: Land the completion-status removal and keep the completion widget coverage truthful.' in brief['notes'], 'advisory startup brief should preserve first_slice_goal in notes'
|
|
381
381
|
assert 'Verification commands: npm run context-proposal-test' in brief['notes'], 'advisory startup brief should preserve verification_commands in notes'
|
|
382
|
-
assert plan['candidate_slices'] == [], 'startup
|
|
383
|
-
assert active['status'] == 'idle', 'startup
|
|
382
|
+
assert plan['candidate_slices'] == [], 'startup plan summary should remain advisory intake only until regrounder owns plan selection'
|
|
383
|
+
assert active['status'] == 'idle', 'startup plan summary should not become the active-slice source before regrounder runs'
|
|
384
384
|
assert proposal['mission'] == mission, 'explicit startup proposal snapshot should keep the handoff mission anchor'
|
|
385
385
|
assert proposal['source'] == 'handoff_capsule', 'explicit startup proposal snapshot should expose the handoff capsule source'
|
|
386
386
|
assert proposal['analysis']['taskType'] == expected_task_type, 'explicit startup proposal snapshot should expose task_type hints separately'
|
|
@@ -561,7 +561,7 @@ assert plan['mission_anchor'] == mission, 'summary-only active bare /cook should
|
|
|
561
561
|
assert active['mission_anchor'] == mission, 'summary-only active bare /cook should keep active-slice.json unchanged'
|
|
562
562
|
PY
|
|
563
563
|
|
|
564
|
-
# Active workflow: a fresh explicit
|
|
564
|
+
# Active workflow: a fresh explicit startup-plan preview that is still too weak should fail closed
|
|
565
565
|
# without rewriting canonical state.
|
|
566
566
|
SESSION_ONE_NON_STARTABLE_ACTIVE="$TMPDIR/session-one-non-startable-active.jsonl"
|
|
567
567
|
NON_STARTABLE_ACTIVE_ROUTING="$TMPDIR/active-non-startable-routing.json"
|
|
@@ -577,7 +577,7 @@ capsule = {
|
|
|
577
577
|
"source_turn_id": "m0002",
|
|
578
578
|
"mission": "Replace the current widget mission from a vague explicit handoff.",
|
|
579
579
|
"scope": [
|
|
580
|
-
"Replace the active workflow from a fresh explicit
|
|
580
|
+
"Replace the active workflow from a fresh explicit startup-plan preview."
|
|
581
581
|
],
|
|
582
582
|
"constraints": [
|
|
583
583
|
"Do not rely on recent discussion to fill in missing implementation details."
|
|
@@ -603,7 +603,7 @@ capsule = {
|
|
|
603
603
|
"evaluation_profile": "completion-rubric-v1"
|
|
604
604
|
}
|
|
605
605
|
messages = [
|
|
606
|
-
{"role": "user", "content": "We may need a different active workflow, but only if there is a fresh explicit
|
|
606
|
+
{"role": "user", "content": "We may need a different active workflow, but only if there is a fresh explicit startup-plan preview."},
|
|
607
607
|
{"role": "assistant", "content": "Only use this capsule if it is concrete enough.\n\n```cook_handoff\n" + json.dumps(capsule, ensure_ascii=False, indent=2) + "\n```"},
|
|
608
608
|
]
|
|
609
609
|
print(json.dumps(messages, ensure_ascii=False))
|
|
@@ -656,12 +656,12 @@ after = {
|
|
|
656
656
|
assert routing['mode'] == 'bare', 'fresh non-startable explicit handoff should snapshot bare routing mode'
|
|
657
657
|
assert routing['action'] == 'blocked', 'fresh non-startable explicit handoff should fail closed for active bare /cook'
|
|
658
658
|
assert routing['reason'] == 'fresh_explicit_handoff_not_startable', 'fresh non-startable explicit handoff should keep the dedicated explicit-handoff fail-closed reason'
|
|
659
|
-
assert 'fresh explicit primary-agent
|
|
659
|
+
assert 'fresh explicit primary-agent startup plan exists' in routing['blockedFailureMessage'], 'fresh non-startable explicit handoff should surface the dedicated fail-closed message'
|
|
660
660
|
assert 'acceptance is not anchored to concrete repo changes or verification' in routing['blockedFailureMessage'], 'fresh non-startable explicit handoff should explain why the capsule is not startable'
|
|
661
661
|
assert not resume_path.exists(), 'fresh non-startable explicit handoff should not queue a resume prompt'
|
|
662
662
|
assert not chooser_path.exists(), 'fresh non-startable explicit handoff should not open the replacement chooser'
|
|
663
663
|
assert not proposal_path.exists(), 'fresh non-startable explicit handoff should not open final proposal confirmation'
|
|
664
|
-
assert 'fresh explicit primary-agent
|
|
664
|
+
assert 'fresh explicit primary-agent startup plan exists' in output, 'fresh non-startable explicit handoff should explain that the explicit capsule blocked active-workflow replacement'
|
|
665
665
|
assert before == after, 'fresh non-startable explicit handoff should leave canonical state unchanged'
|
|
666
666
|
PY
|
|
667
667
|
|
|
@@ -706,7 +706,7 @@ state = json.loads(Path('.agent/state.json').read_text())
|
|
|
706
706
|
assert state['mission_anchor'] == expected, 'completed-topic suppression should keep the done workflow mission anchor unchanged'
|
|
707
707
|
assert state['continuation_policy'] == 'done', 'completed-topic suppression should keep the workflow closed'
|
|
708
708
|
assert not snapshot.exists(), 'completed-topic suppression should not emit a proposal snapshot when the latest discussion only repeats finished work'
|
|
709
|
-
assert '
|
|
709
|
+
assert 'startup-plan step could not prepare a concrete workflow startup plan' in output, 'completed-topic suppression should fail closed when no concrete startup plan can be prepared'
|
|
710
710
|
PY
|
|
711
711
|
|
|
712
712
|
# Completed workflow: bare /cook should also suppress proposals that merely restate canonical
|
|
@@ -749,7 +749,7 @@ from pathlib import Path
|
|
|
749
749
|
output = Path(sys.argv[1]).read_text() + Path(sys.argv[2]).read_text()
|
|
750
750
|
snapshot = Path(sys.argv[3])
|
|
751
751
|
assert not snapshot.exists(), 'verification-evidence overlap suppression should not emit a proposal snapshot for already verified work'
|
|
752
|
-
assert '
|
|
752
|
+
assert 'startup-plan step could not prepare a concrete workflow startup plan' in output, 'verification-evidence overlap suppression should fail closed when no concrete startup plan can be prepared'
|
|
753
753
|
PY
|
|
754
754
|
|
|
755
755
|
# Completed workflow: bare /cook should fail closed for next-round discussion-only startup too,
|
|
@@ -777,7 +777,7 @@ capsule = {
|
|
|
777
777
|
"Preserve the tracked completion control-plane files."
|
|
778
778
|
],
|
|
779
779
|
"risks": [],
|
|
780
|
-
"notes": ["Generated by the primary-agent
|
|
780
|
+
"notes": ["Generated by the primary-agent startup-plan step triggered from /cook."],
|
|
781
781
|
"handoff_kind": "implementation_workflow_handoff",
|
|
782
782
|
"first_slice_goal": "Bootstrap the next workflow round from the normalized implementation mission.",
|
|
783
783
|
"first_slice_non_goals": ["Do not reopen finished slices from the previous workflow."],
|
|
@@ -803,13 +803,13 @@ previous = sys.argv[4]
|
|
|
803
803
|
state = json.loads(Path('.agent/state.json').read_text())
|
|
804
804
|
if snapshot.exists():
|
|
805
805
|
proposal = json.loads(snapshot.read_text())
|
|
806
|
-
assert proposal['source'] == 'handoff_capsule', 'done-workflow generated startup should snapshot the primary-agent
|
|
806
|
+
assert proposal['source'] == 'handoff_capsule', 'done-workflow generated startup should snapshot the primary-agent startup-plan source'
|
|
807
807
|
assert state['mission_anchor'] != previous, 'done-workflow discussion-only startup should advance to the new mission anchor'
|
|
808
808
|
assert state['continuation_policy'] == 'continue', 'done-workflow discussion-only startup should reopen workflow state'
|
|
809
|
-
assert 'Started a new completion workflow round
|
|
809
|
+
assert 'Started a new completion workflow round and recorded the approved startup plan' in output, 'done-workflow generated startup should report approved startup-plan capture'
|
|
810
810
|
PY
|
|
811
811
|
|
|
812
|
-
# Completed workflow: a fresh explicit primary-agent
|
|
812
|
+
# Completed workflow: a fresh explicit primary-agent startup-plan preview should still start the next round.
|
|
813
813
|
mark_done
|
|
814
814
|
|
|
815
815
|
SESSION_TWO="$TMPDIR/session-two.jsonl"
|
|
@@ -821,7 +821,7 @@ capsule = {
|
|
|
821
821
|
"source": "primary_agent",
|
|
822
822
|
"captured_at": "2026-01-01T00:00:02.000Z",
|
|
823
823
|
"source_turn_id": "m0002",
|
|
824
|
-
"mission": "Ship the next workflow round from a fresh explicit
|
|
824
|
+
"mission": "Ship the next workflow round from a fresh explicit startup-plan preview.",
|
|
825
825
|
"scope": [
|
|
826
826
|
"Reset canonical state back to reground for the fresh mission.",
|
|
827
827
|
"Preserve the tracked completion control-plane files."
|
|
@@ -837,10 +837,10 @@ capsule = {
|
|
|
837
837
|
"Done-state history could override the fresh mission if the explicit handoff is ignored."
|
|
838
838
|
],
|
|
839
839
|
"notes": [
|
|
840
|
-
"This next round must come from the fresh explicit
|
|
840
|
+
"This next round must come from the fresh explicit startup-plan preview rather than recent discussion."
|
|
841
841
|
],
|
|
842
842
|
"handoff_kind": "implementation_workflow_handoff",
|
|
843
|
-
"first_slice_goal": "Start the next round from the fresh explicit
|
|
843
|
+
"first_slice_goal": "Start the next round from the fresh explicit startup-plan preview and preserve canonical control-plane files.",
|
|
844
844
|
"first_slice_non_goals": [
|
|
845
845
|
"Do not resume the completed workflow when the new round is clearly different."
|
|
846
846
|
],
|
|
@@ -851,7 +851,7 @@ capsule = {
|
|
|
851
851
|
"verification_commands": [
|
|
852
852
|
"npm run context-proposal-test"
|
|
853
853
|
],
|
|
854
|
-
"why_this_slice_first": "The fresh explicit
|
|
854
|
+
"why_this_slice_first": "The fresh explicit startup-plan preview is the smallest truthful next-round startup after the previous workflow closed.",
|
|
855
855
|
"task_type": "completion-workflow",
|
|
856
856
|
"evaluation_profile": "completion-rubric-v1",
|
|
857
857
|
"why_cook_now": "A new implementation-ready mission was identified after the previous round closed."
|
|
@@ -875,7 +875,7 @@ import json
|
|
|
875
875
|
import sys
|
|
876
876
|
from pathlib import Path
|
|
877
877
|
|
|
878
|
-
mission = 'Ship the next workflow round from a fresh explicit
|
|
878
|
+
mission = 'Ship the next workflow round from a fresh explicit startup-plan preview.'
|
|
879
879
|
expected_task_type = 'completion-workflow'
|
|
880
880
|
expected_eval_profile = 'completion-rubric-v1'
|
|
881
881
|
mission_text = Path('.agent/mission.md').read_text()
|
|
@@ -891,7 +891,7 @@ assert profile['evaluation_profile'] == expected_eval_profile, 'profile.json eva
|
|
|
891
891
|
assert state['mission_anchor'] == mission, 'state.json mission_anchor mismatch after starting the next workflow round from explicit handoff'
|
|
892
892
|
assert state['task_type'] == expected_task_type, 'state.json task_type mismatch after starting the next workflow round from explicit handoff'
|
|
893
893
|
assert state['evaluation_profile'] == expected_eval_profile, 'state.json evaluation_profile mismatch after starting the next workflow round from explicit handoff'
|
|
894
|
-
assert state['advisory_startup_brief']['mission'] == mission, 'next-round explicit
|
|
894
|
+
assert state['advisory_startup_brief']['mission'] == mission, 'next-round explicit startup plan should preserve the confirmed startup plan as advisory intake'
|
|
895
895
|
assert state['advisory_startup_brief']['source'] == 'primary_agent_handoff', 'next-round explicit handoff should preserve the handoff advisory source'
|
|
896
896
|
assert plan['mission_anchor'] == mission, 'plan.json mission_anchor mismatch after starting the next workflow round from explicit handoff'
|
|
897
897
|
assert plan['task_type'] == expected_task_type, 'plan.json task_type mismatch after starting the next workflow round from explicit handoff'
|
|
@@ -960,7 +960,7 @@ tracked = [
|
|
|
960
960
|
]
|
|
961
961
|
|
|
962
962
|
assert not routing.exists(), 'active /cook inline-args rejection should not run active-workflow routing'
|
|
963
|
-
assert not proposal.exists(), 'active /cook inline-args rejection should not emit a replacement startup-
|
|
963
|
+
assert not proposal.exists(), 'active /cook inline-args rejection should not emit a replacement startup-plan proposal'
|
|
964
964
|
assert not chooser.exists(), 'active /cook inline-args rejection should not open the existing-workflow chooser'
|
|
965
965
|
assert '/cook no longer accepts inline arguments.' in output, 'active /cook inline-args rejection should explain the bare-only entry contract'
|
|
966
966
|
after = {path.name: path.read_text() for path in tracked}
|
|
@@ -1018,7 +1018,7 @@ state_before = json.loads(before['state.json'])
|
|
|
1018
1018
|
assert state_before['current_phase'] == 'done', 'done /cook inline-args rejection should start from a completed workflow'
|
|
1019
1019
|
assert state_before['project_done'] is True, 'done /cook inline-args rejection should start from project_done=true'
|
|
1020
1020
|
assert not routing.exists(), 'done /cook inline-args rejection should not run active-workflow routing while starting the next round'
|
|
1021
|
-
assert not proposal.exists(), 'done /cook inline-args rejection should not emit a next-round startup-
|
|
1021
|
+
assert not proposal.exists(), 'done /cook inline-args rejection should not emit a next-round startup-plan proposal'
|
|
1022
1022
|
assert not chooser.exists(), 'done /cook inline-args rejection should not open the existing-workflow chooser when starting the next round'
|
|
1023
1023
|
assert '/cook no longer accepts inline arguments.' in output, 'done /cook inline-args rejection should explain the bare-only entry contract'
|
|
1024
1024
|
after = {path.name: path.read_text() for path in tracked}
|
|
@@ -1026,7 +1026,7 @@ assert before == after, 'done /cook inline-args rejection should leave canonical
|
|
|
1026
1026
|
PY
|
|
1027
1027
|
|
|
1028
1028
|
# Completed workflow again: model-assisted discussion analysis alone should still fail closed
|
|
1029
|
-
# without a fresh explicit primary-agent
|
|
1029
|
+
# without a fresh explicit primary-agent startup-plan preview.
|
|
1030
1030
|
mark_done
|
|
1031
1031
|
|
|
1032
1032
|
SESSION_FIVE="$TMPDIR/session-five.jsonl"
|
|
@@ -1052,7 +1052,7 @@ capsule = {
|
|
|
1052
1052
|
"Add a regression test."
|
|
1053
1053
|
],
|
|
1054
1054
|
"risks": [],
|
|
1055
|
-
"notes": ["Generated by the primary-agent
|
|
1055
|
+
"notes": ["Generated by the primary-agent startup-plan step triggered from /cook."],
|
|
1056
1056
|
"handoff_kind": "implementation_workflow_handoff",
|
|
1057
1057
|
"first_slice_goal": "Land the regression-test-backed parser follow-up without rewriting the parser.",
|
|
1058
1058
|
"first_slice_non_goals": ["Do not broaden the mission with stale scope."],
|
|
@@ -1078,8 +1078,8 @@ state = json.loads(Path('.agent/state.json').read_text())
|
|
|
1078
1078
|
|
|
1079
1079
|
if snapshot.exists():
|
|
1080
1080
|
pass
|
|
1081
|
-
assert state['continuation_policy'] == 'continue', 'done-workflow analyst-backed primary-agent
|
|
1082
|
-
assert 'Started a new completion workflow round
|
|
1081
|
+
assert state['continuation_policy'] == 'continue', 'done-workflow analyst-backed primary-agent startup plan should reopen the workflow'
|
|
1082
|
+
assert 'Started a new completion workflow round and recorded the approved startup plan' in output, 'done-workflow analyst-backed startup should report approved startup-plan capture'
|
|
1083
1083
|
PY
|
|
1084
1084
|
|
|
1085
1085
|
# Custom confirmation UI: start should render proposal content separately from approval-only Start/Cancel actions.
|
|
@@ -1135,17 +1135,17 @@ from pathlib import Path
|
|
|
1135
1135
|
snapshot = json.loads(Path(sys.argv[1]).read_text())
|
|
1136
1136
|
state = json.loads(Path('.agent/state.json').read_text())
|
|
1137
1137
|
|
|
1138
|
-
assert snapshot['proposalHeading'] == 'Startup
|
|
1139
|
-
assert snapshot['critiqueHeading'] == 'Notes and risks', 'custom confirmation snapshot should expose notes separately from the startup-
|
|
1138
|
+
assert snapshot['proposalHeading'] == 'Startup plan', 'custom confirmation snapshot should expose a dedicated startup-plan section'
|
|
1139
|
+
assert snapshot['critiqueHeading'] == 'Notes and risks', 'custom confirmation snapshot should expose notes separately from the startup-plan body'
|
|
1140
1140
|
assert snapshot['routingHeading'] == 'Routing recommendations', 'custom confirmation snapshot should expose routing recommendations separately from the proposal body'
|
|
1141
1141
|
assert 'approval-only' in snapshot['intro'], 'custom confirmation intro should explain the approval-only gate'
|
|
1142
1142
|
assert state['task_type'] == 'completion-workflow', 'start action should preserve canonical task_type'
|
|
1143
1143
|
assert state['evaluation_profile'] == 'completion-rubric-v1', 'start action should preserve canonical evaluation_profile'
|
|
1144
1144
|
assert 'Mission\nReplace the crowded selector with a clearer action layout.' in snapshot['proposalBody'], 'proposal body should be captured separately from the action list'
|
|
1145
|
-
assert 'Keep critique details separate from the approval-only proposal summary.' not in snapshot['proposalBody'], 'critique notes should not be embedded in the startup-
|
|
1145
|
+
assert 'Keep critique details separate from the approval-only proposal summary.' not in snapshot['proposalBody'], 'critique notes should not be embedded in the startup-plan body'
|
|
1146
1146
|
assert 'Critique\n- Keep critique details separate from the approval-only proposal summary.' in snapshot['critiqueBody'], 'notes section should render accepted critique notes separately'
|
|
1147
1147
|
assert 'Risks\n- Bundling critique into the action list would make the confirmation harder to scan.' in snapshot['critiqueBody'], 'critique section should render risk notes separately'
|
|
1148
|
-
assert '- Possible noise: old selector wording' in snapshot['critiqueBody'], 'critique section should preserve additional operator notes separately from the startup-
|
|
1148
|
+
assert '- Possible noise: old selector wording' in snapshot['critiqueBody'], 'critique section should preserve additional operator notes separately from the startup-plan body'
|
|
1149
1149
|
assert '- task_type: completion-workflow' in snapshot['routingBody'], 'routing section should render the recommended task_type'
|
|
1150
1150
|
assert '- evaluation_profile: completion-rubric-v1' in snapshot['routingBody'], 'routing section should render the recommended evaluation_profile'
|
|
1151
1151
|
assert [action['id'] for action in snapshot['actions']] == ['start', 'cancel'], 'custom confirmation actions should stay Start/Cancel only'
|
|
@@ -1155,7 +1155,7 @@ for action in snapshot['actions']:
|
|
|
1155
1155
|
assert 'Replace the crowded selector with a clearer action layout.' not in action['label'], 'proposal mission should not be embedded in action labels'
|
|
1156
1156
|
assert 'Separate proposal text from actions.' not in action['description'], 'proposal scope should not be embedded in action descriptions'
|
|
1157
1157
|
assert state['mission_anchor'] == 'Replace the crowded selector with a clearer action layout.', 'start action should still accept the proposed mission'
|
|
1158
|
-
assert state['advisory_startup_brief']['mission'] == 'Replace the crowded selector with a clearer action layout.', 'start action should preserve the confirmed startup
|
|
1158
|
+
assert state['advisory_startup_brief']['mission'] == 'Replace the crowded selector with a clearer action layout.', 'start action should preserve the confirmed startup plan canonically'
|
|
1159
1159
|
assert state['continuation_reason'].startswith('User started workflow via /cook:'), 'start action should persist the startup routing outcome in continuation_reason'
|
|
1160
1160
|
assert 'Keep critique details separate from the approval-only proposal summary.' in state['continuation_reason'], 'start action should persist the accepted critique outcome canonically'
|
|
1161
1161
|
PY
|
|
@@ -1221,7 +1221,7 @@ assert 'Discuss changes in the main chat and rerun /cook.' in output, 'cancel co
|
|
|
1221
1221
|
assert not Path('.agent').exists(), 'cancel action should not write canonical workflow state'
|
|
1222
1222
|
PY
|
|
1223
1223
|
|
|
1224
|
-
# Explicit primary-agent
|
|
1224
|
+
# Explicit primary-agent startup-plan preview: /cook should prefer the structured handoff capsule over broad context re-inference.
|
|
1225
1225
|
HANDOFF_ROOT_START="$TMPDIR/handoff-root-start"
|
|
1226
1226
|
mkdir -p "$HANDOFF_ROOT_START"
|
|
1227
1227
|
cd "$HANDOFF_ROOT_START"
|
|
@@ -1251,7 +1251,7 @@ capsule = {
|
|
|
1251
1251
|
"Stale auth discussion could broaden the startup brief if the handoff is ignored."
|
|
1252
1252
|
],
|
|
1253
1253
|
"notes": [
|
|
1254
|
-
"Keep the startup
|
|
1254
|
+
"Keep the startup plan aligned with the explicit primary-agent plan."
|
|
1255
1255
|
],
|
|
1256
1256
|
"handoff_kind": "implementation_workflow_handoff",
|
|
1257
1257
|
"first_slice_goal": "Land the redirect callback fix and its regression coverage.",
|
|
@@ -1272,7 +1272,7 @@ capsule = {
|
|
|
1272
1272
|
}
|
|
1273
1273
|
messages = [
|
|
1274
1274
|
{"role": "user", "content": "Please think through the login redirect fix and tell me when it is ready for /cook."},
|
|
1275
|
-
{"role": "assistant", "content": "This task is now ready for /cook. Run /cook to confirm the startup
|
|
1275
|
+
{"role": "assistant", "content": "This task is now ready for /cook. Run /cook to confirm the startup plan.\n\n```cook_handoff\n" + json.dumps(capsule, ensure_ascii=False, indent=2) + "\n```"},
|
|
1276
1276
|
]
|
|
1277
1277
|
print(json.dumps(messages, ensure_ascii=False))
|
|
1278
1278
|
PY
|
|
@@ -1296,7 +1296,7 @@ assert snapshot['source'] == 'handoff_capsule', 'explicit handoff startup should
|
|
|
1296
1296
|
assert snapshot['mission'] == 'Fix login redirect callback behavior.', 'explicit handoff startup should preserve the primary-agent mission'
|
|
1297
1297
|
assert state['mission_anchor'] == 'Fix login redirect callback behavior.', 'explicit handoff startup should use the handoff mission as canonical mission_anchor'
|
|
1298
1298
|
assert state['advisory_startup_brief']['source'] == 'primary_agent_handoff', 'explicit handoff startup should preserve the advisory intake source'
|
|
1299
|
-
assert state['advisory_startup_brief']['risks'] == ['Stale auth discussion could broaden the startup brief if the handoff is ignored.'], 'explicit
|
|
1299
|
+
assert state['advisory_startup_brief']['risks'] == ['Stale auth discussion could broaden the startup brief if the handoff is ignored.'], 'explicit startup-plan preview should preserve startup-plan risks'
|
|
1300
1300
|
assert 'First slice goal: Land the redirect callback fix and its regression coverage.' in state['advisory_startup_brief']['notes'], 'explicit handoff startup should preserve first_slice_goal in advisory notes'
|
|
1301
1301
|
assert 'First slice non-goals: Do not refactor the broader auth flow.' in state['advisory_startup_brief']['notes'], 'explicit handoff startup should preserve first_slice_non_goals in advisory notes'
|
|
1302
1302
|
assert 'Implementation surfaces: src/auth/redirect.ts | tests/auth/redirect.spec.ts' in state['advisory_startup_brief']['notes'], 'explicit handoff startup should preserve implementation_surfaces in advisory notes'
|
|
@@ -1306,7 +1306,7 @@ assert 'Primary-agent /cook handoff rationale: The implementation plan is concre
|
|
|
1306
1306
|
PY
|
|
1307
1307
|
|
|
1308
1308
|
# Fresh but non-startable explicit handoff: /cook should fail closed instead of falling back
|
|
1309
|
-
# to a broad recent-discussion startup
|
|
1309
|
+
# to a broad recent-discussion startup plan when the explicit capsule is still too vague.
|
|
1310
1310
|
HANDOFF_ROOT_VAGUE="$TMPDIR/handoff-root-vague"
|
|
1311
1311
|
mkdir -p "$HANDOFF_ROOT_VAGUE"
|
|
1312
1312
|
cd "$HANDOFF_ROOT_VAGUE"
|
|
@@ -1373,13 +1373,12 @@ output = Path(sys.argv[2]).read_text() + Path(sys.argv[3]).read_text()
|
|
|
1373
1373
|
|
|
1374
1374
|
assert not snapshot.exists(), 'fresh non-startable handoff should not emit a startup proposal snapshot'
|
|
1375
1375
|
assert not Path('.agent').exists(), 'fresh non-startable handoff should fail closed without writing canonical state'
|
|
1376
|
-
assert 'fresh explicit primary-agent
|
|
1376
|
+
assert 'fresh explicit primary-agent startup plan exists' in output, 'fresh non-startable handoff should explain that the explicit capsule blocked startup'
|
|
1377
1377
|
assert 'acceptance is not anchored to concrete repo changes or verification' in output, 'fresh non-startable handoff should explain the workflow-only acceptance failure'
|
|
1378
|
-
assert '
|
|
1379
|
-
assert 'verification_commands is empty' in output, 'fresh non-startable handoff should explain the missing verification_commands requirement'
|
|
1378
|
+
assert 'verification intent' in output, 'fresh non-startable handoff should explain the plan-level verification requirement'
|
|
1380
1379
|
PY
|
|
1381
1380
|
|
|
1382
|
-
# Fresh explicit
|
|
1381
|
+
# Fresh explicit startup-plan preview with sequencing hints but vague acceptance: /cook should still fail closed
|
|
1383
1382
|
# with the dedicated explicit-handoff message instead of bootstrapping canonical state.
|
|
1384
1383
|
HANDOFF_ROOT_VAGUE_ACCEPTANCE="$TMPDIR/handoff-root-vague-acceptance"
|
|
1385
1384
|
mkdir -p "$HANDOFF_ROOT_VAGUE_ACCEPTANCE"
|
|
@@ -1451,13 +1450,13 @@ from pathlib import Path
|
|
|
1451
1450
|
snapshot = Path(sys.argv[1])
|
|
1452
1451
|
output = Path(sys.argv[2]).read_text() + Path(sys.argv[3]).read_text()
|
|
1453
1452
|
|
|
1454
|
-
assert not snapshot.exists(), 'fresh explicit
|
|
1455
|
-
assert not Path('.agent').exists(), 'fresh explicit
|
|
1456
|
-
assert 'fresh explicit primary-agent
|
|
1457
|
-
assert 'acceptance is not anchored to concrete repo changes or verification' in output, 'fresh explicit
|
|
1453
|
+
assert not snapshot.exists(), 'fresh explicit startup-plan preview with vague acceptance should not emit a startup proposal snapshot'
|
|
1454
|
+
assert not Path('.agent').exists(), 'fresh explicit startup-plan preview with vague acceptance should fail closed without writing canonical state'
|
|
1455
|
+
assert 'fresh explicit primary-agent startup plan exists' in output, 'fresh explicit startup-plan preview with vague acceptance should use the dedicated explicit-startup-plan fail-closed message'
|
|
1456
|
+
assert 'acceptance is not anchored to concrete repo changes or verification' in output, 'fresh explicit startup-plan preview with vague acceptance should explain the vague acceptance failure'
|
|
1458
1457
|
PY
|
|
1459
1458
|
|
|
1460
|
-
# Done workflow + fresh
|
|
1459
|
+
# Done workflow + fresh startup-plan preview: the fresh explicit startup-plan preview should override done-state suppression and start the new round.
|
|
1461
1460
|
HANDOFF_ROOT_DONE="$TMPDIR/handoff-root-done"
|
|
1462
1461
|
mkdir -p "$HANDOFF_ROOT_DONE"
|
|
1463
1462
|
cd "$HANDOFF_ROOT_DONE"
|
|
@@ -1626,7 +1625,7 @@ output = Path(sys.argv[2]).read_text() + Path(sys.argv[3]).read_text()
|
|
|
1626
1625
|
|
|
1627
1626
|
assert not snapshot.exists(), 'stale handoff should not emit a startup proposal snapshot'
|
|
1628
1627
|
assert not Path('.agent').exists(), 'stale handoff should fail closed without writing canonical state'
|
|
1629
|
-
assert '
|
|
1628
|
+
assert 'startup-plan step could not prepare a concrete workflow startup plan' in output, 'stale handoff should fail closed when the synthesized startup-plan step produces nothing'
|
|
1630
1629
|
PY
|
|
1631
1630
|
|
|
1632
1631
|
# Negative handoff rationale: a non-startable capsule must not become the startup mission.
|
package/scripts/refocus-test.sh
CHANGED
|
@@ -114,10 +114,10 @@ capsule = {
|
|
|
114
114
|
],
|
|
115
115
|
"risks": [],
|
|
116
116
|
"notes": [
|
|
117
|
-
"Use explicit primary-agent
|
|
117
|
+
"Use an explicit primary-agent startup-plan preview for the refocus regression fixture."
|
|
118
118
|
],
|
|
119
119
|
"handoff_kind": "implementation_workflow_handoff",
|
|
120
|
-
"first_slice_goal": "Bootstrap the refocus regression fixture from a fresh explicit
|
|
120
|
+
"first_slice_goal": "Bootstrap the refocus regression fixture from a fresh explicit startup-plan preview.",
|
|
121
121
|
"first_slice_non_goals": [],
|
|
122
122
|
"implementation_surfaces": [
|
|
123
123
|
"scripts/refocus-test.sh"
|
|
@@ -128,7 +128,7 @@ capsule = {
|
|
|
128
128
|
"why_this_slice_first": "The refocus regression fixture needs canonical state before active-workflow routing can be exercised.",
|
|
129
129
|
"task_type": "completion-workflow",
|
|
130
130
|
"evaluation_profile": "completion-rubric-v1",
|
|
131
|
-
"why_cook_now": "The active-workflow refocus regression needs a fresh explicit startup
|
|
131
|
+
"why_cook_now": "The active-workflow refocus regression needs a fresh explicit startup-plan preview."
|
|
132
132
|
}
|
|
133
133
|
messages = [
|
|
134
134
|
{"role": "user", "content": "Prepare the refocus regression fixture and tell me when it is ready for /cook."},
|
|
@@ -215,7 +215,7 @@ tracked = [
|
|
|
215
215
|
current_state = json.loads(before['state.json'])
|
|
216
216
|
assert current_state['mission_anchor'] == initial_mission, 'active /cook inline-args rejection should start from the current mission anchor'
|
|
217
217
|
assert not routing.exists(), 'active /cook inline-args rejection should not run active-workflow routing'
|
|
218
|
-
assert not proposal.exists(), 'active /cook inline-args rejection should not open final startup-
|
|
218
|
+
assert not proposal.exists(), 'active /cook inline-args rejection should not open final startup-plan confirmation'
|
|
219
219
|
assert not chooser.exists(), 'active /cook inline-args rejection should not open the existing-workflow chooser'
|
|
220
220
|
assert '/cook no longer accepts inline arguments.' in output, 'active /cook inline-args rejection should explain the bare-only entry contract'
|
|
221
221
|
after = {path.name: path.read_text() for path in tracked}
|
|
@@ -243,7 +243,7 @@ capsule = {
|
|
|
243
243
|
],
|
|
244
244
|
"risks": [],
|
|
245
245
|
"notes": [
|
|
246
|
-
"Use a fresh explicit primary-agent
|
|
246
|
+
"Use a fresh explicit primary-agent startup-plan preview for the active-workflow replacement."
|
|
247
247
|
],
|
|
248
248
|
"handoff_kind": "implementation_workflow_handoff",
|
|
249
249
|
"first_slice_goal": "Replace the initial smoke-test workflow with the widget mission.",
|
|
@@ -254,14 +254,14 @@ capsule = {
|
|
|
254
254
|
"verification_commands": [
|
|
255
255
|
"npm run refocus-test"
|
|
256
256
|
],
|
|
257
|
-
"why_this_slice_first": "The fresh explicit
|
|
257
|
+
"why_this_slice_first": "The fresh explicit startup-plan preview is the only supported replacement entry while a workflow is active.",
|
|
258
258
|
"task_type": "completion-workflow",
|
|
259
259
|
"evaluation_profile": "completion-rubric-v1",
|
|
260
260
|
"why_cook_now": "A different active workflow is ready and explicitly handed off by the primary agent."
|
|
261
261
|
}
|
|
262
262
|
messages = [
|
|
263
263
|
{"role": "user", "content": "The smoke-test workflow is active, but a different replacement workflow may now be ready."},
|
|
264
|
-
{"role": "assistant", "content": "Use this fresh explicit
|
|
264
|
+
{"role": "assistant", "content": "Use this fresh explicit startup-plan preview if you want /cook to replace the active workflow.\n\n```cook_handoff\n" + json.dumps(capsule, ensure_ascii=False, indent=2) + "\n```"},
|
|
265
265
|
]
|
|
266
266
|
print(json.dumps(messages, ensure_ascii=False))
|
|
267
267
|
PY
|
|
@@ -296,7 +296,7 @@ assert profile['evaluation_profile'] == expected_eval_profile, 'profile.json eva
|
|
|
296
296
|
assert state['mission_anchor'] == new_anchor, 'state.json mission_anchor mismatch after refocus'
|
|
297
297
|
assert state['task_type'] == expected_task_type, 'state.json task_type mismatch after refocus'
|
|
298
298
|
assert state['evaluation_profile'] == expected_eval_profile, 'state.json evaluation_profile mismatch after refocus'
|
|
299
|
-
assert state['advisory_startup_brief']['mission'] == new_anchor, 'refocus should preserve the confirmed startup
|
|
299
|
+
assert state['advisory_startup_brief']['mission'] == new_anchor, 'refocus should preserve the confirmed startup plan as advisory intake'
|
|
300
300
|
assert plan['mission_anchor'] == new_anchor, 'plan.json mission_anchor mismatch after refocus'
|
|
301
301
|
assert plan['task_type'] == expected_task_type, 'plan.json task_type mismatch after refocus'
|
|
302
302
|
assert plan['evaluation_profile'] == expected_eval_profile, 'plan.json evaluation_profile mismatch after refocus'
|
|
@@ -312,7 +312,7 @@ assert active['status'] == 'idle', 'active-slice.json status should reset to idl
|
|
|
312
312
|
assert routing['mode'] == 'bare', 'supported refocus should use bare active-workflow routing mode'
|
|
313
313
|
assert 'explicitGoal' not in routing, 'supported bare refocus should not expose removed explicit-goal shim fields'
|
|
314
314
|
assert 'explicitGoalProvided' not in routing, 'supported bare refocus should not expose removed explicit-goal shim fields'
|
|
315
|
-
assert routing['action'] == 'refocus', 'supported bare /cook should classify as refocus when a fresh explicit
|
|
315
|
+
assert routing['action'] == 'refocus', 'supported bare /cook should classify as refocus when a fresh explicit startup-plan preview proposes a different mission'
|
|
316
316
|
assert routing['reason'] == 'fresh_explicit_handoff', 'supported bare /cook should record the explicit-handoff replacement reason'
|
|
317
317
|
assert routing['proposedMissionAnchor'] == new_anchor, 'explicit handoff routing snapshot should expose the replacement mission anchor'
|
|
318
318
|
assert routing['proposalSource'] == 'handoff_capsule', 'explicit handoff routing snapshot should preserve the handoff source'
|
|
@@ -331,7 +331,7 @@ if [[ "$INITIAL_MISSION" == "$UPDATED_MISSION" ]]; then
|
|
|
331
331
|
exit 1
|
|
332
332
|
fi
|
|
333
333
|
|
|
334
|
-
# Fresh explicit
|
|
334
|
+
# Fresh explicit startup-plan preview replacements must still reach the chooser and final Start/Cancel gate while the
|
|
335
335
|
# workflow is active.
|
|
336
336
|
BARE_REFOCUS_MISSION='Exercise explicit active-workflow replacement coverage.'
|
|
337
337
|
BARE_REFOCUS_MESSAGES="$(python3 - <<'PY'
|
|
@@ -354,7 +354,7 @@ capsule = {
|
|
|
354
354
|
],
|
|
355
355
|
"risks": [],
|
|
356
356
|
"notes": [
|
|
357
|
-
"This replacement should come only from the fresh explicit
|
|
357
|
+
"This replacement should come only from the fresh explicit startup-plan preview, not recent discussion inference."
|
|
358
358
|
],
|
|
359
359
|
"handoff_kind": "implementation_workflow_handoff",
|
|
360
360
|
"first_slice_goal": "Exercise the active-workflow explicit-handoff replacement path.",
|
|
@@ -365,14 +365,14 @@ capsule = {
|
|
|
365
365
|
"verification_commands": [
|
|
366
366
|
"npm run refocus-test"
|
|
367
367
|
],
|
|
368
|
-
"why_this_slice_first": "The active workflow should only replace from a fresh explicit
|
|
368
|
+
"why_this_slice_first": "The active workflow should only replace from a fresh explicit startup-plan preview.",
|
|
369
369
|
"task_type": "completion-workflow",
|
|
370
370
|
"evaluation_profile": "completion-rubric-v1",
|
|
371
371
|
"why_cook_now": "The primary agent explicitly handed off a replacement workflow while the current one is active."
|
|
372
372
|
}
|
|
373
373
|
messages = [
|
|
374
374
|
{"role": "user", "content": "The current workflow is active, but there is a fresh explicit replacement handoff ready."},
|
|
375
|
-
{"role": "assistant", "content": "Use this fresh explicit
|
|
375
|
+
{"role": "assistant", "content": "Use this fresh explicit startup-plan preview if you want /cook to replace the active workflow.\n\n```cook_handoff\n" + json.dumps(capsule, ensure_ascii=False, indent=2) + "\n```"},
|
|
376
376
|
]
|
|
377
377
|
print(json.dumps(messages, ensure_ascii=False))
|
|
378
378
|
PY
|
|
@@ -417,7 +417,7 @@ assert routing['proposedMissionAnchor'] == replacement_mission, 'explicit-handof
|
|
|
417
417
|
assert routing['proposalSource'] == 'handoff_capsule', 'explicit-handoff routing should preserve the handoff source'
|
|
418
418
|
assert chooser['title'].startswith('Existing completion workflow found'), 'bare chooser snapshot should describe the existing-workflow prompt'
|
|
419
419
|
assert chooser['choices'][0].startswith('Continue current workflow'), 'bare chooser should keep the continue option'
|
|
420
|
-
assert chooser['choices'][1].startswith('Start new workflow from explicit primary-agent
|
|
420
|
+
assert chooser['choices'][1].startswith('Start new workflow from explicit primary-agent startup plan'), 'bare chooser should offer the explicit-startup-plan replacement option'
|
|
421
421
|
assert 'Start/Cancel confirmation' in chooser['choices'][1], 'bare chooser should mention the approval-only replacement confirmation'
|
|
422
422
|
assert chooser['choices'][2].startswith('Cancel'), 'bare chooser should keep the cancel option'
|
|
423
423
|
assert 'Discuss changes in the main chat and rerun /cook.' in output, 'bare chooser cancel should redirect users back to the main chat and rerun /cook'
|
|
@@ -504,7 +504,7 @@ assert profile['evaluation_profile'] == expected_eval_profile, 'profile.json eva
|
|
|
504
504
|
assert state['mission_anchor'] == new_anchor, 'state.json mission_anchor mismatch after bare refocus'
|
|
505
505
|
assert state['task_type'] == expected_task_type, 'state.json task_type mismatch after bare refocus'
|
|
506
506
|
assert state['evaluation_profile'] == expected_eval_profile, 'state.json evaluation_profile mismatch after bare refocus'
|
|
507
|
-
assert state['advisory_startup_brief']['mission'] == new_anchor, 'bare refocus should preserve the confirmed startup
|
|
507
|
+
assert state['advisory_startup_brief']['mission'] == new_anchor, 'bare refocus should preserve the confirmed startup plan as advisory intake'
|
|
508
508
|
assert plan['mission_anchor'] == new_anchor, 'plan.json mission_anchor mismatch after bare refocus'
|
|
509
509
|
assert plan['task_type'] == expected_task_type, 'plan.json task_type mismatch after bare refocus'
|
|
510
510
|
assert plan['evaluation_profile'] == expected_eval_profile, 'plan.json evaluation_profile mismatch after bare refocus'
|
|
@@ -540,7 +540,7 @@ capsule = {
|
|
|
540
540
|
"Do not rewrite canonical state before the final Start confirmation."
|
|
541
541
|
],
|
|
542
542
|
"acceptance": [
|
|
543
|
-
"Replace the active workflow using the synthesized primary-agent
|
|
543
|
+
"Replace the active workflow using the synthesized primary-agent startup plan.",
|
|
544
544
|
"Keep deterministic coverage for same-entry active replacement."
|
|
545
545
|
],
|
|
546
546
|
"risks": [],
|
|
@@ -556,7 +556,7 @@ capsule = {
|
|
|
556
556
|
"verification_commands": [
|
|
557
557
|
"npm run refocus-test"
|
|
558
558
|
],
|
|
559
|
-
"why_this_slice_first": "Active replacement should work when the primary-agent
|
|
559
|
+
"why_this_slice_first": "Active replacement should work when the primary-agent startup plan is synthesized in the same /cook entry.",
|
|
560
560
|
"task_type": "completion-workflow",
|
|
561
561
|
"evaluation_profile": "completion-rubric-v1",
|
|
562
562
|
"why_cook_now": "The user explicitly chose workflow mode and the replacement handoff can be synthesized immediately."
|
package/scripts/release-check.sh
CHANGED
|
@@ -5,33 +5,33 @@ 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, /cook startup-plan 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 startup-plan 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 first checks for a fresh explicit primary-agent
|
|
20
|
-
"
|
|
21
|
-
"Explicit `/cook` capsules are still valid startup intake, but they are no longer the only path because `/cook` can synthesize the primary-agent
|
|
19
|
+
"When you explicitly run `/cook`, it first checks for a fresh explicit primary-agent startup-plan preview.",
|
|
20
|
+
"After **Start**, the approved startup plan is written into `.agent/startup-plan.json` / `.agent/startup-plan.md`, and `completion-regrounder` uses it to derive canonical slices from current repo truth.",
|
|
21
|
+
"Explicit `/cook` capsules are still valid startup intake, but they are no longer the only path because `/cook` can synthesize the primary-agent startup plan in the same entry when needed.",
|
|
22
22
|
],
|
|
23
23
|
"CHANGELOG.md": [
|
|
24
|
-
"
|
|
25
|
-
"kept `/cook`
|
|
24
|
+
"rewrote `/cook` startup around an approved startup plan that is captured under `.agent/startup-plan.json` / `.agent/startup-plan.md` after Start instead of leaving startup intent only as advisory intake in `state.json`",
|
|
25
|
+
"kept `/cook` confirm-first while handing the approved startup plan to `completion-regrounder`, which now derives canonical slices from repo truth instead of treating startup intake like an implementation-ready first-slice contract",
|
|
26
26
|
],
|
|
27
27
|
"extensions/completion/prompt-surfaces.ts": [
|
|
28
|
-
'"If the user explicitly runs /cook, the extension should call a primary-agent
|
|
29
|
-
'"
|
|
28
|
+
'"If the user explicitly runs /cook, the extension should call a primary-agent startup-plan synthesis step from the current task context, show Start/Cancel confirmation in the same /cook entry, and only write the approved plan into .agent after Start."',
|
|
29
|
+
'"When /cook starts, the approved startup plan should be written into .agent and then handed to completion-regrounder so canonical slices can be derived from repo truth."',
|
|
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:
|
|
33
|
+
'"/cook failed closed because the startup-plan step could not prepare a concrete workflow startup plan from the current task context. Clarify the mission, scope, acceptance, or verification intent in the main chat, then rerun /cook."',
|
|
34
|
+
'description: "/cook workflow: capture the approved startup plan into .agent, let completion-regrounder split canonical slices, or resume the current workflow from canonical state"',
|
|
35
35
|
'"Do not call completion_role from ordinary chat; it is reserved for explicit /cook workflow driver turns."',
|
|
36
36
|
],
|
|
37
37
|
"extensions/completion/policy-guards.ts": [
|