forked from Yeachan-Heo/gajae-code
-
Notifications
You must be signed in to change notification settings - Fork 0
feat(sdk): C04 terminal abort with turn|owned scope #21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
snowykr
wants to merge
30
commits into
dev
Choose a base branch
from
feat/abort-sdk-terminal
base: dev
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
30 commits
Select commit
Hold shift + click to select a range
275bde3
feat(sdk): add validated C04 terminal abort input contract
snowykr a0c2c43
feat(sdk): v2 reconciliation store with durable terminal scope records
snowykr 33e353d
feat(sdk): private turn-continuation fence and origin gate
snowykr 29fa374
feat(sdk): bind private lineage/attempt origin at tool registration s…
snowykr 87f81f9
feat(sdk): origin-aware async-result delivery with fresh-attempt resume
snowykr 9af3f07
feat(sdk): turn.abort terminal surface with turn-scope registration a…
snowykr 4841d79
docs(sdk): add mandatory terminal-abort ADR and design-note gate
snowykr 9a07436
feat(sdk): durable terminal-scope record with no-store gate
snowykr 66a50a8
feat(sdk): owned-scope exact stop with delivery settlement and event …
snowykr f9637da
feat(sdk): deterministic replay, fenced-turn bounds, and gate registr…
snowykr 2efa6e8
fix(sdk): drop denied owned deliveries and partition mixed batches
snowykr 9497f59
feat(sdk): durable terminal marker, replay rows, and host delivery ou…
snowykr 9bfcb7f
chore(sdk): rebase cleanup — regenerate docs index, fix dev-side send…
snowykr 7b3b70a
fix(sdk): decide terminal success by terminalizePrompt outcome; await…
snowykr 7cedb07
fix(sdk): normalize terminal abort input before idempotency hashing
snowykr 15f3948
fix(sdk): fresh lineage epoch per root turn; durable conflicts as con…
snowykr 9bd8706
fix(sdk): guard response-state transition by terminal input hash
snowykr 851f0bd
fix(sdk): durably reserve idle terminal keys; register monitor jobs a…
snowykr 4117879
fix(sdk): defer resume lineage to admission; strict delivery-hook inp…
snowykr 37eca64
fix(sdk): fresh lineage at follow-up admission; preserve aborted epoc…
snowykr ac6bc7e
fix(sdk): session-relative resume epoch; gate hidden next-turn by the…
snowykr 6312cc8
fix(sdk): cancel pending preflights on terminal abort; drop owned-sto…
snowykr 4a0c76f
fix(sdk): invalidate the session preflight on terminal abort
snowykr a57e5c1
fix(sdk): preserve ownership for pre-abort async completions
snowykr 50ab00a
fix(sdk): drop denied owned-completion follow-ups; discard blocked hi…
snowykr 2091726
fix(sdk): rebind stale owned registrations; keep owned envelopes out …
snowykr 7e8e903
fix(sdk): cancel accepted-not-started prompts; bound durable terminal…
snowykr 57375f8
fix(sdk): finalize accepted pre-run aborts as cancelled, not fenced-u…
snowykr 7ec0920
fix(sdk): expose terminal abort seams on ExtensionContext
snowykr 264cde8
fix(sdk): clear hidden successors on skip/admission; reserve pre-run …
snowykr File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,117 @@ | ||
| # ADR: SDK terminal abort — turn-origin fence with owned-completion enablement | ||
|
|
||
| ## Decision | ||
|
|
||
| **ADOPT — origin-aware `TurnContinuationFence`/`TurnContinuationGate` plus normal owned-completion delivery.** | ||
|
|
||
| C04 `turn.abort` gains `mode:"terminal"` with typed `scope:"turn" | "owned"` (default `"turn"`) | ||
| and a required bounded idempotency key (≤128 UTF-8 bytes). Terminal abort stops the root | ||
| worker's current turn and blocks **only** that turn's own continuation routes; exact owned | ||
| background work (Bash/task jobs, detached subagents) that the caller deliberately leaves | ||
| running keeps running, and its completion/progress is delivered through the existing | ||
| `YieldQueue -> agent.followUp`/`agent.prompt` path as a **fresh** root turn with a new | ||
| attempt/lineage/worker epoch. | ||
|
|
||
| ## Prominent corrected design note (mandatory) | ||
|
|
||
| > **ADR/design note — turn abort is not owned-delivery abort.** `scope:"turn"` closes the root | ||
| > worker's current turn and its own continuation routes, while exact owned work remains | ||
| > runnable and its completion/progress results are intentionally delivered through the | ||
| > existing `YieldQueue -> AgentSession -> agent.followUp`/`agent.prompt` path. The delivery | ||
| > starts a fresh root turn with a new attempt/lineage. The earlier stage-04 no-successor fence | ||
| > that suppressed or deferred those deliveries was a misunderstanding: it defeated the reason | ||
| > to expose a leave-running option. **Do not reinstate it under another name.** | ||
|
|
||
| ## Naming rules | ||
|
|
||
| - Blocked routes are **turn-origin continuations**: `TurnContinuationFence`, | ||
| `TurnContinuationGate`, `blockedContinuationIds`, `predecessorTombstones`. The gate denies | ||
| only `turn-continuation` origins after close. | ||
| - Allowed left-running feedback is **owned-completion delivery**: `ownedCompletionPolicy`, | ||
| `ownedCompletionDelivery`, `resumeFromOwnedCompletion`, `OwnedCompletionEnvelope`. A closed | ||
| turn record never invalidates or denies an allowed owned-completion entry. | ||
| - **Prohibited names** (any code, test, or review text): `TurnDeliveryGate`, | ||
| `suppressOwnedDelivery`, `closedOwnedDeliveryFence`, `selectedDeliverySuppression`, | ||
| `deferredOwnedCompletion`, or any phrasing that says "closed turn means no owned-completion | ||
| delivery". Finding any is a hard implementation blocker. | ||
|
|
||
| ## Semantics | ||
|
|
||
| - `scope:"turn"` (default): `ownedWork:"left_running"`, `automaticDelivery:"enabled"`, | ||
| `resumeOnOwnedCompletion:true`. Owned work keeps running; an owned completion resumes the | ||
| root with a fresh attempt. Same-turn retry, TTSR/`agent.continue`, steering continuation, | ||
| hidden-next-turn, maintenance/worker successor, and accepted-pre-close same-attempt | ||
| continuations are blocked/tombstoned. | ||
| - `scope:"owned"`: additionally stops exact causal owned work with full quiescence proof and | ||
| foreign-work uncertainty; nothing resumes from stopped work (`automaticDelivery:"none"`, | ||
| `resumeOnOwnedCompletion:false`). | ||
| - Classification is **source/lineage-based, never timing-based**: the exact five-tuple | ||
| (endpoint generation, lineage hash, attempt epoch, job id, job generation) is recorded | ||
| before the job handle escapes; missing/mismatched metadata fails closed to ordinary. | ||
| - ultragoal/ralplan workflow stop is out of scope; ledgers/artifacts/handoffs stay untouched. | ||
| - No public surface widening: only the typed scope and bounded outcome metadata are exposed; | ||
| lineage/fence/ticket/envelope machinery is private to the SDK session layers. | ||
|
|
||
| ## Implementation state | ||
|
|
||
| Committed on `feat/abort-sdk-terminal` (lore `c04-terminal-*`), base `e92a04e3`: | ||
|
|
||
| - `c04-terminal-lineage`: lineage/attempt origin authority — per-turn lineage minted before | ||
| model execution, `beforeToolCall` binding, task/Bash `registerOwnedIfLineaged` five-tuple | ||
| capture; bounded registries, fail-closed. | ||
| - `c04-terminal-origin-delivery`: origin-aware async-result delivery — | ||
| `classifyOwnedCompletion` before formatting/artifact allocation, `OwnedCompletionEnvelope` | ||
| carrier, `resumeFromOwnedCompletion` fresh-attempt allocation; mandated boundary comments at | ||
| `sdk/session.ts`, `yield-queue.ts`, and both `agent-session.ts` injectors. | ||
| - `c04-terminal-surface`: `turn.abort` terminal surface wired to the durable prompt | ||
| terminalization; landed-terminal verification before claiming `stopped`; no-active-turn = | ||
| `terminal_no_effect`; unfencible = `terminal_uncertain`; turn dispositions as above. | ||
| - `c04-terminal-scope-registration`: terminal scope registered + synchronously closed at abort | ||
| (session `abortPromptAndWait` terminal option), epoch advanced so the fence never leaks onto | ||
| later turns; `classifyOwnedCompletion` live end to end. | ||
| - `c04-terminal-continuation-gate`: same-turn continuations denied at the final synchronous | ||
| boundary (skip reason `terminal_turn`); fail-open without a scope. | ||
| - `c04-terminal-durable-record`: bounded `DurableTerminalScopeRecord` (selection, fence, policy, | ||
| dispositions, response state, payload hash, key hash) through the v2 store; AC 5 no-store | ||
| gate; same-key replay via dispatch + durable key-hash lookup. | ||
| - `c04-terminal-owned-stop`: `scope:"owned"` generation-verified exact cancel, fixed grace, | ||
| second quiescence proof (generation-revalidated), delivery purge, `ownedWork:"stopped"` only | ||
| after proof; `settleOwnedWork` unit-tested; event metadata on the correlated `agent_end`. | ||
| - `c04-terminal-gate-authority`: gate requires the exact registered five-tuple (forged/ | ||
| unregistered denied); injectors drop denied owned-completion deliveries entirely (AC 36 | ||
| zero final calls) and allocate a fresh attempt only on `allow-new-turn`. | ||
|
|
||
| Durable contract status (AC 6/18/19/41/42): the record persists selection, the | ||
| continuation fence (epoch + tombstones + policy), dispositions, the | ||
| normalized-input and key hashes, response state, and `terminalPublished`. Same-key | ||
| replay/conflict is deterministic across dispatch-LRU eviction and restart (the v2 | ||
| store reloads terminal scopes from the single document), and response state | ||
| advances monotonic `pending -> sent` once the host writes the control response. | ||
| Not wired (tracked): a `pending -> failed` transition on host write rejection | ||
| (no surface-level host failure hook exists), a `sent -> delivered` transition | ||
| (client-acknowledgement protocol), and runtime re-hydration of the continuation | ||
| fence into the process registry. The last is architecturally bounded: lineage | ||
| registries are process-local and the per-session lineage secret regenerates on | ||
| restart, so a restarted session has NO lineage authority for a previous turn — | ||
| the plan's own AC 42 conditions fence installation on "runtime authority being | ||
| present", and missing authority failing closed (no auto-inject) is satisfied by | ||
| the durable replay/conflict gate alone. | ||
|
|
||
| ## Reviewer / implementer checklist (mandatory) | ||
|
|
||
| Answer these against any change to this feature: | ||
|
|
||
| 1. **Which origins are blocked?** Only `turn-continuation` origins of the aborted turn (same-turn | ||
| retry, TTSR/`agent.continue`, steering, hidden-next-turn, maintenance/worker successor, | ||
| accepted-pre-close same-attempt continuation). Not owned-completion, not foreign, not | ||
| ordinary. | ||
| 2. **Can a left-running owned completion reach `followUp`/`prompt`?** Yes — it must, through the | ||
| normal `YieldQueue` path, after a closed `turn` record, as a fresh turn. | ||
| 3. **Where is the fresh attempt allocated?** `AgentSession.#resumeFromOwnedCompletion` (fresh | ||
| `promptAttemptEpoch` + opaque lineage id) immediately before the existing | ||
| `followUp`/`prompt` call. It never reuses the aborted attempt's epoch. | ||
| 4. **Is any six-path observer turn-only?** No. Any `OwnedDeliverySettlementObserver` is | ||
| owned-scope-only proof of exact settlement; it never runs for a `turn` left-running | ||
| completion and never emits `suppressed`/`deferred` turn receipts. | ||
| 5. **Does any name imply suppressing owned delivery?** If yes (see prohibited names above), the | ||
| change is blocked pending a fresh intent decision. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
3 changes: 2 additions & 1 deletion
3
packages/coding-agent/src/internal-urls/docs-index.generated.ts
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.