[Kernel][STOP] Confirm trusted-development cancellation only after owned process-group settlement #90

Closed
opened 2026-10-16 12:46:16 +00:00 by kilo · 3 comments
Member

Goal

Make a user-requested STOP in the currently supported foreground task run --approve --trusted-development path durable and truthful. Reuse the existing SIGINT/Ctrl-C cancellation path and report completion only after the exact owned Codex process group has a known cleanup outcome. This is a trusted-development task-control improvement, not an isolation or effect-expiry feature.

Why

The current path already latches SIGINT in the CLI, records cancel:<attempt> through task_execution, requests turn/interrupt, and uses CodexStdio's bounded SIGTERM/SIGKILL process-group cleanup. Keep and reuse those mechanisms.

There is a status-ordering gap to close: the trusted-development CodexRuntime is constructed without a retire or settled callback. A terminal Codex turn observation can therefore be recorded as cancellation terminal before the CLI's finally closes the CodexStdio connection and obtains its owned_group_settled result. The final user-visible cancelled result must not be stronger than the durable process-group evidence.

Scope

  • Scope only the existing foreground trusted-development task CLI and its SIGINT/Ctrl-C request. Do not add a new standalone STOP command, endpoint, process, or service.
  • Keep the signal handler as a flag/latch only. Process the request on the existing controller/SQLite owner thread; do not open a second SQLite writer or mutate state from the signal handler.
  • Reuse the existing cancel:<attempt> operation, exact attempt/operation/receipt binding, CodexRuntime.cancel, turn/interrupt, CodexStdio.close, and bounded owned-process-group SIGTERM/SIGKILL escalation.
  • Persist the cancellation request before interrupt/transport teardown. Feed the owned process-group cleanup result into durable cancellation reconciliation before reporting the final condition.
  • Treat a JSON-RPC interrupt acknowledgement, an interrupted turn, or the leader process exiting as insufficient proof by itself that the owned process group is settled.
  • Distinguish cancelled_no_dispatch, confirmed cancelled, and cancel_uncertain in exported state and CLI output. If the group remains, the outcome is unknown, or the result cannot be reconciled, preserve the workspace and original envelope; do not start a new Attempt, replay an uncertain interrupt, or claim rollback.
  • Bound the wait using the existing finite Codex RPC and process-group termination timeouts. Do not introduce a new timeout policy or unbounded wait.
  • Descendant claims are limited to the existing owned process group. If a child escaped that group or cannot be observed, report uncertainty; do not claim universal descendant termination in trusted-development mode.

Acceptance Criteria

  1. A synthetic SIGINT before dispatch records the cancellation against the exact Attempt/Operation, starts no worker, creates no runtime receipt, and returns cancelled_no_dispatch idempotently on recovery.
  2. A synthetic SIGINT during a blocking app-server request is handled within the existing finite request bound; durable cancellation intent is recorded before interrupt/close, and the exact original receipt is the only target.
  3. A fixture where the Codex leader exits while a child remains in the owned process group does not report cancelled until bounded group cleanup is confirmed. If the group remains after existing escalation, the result is cancel_uncertain and the workspace is retained.
  4. A fixture with an unobservable/escaped descendant is not described as fully settled; the user-facing/exported result reports uncertainty and does not trigger a retry or acceptance.
  5. Lost interrupt replies and crashes before/after cancellation receipt persistence recover without duplicate starts, blind interrupt replay, or a second SQLite writer. Existing single-writer and operation-fence invariants remain intact.
  6. User-facing output clearly distinguishes a requested/in-progress stop, confirmed owned-group cancellation, and uncertain outcome, and states that cancellation is not rollback.
  7. Tests use synthetic providers and fixtures only. No live inference, new service, standalone STOP API, privileged component, new cgroup policy, or change to TRUSTED_DEVELOPMENT semantics is needed.

Constraints

  • This issue supplies only the STOP/cancellation component of a task-level baseline, under accepted ADR 0011. It does not prove strict native effect expiry, universal mediation, hostile-worker containment, rollback, or full AC4 acceptance. During bounded termination local native effects may still occur; report unknown/unsettled descendants honestly and block acceptance/publication while uncertainty remains.
  • Do not turn an external STOP process into a concurrent SQLiteProgramStore writer. Any future out-of-process stop request would require an owner-thread command channel and separate authorization; it is outside this issue.
  • Preserve the exact cancellation target and unknown-outcome behavior. Never signal a foreign/shared process group.
  • No live/paid inference and no merge, release, or deployment authority is implied.
  • #48: existing bounded task lifecycle and cancellation mechanisms.
  • #53 / PR #85: historical strict-expiry delivery remains CLOSED / NOT IMPLEMENTED / UNMERGED; the diagnostic is evidence that strict native-effect expiry is unsupported, not a task-level acceptance receipt under ADR 0011.
  • Evidence reference at closeout: PR #85 head 9a38843eb948b2ab1c4c396786e5d9239f5d0394.
## Goal Make a user-requested STOP in the currently supported foreground `task run --approve --trusted-development` path durable and truthful. Reuse the existing SIGINT/Ctrl-C cancellation path and report completion only after the exact owned Codex process group has a known cleanup outcome. This is a trusted-development task-control improvement, not an isolation or effect-expiry feature. ## Why The current path already latches SIGINT in the CLI, records `cancel:<attempt>` through `task_execution`, requests `turn/interrupt`, and uses `CodexStdio`'s bounded SIGTERM/SIGKILL process-group cleanup. Keep and reuse those mechanisms. There is a status-ordering gap to close: the trusted-development `CodexRuntime` is constructed without a `retire` or `settled` callback. A terminal Codex turn observation can therefore be recorded as cancellation terminal before the CLI's `finally` closes the `CodexStdio` connection and obtains its `owned_group_settled` result. The final user-visible `cancelled` result must not be stronger than the durable process-group evidence. ## Scope - Scope only the existing foreground trusted-development task CLI and its SIGINT/Ctrl-C request. Do not add a new standalone STOP command, endpoint, process, or service. - Keep the signal handler as a flag/latch only. Process the request on the existing controller/SQLite owner thread; do not open a second SQLite writer or mutate state from the signal handler. - Reuse the existing `cancel:<attempt>` operation, exact attempt/operation/receipt binding, `CodexRuntime.cancel`, `turn/interrupt`, `CodexStdio.close`, and bounded owned-process-group SIGTERM/SIGKILL escalation. - Persist the cancellation request before interrupt/transport teardown. Feed the owned process-group cleanup result into durable cancellation reconciliation before reporting the final condition. - Treat a JSON-RPC interrupt acknowledgement, an interrupted turn, or the leader process exiting as insufficient proof by itself that the owned process group is settled. - Distinguish `cancelled_no_dispatch`, confirmed `cancelled`, and `cancel_uncertain` in exported state and CLI output. If the group remains, the outcome is unknown, or the result cannot be reconciled, preserve the workspace and original envelope; do not start a new Attempt, replay an uncertain interrupt, or claim rollback. - Bound the wait using the existing finite Codex RPC and process-group termination timeouts. Do not introduce a new timeout policy or unbounded wait. - Descendant claims are limited to the existing owned process group. If a child escaped that group or cannot be observed, report uncertainty; do not claim universal descendant termination in trusted-development mode. ## Acceptance Criteria 1. A synthetic SIGINT before dispatch records the cancellation against the exact Attempt/Operation, starts no worker, creates no runtime receipt, and returns `cancelled_no_dispatch` idempotently on recovery. 2. A synthetic SIGINT during a blocking app-server request is handled within the existing finite request bound; durable cancellation intent is recorded before interrupt/close, and the exact original receipt is the only target. 3. A fixture where the Codex leader exits while a child remains in the owned process group does not report `cancelled` until bounded group cleanup is confirmed. If the group remains after existing escalation, the result is `cancel_uncertain` and the workspace is retained. 4. A fixture with an unobservable/escaped descendant is not described as fully settled; the user-facing/exported result reports uncertainty and does not trigger a retry or acceptance. 5. Lost interrupt replies and crashes before/after cancellation receipt persistence recover without duplicate starts, blind interrupt replay, or a second SQLite writer. Existing single-writer and operation-fence invariants remain intact. 6. User-facing output clearly distinguishes a requested/in-progress stop, confirmed owned-group cancellation, and uncertain outcome, and states that cancellation is not rollback. 7. Tests use synthetic providers and fixtures only. No live inference, new service, standalone STOP API, privileged component, new cgroup policy, or change to `TRUSTED_DEVELOPMENT` semantics is needed. ## Constraints - This issue supplies only the STOP/cancellation component of a task-level baseline, under accepted ADR 0011. It does not prove strict native effect expiry, universal mediation, hostile-worker containment, rollback, or full AC4 acceptance. During bounded termination local native effects may still occur; report unknown/unsettled descendants honestly and block acceptance/publication while uncertainty remains. - Do not turn an external STOP process into a concurrent `SQLiteProgramStore` writer. Any future out-of-process stop request would require an owner-thread command channel and separate authorization; it is outside this issue. - Preserve the exact cancellation target and unknown-outcome behavior. Never signal a foreign/shared process group. - No live/paid inference and no merge, release, or deployment authority is implied. ## Links - #48: existing bounded task lifecycle and cancellation mechanisms. - #53 / PR #85: historical strict-expiry delivery remains CLOSED / NOT IMPLEMENTED / UNMERGED; the diagnostic is evidence that strict native-effect expiry is unsupported, not a task-level acceptance receipt under ADR 0011. - Evidence reference at closeout: PR #85 head `9a38843eb948b2ab1c4c396786e5d9239f5d0394`.
Author
Member

Implemented issue #90 in commit f1aee45a1ced51df24b5ff779192873c407a135c and opened PR #93: #93. Exact base/head: 40eea02cee517f7b31da01173739b23c510779b0 / f1aee45a1ced51df24b5ff779192873c407a135c. make check passed (1456 passed, 85 skipped, 106 subtests); make package-check passed. The change keeps uncertain or mismatched group outcomes unaccepted and does not claim rollback or universal descendant containment. No merge or issue closure.

Implemented issue #90 in commit `f1aee45a1ced51df24b5ff779192873c407a135c` and opened PR #93: https://forgejo.creatidy.com/Creatidy/creatidy-kernel/pulls/93. Exact base/head: `40eea02cee517f7b31da01173739b23c510779b0` / `f1aee45a1ced51df24b5ff779192873c407a135c`. `make check` passed (1456 passed, 85 skipped, 106 subtests); `make package-check` passed. The change keeps uncertain or mismatched group outcomes unaccepted and does not claim rollback or universal descendant containment. No merge or issue closure.
Author
Member

Review ordinal 3/10 identified and reproduced a P1: cleanup skipped surviving group children after the leader exited. Fixed in remediation commit 085c5c43f22da3e6b0ec61cce4d2914e5d018d36, with a regression that confirms bounded SIGTERM/SIGKILL escalation on the original group. Fresh make check passed (1457 passed, 85 skipped, 106 subtests) and make package-check passed. PR #93 is updated to head 085c5c43f22da3e6b0ec61cce4d2914e5d018d36; the branch remains unmerged and issue #90 remains open.

Review ordinal 3/10 identified and reproduced a P1: cleanup skipped surviving group children after the leader exited. Fixed in remediation commit `085c5c43f22da3e6b0ec61cce4d2914e5d018d36`, with a regression that confirms bounded SIGTERM/SIGKILL escalation on the original group. Fresh `make check` passed (1457 passed, 85 skipped, 106 subtests) and `make package-check` passed. PR #93 is updated to head `085c5c43f22da3e6b0ec61cce4d2914e5d018d36`; the branch remains unmerged and issue #90 remains open.
Author
Member

Integrated via PR #93. Forgejo records merge commit a7da7c788503edcec85af9485b1f72913be0e632 with first parent base 40eea02cee517f7b31da01173739b23c510779b0 and reviewed head 085c5c43f22da3e6b0ec61cce4d2914e5d018d36; the reviewed head is an ancestor of current develop. Exact-head PR workflow run #2913 succeeded. On the integrated merge commit, make check passed (1457 passed, 85 skipped, 106 subtests) and make package-check passed. Independent review ordinal 4/10 approved that exact head/base with no findings. Acceptance is limited to exact owned process-group cancellation; strict native-effect expiry, rollback and universal descendant containment remain unsupported/out of scope. Closing issue under the active /loop completion gate.

Integrated via PR #93. Forgejo records merge commit `a7da7c788503edcec85af9485b1f72913be0e632` with first parent base `40eea02cee517f7b31da01173739b23c510779b0` and reviewed head `085c5c43f22da3e6b0ec61cce4d2914e5d018d36`; the reviewed head is an ancestor of current `develop`. Exact-head PR workflow run #2913 succeeded. On the integrated merge commit, `make check` passed (1457 passed, 85 skipped, 106 subtests) and `make package-check` passed. Independent review ordinal 4/10 approved that exact head/base with no findings. Acceptance is limited to exact owned process-group cancellation; strict native-effect expiry, rollback and universal descendant containment remain unsupported/out of scope. Closing issue under the active /loop completion gate.
kilo closed this issue 2026-10-18 18:56:38 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Reference
Creatidy/creatidy-kernel#90
No description provided.