Skip to content

fix: stop Copilot continuation replay - #749

Open
akash-doshi wants to merge 1 commit into
awslabs:v2from
akash-doshi:copilot-stop-loop
Open

fix: stop Copilot continuation replay#749
akash-doshi wants to merge 1 commit into
awslabs:v2from
akash-doshi:copilot-stop-loop

Conversation

@akash-doshi

@akash-doshi akash-doshi commented Aug 12, 2026

Copy link
Copy Markdown

Confirmed failure

The AI-DLC Copilot adapter ignored the successful orchestration result supplied by postToolUse.

When agentStop later fired, the core Stop hook ran a fresh next. That restarted steering at part 1, even when the current Copilot session had already received a newer continuation token or run-stage.

Confirmed Copilot contract

This fix follows GitHub's documented hook behaviour:

  • postToolUse fires after a successful tool call and exposes the model-facing tool result.
  • agentStop fires when the main agent finishes and may return decision: "block" with a reason to force another turn.
  • userPromptSubmitted fires when the user submits a prompt.
  • Copilot bounds repeated agentStop blocks and supplies stop_hook_active.

Source: https://docs.github.com/en/copilot/reference/hooks-configuration

Fix

  • Capture the latest successful next, continue, or report directive from postToolUse.
  • Store a bounded receipt keyed by Copilot session and workflow-state digest.
  • When the existing core Stop hook decides to block, replace only its guidance with the latest session directive.
  • Reuse the newest continuation token instead of running steering from part 1.
  • Record the existing AI-DLC human-turn marker from userPromptSubmitted.
  • Fall back to the existing Stop behaviour for stale, malformed, or missing receipts.

Safety boundary

The receipt only changes the guidance returned after the core Stop hook has already decided to block. It cannot:

  • grant tool permission
  • mutate workflow state
  • bypass human-wait checks
  • bypass recursion limits
  • bypass autonomy rules
  • affect another harness

Scope

  • 1 authored production file
  • 2 authored test files
  • 1 generated Copilot adapter
  • 437 additions, 31 deletions
  • No core workflow, audit, pipeline, review, state-machine, version, or other harness changes

Validation

  • Focused receipt tests: 9/9
  • Copilot security tests: 25/25
  • Typecheck passed
  • Biome passed
  • Package parity passed
  • git diff --check passed
  • Independent review found no P0/P1 issues

Related issues

@akash-doshi
akash-doshi marked this pull request as draft August 12, 2026 23:49
@akash-doshi
akash-doshi marked this pull request as ready for review August 12, 2026 23:58
@apackeer

Copy link
Copy Markdown
Contributor

Akash, this PR adds a Copilot-specific receipt for successful orchestration results and uses it to preserve the latest continuation or run-stage guidance when the shared Stop hook blocks. It also brings Copilot's UserPromptSubmit path in line with the shared human-turn marker contract.

Part A - Direction: sound. I verified the problem against origin/v2: Copilot's post-tool path ignores the successful tool result, and the shared Stop hook probes a fresh next, which can restart steering from part 1. The adapter is the right layer for a Copilot-session receipt, the authored/generated split is correct, and package parity passes.

Part B - Review: request changes.

  1. harness/copilot/hooks/aidlc-copilot-adapter.ts:232 accepts a direct orchestration command with --project-dir <other-project>, but :265 stores that foreign result under the current hook project's session and state digest. I reproduced a current-project Stop prompt replaying the other project's intent-capture rules and token. Please parse the effective target and either require it to canonicalize to the hook project or bind the receipt to that target, with a regression test.

  2. The PR says Closes #739, but the consumed-token half of that issue is unchanged. core/tools/aidlc-orchestrate.ts:5327 still accepts the same valid continuation token repeatedly; on this head, two continue T1 calls returned the same run-stage. Please implement the session-scoped replay denial from [Bug]: Copilot Stop hook restarts completed steering and replays continuation tokens #739, or keep [Bug]: Copilot Stop hook restarts completed steering and replays continuation tokens #739 open and scope this PR explicitly to the Stop-handoff fix.

  3. This branch is three v2 commits behind. Its version, README badge, and changelog are still 2.5.64, while current origin/v2 is 2.5.69. Please rebase, claim 2.5.70 in all three authored surfaces, add the Copilot upgrade note, regenerate dist/, and rerun parity. The sync test currently passes only because the stale values agree.

  4. The receipt-specific reasons at harness/copilot/hooks/aidlc-copilot-adapter.ts:1038-1047 drop load-steering's "keep following until run-stage" and anti-narration instructions, plus run-stage's report/park/never-rubber-stamp guidance from core/hooks/aidlc-continue-workflow.ts:956-975. Please retain those safeguards in the replacement text.

  5. A run-stage receipt remains valid across PreCompact because compaction does not change the state digest, but the full directive it references may no longer be in context. The resulting Stop prompt says to continue from current context and forbids next/continue, leaving no recovery path. Please invalidate that receipt on compaction, persist enough directive data, or add a safe one-time next fallback, with coverage.

Non-blocking notes: expired receipt files are never garbage-collected, and the PR's "9/9" receipt-test count is not reflected by the seven added test blocks; the reproducible full totals are t249 32/32 and t250 25/25.

Part C - UX. The intended experience is consistent: Copilot should resume the latest steering position or active stage instead of restarting the forwarding loop, and ordinary conversational turns should end cleanly. There are no new commands, flags, stages, defaults, or intended breaking changes. The replacement prompts should preserve the existing forwarding-loop and non-narration language, and compaction needs an explicit recovery path.

Verification: focused tests passed at tests/logs/2026-08-13T01-53-05Z-p2 with RESULT: PASS; the independent adapter/security run also passed at tests/logs/2026-08-13T02-03-10Z-p393982; package parity, typecheck, Biome, and git diff --check passed on the current branch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants