Repository navigation
feat(senpi-codemode): bind kernel tool invoker authority - #4390
Open
code-yeongyu wants to merge 8 commits into
Open
code-yeongyu wants to merge 8 commits into
code-yeongyu wants to merge 8 commits into
Conversation
code-yeongyu
marked this pull request as ready for review
October 26, 2026 15:33
This was referenced Oct 26, 2026
Keep no-session contexts on the owner-authority path and clear ambient invokers. Cover all supported context shapes across both dispatch runtimes, and approve only PR 4390 invocation gate additions.
Fold both LOW findings from the PR 4390 review. Registered handlers use their emitting session even inside a parent task. Cross-session errors identify the authority barrier and enforcing session rather than claiming an operation-specific rule match.
…port discovery Fold the two LOW findings from the #4387 delta review at 49d718a: - js-kernel-permission-interrupt.test.ts holds a host decision, interrupts, and asserts the active token word is dead before any result frame and the held write never lands. Replacing the interrupt-time #release with a plain registry delete fails it. - receivedPorts pushes collection entries one at a time, so a frame holding a port inside an array or Set past the engine's argument limit is delivered with the port working instead of degrading to messageerror. The transfer scenario adds a 3,000,000-element array row.
code-yeongyu
force-pushed
the
feat/kernel-tool-invoker-authority
branch
from
October 27, 2026 10:16
6bbda33 to
fb6ae1d
Compare
code-yeongyu
added a commit
that referenced
this pull request
Oct 27, 2026
…ation A live token with no deny rules kept its invoker binding when it was released, and the binding only went away at worker retirement. One finished cross-session call therefore let that invoker revoke and retire the owner's whole kernel long after the work was done, costing the owner its kernel state. The binding is now held per retained token and given back as soon as that token is dead, which closing the kernel makes true. A settled cross-session continuation that is still alive keeps its binding and stays revocable by its invoker, which the #4390 contract still pins. Folds the LOW from the #4390 delta review at fb6ae1d. Part of #4309.
code-yeongyu
added a commit
that referenced
this pull request
Oct 27, 2026
The fragment and the comment claimed the binding stopped outliving a finished cross-session call. It does not. A token released alive stays alive under #4387's rule, so it keeps its binding, and its invoker can still revoke and retire the owner's kernel until the kernel closes; closing is what ends those tokens and returns their bindings. Both halves are pinned by the existing contract, which asserts the retirement still lands right after release and no longer lands once the kernel has closed. Tying the binding to the continuation itself is not available: node:async_hooks createHook emits no init or destroy callbacks under Bun 1.4.4, so nothing reports when the continuation finishes, and releasing on a guessed signal would drop revocability that #4390 requires. Part of #4309.
…l-tool-invoker-authority
Session replacement (8c749e5 on main) emits session_extensions_removed on the old runner after it is invalidated. The #4390 handler wrapper read context.sessionManager first, whose guarded getter throws StaleExtensionContextError, so the removed extension's handler never ran. The wrapper now resolves the handler's session without letting a stale context abort the dispatch: a stale context binds no invoker and runs the handler under kernelToolInvokerStorage.exit, so it never borrows the emitting scope's identity, and the context's own guarded getters (kernelTools included) still refuse it. Other errors still propagate.
code-yeongyu
added a commit
that referenced
this pull request
Oct 27, 2026
code-yeongyu
added a commit
that referenced
this pull request
Oct 28, 2026
This branch has not been deployed
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Summary
Part of #4309.
Stacked on #4387 at
42e0e2707c118b438da2414f5dc22496e619976e; the base isfeat/eval-kernel-permission-core, notmain.invokeroptions; tool arguments remain ordinary data.permissions.resolveSessionseam lets the permission integration resolve sessions that have never opened a kernel. As in PR 2, connecting the real permission extension remains integration work; an unregistered session without that resolver retains the core's inactive behavior.Evidence (initial implementation)
bun run checkpassed.tool_child_bootstrap_failed: exited_before_ready; the same test fails at the untouched parent commit42e0e2707c. Its other six tests pass. No test was weakened.The CLI harness needed the inherited
SENPI_RPC_INTERNAL_KEY_STDINbootstrap flag removed from its subprocess environment. This is a QA-launcher isolation detail, not a product change.QA artifacts are retained locally under
local-ignore/qa-evidence/20261027-pr2b-invoker/:Known limitation: reads performed by the runtime's native module resolver (bare packages, tsconfig aliases, package.json #imports, symlinked packages) are not covered by this work; tracked in #4380.
Kept draft.
CI fold
Pushed
6bbda331f92ca96045ea6a2ef735be8cb678399awithout restacking. The parent remains42e0e2707c118b438da2414f5dc22496e619976e. The CI repair isb4f1d54737; the subsequent review-LOW fold is6bbda331f9.child-dispatch.test.tsreads an unavailablectx.sessionManager; bothobserver-failure.test.tsruntimes throw atgetSessionIdinvocation-authority.tsimport memberships and 16 invocation-contract approvals undersenpi#4390, including three review-fold metadata cases. No baseline cell, historical outcome, or prior approval was removed or changed.reviewBaselineChangesreturns zero failures; the comparison has zero unapproved additions owned by this PR. Cold base/head import measurements differ by exactlyinvocation-authority.tsin each scope.node: eval bootstrap was not delivered42e0e2707c; the original child/observer tests pass there, 6/6.Permission authority not initializedatgate-import-observer.ts:1242e0e2707c. The separate membership measurement uses the repaired upstream observer against both unchanged source targets; it is not represented as a passing canonical gate.42e0e2707c. The nine inherited permission-core import memberships are also present at that base.Bun.spawnSyncinterrupt assertionValidation:
bun run check: passed, as did the normal pre-commit formatting/lint/typecheck hook.--maxWorkers=4: all 51 files and 1,186 tests passed. The earlier uncapped run had 1,184 passes and two RPC deadline failures; both files passed all seven focused tests at base and head before the final clean full run.src/core/tool-dispatchtest gate, full codemode package test gate, and exact additive-approval review each returned 0; push returned 0.6bbda331f92ca96045ea6a2ef735be8cb678399acompleted FAIL (240 prompt cells, 5 runtimes). Remaining failures are the inherited import-observer failure/unmeasured imports, 21 inherited permission-core contract additions, and three local Julia JSON-byte ordering mismatches. The three Julia witnesses have identical decoded JSON values to the baseline; the comparison remains unchanged. The gate recorded 2,262 legacy contract outcomes and no unapproved additions owned by feat(senpi-codemode): bind kernel tool invoker authority #4390. The initial base/head attempts hit the local ten-minute watcher deadline; their incomplete output is not counted as a gate result.Gate-review method: read the repository's gate implementation and baseline-review instructions; use the final focused JSON report's 16 passing invocation contracts plus cold import measurements of this head and the pinned base. Only the import observer comes from the already-repaired upstream harness. The committed baseline receives two measured membership additions only; every non-import baseline section and every existing allowlist node is unchanged.
Local evidence is retained under
local-ignore/qa-evidence/20261027-pr4390-ci-fold/. Decisive SHA-256 receipts:CLEAR review LOWs
The receipt for original head
353b6038b735b823f523e04195c6fa6cc3a0895areported CLEAR / APPROVE-WITH-NITS, with no CRITICAL/HIGH/MEDIUM findings and two LOWs. Both are folded; neither is deferred.rules[0]as though that rule matched the invoked operation.reason: "cross_session_authority"andenforcingSessionId; the message/documentation identifyruleas an example activating deny rule, not a match against the unexecuted body. Refusal behavior and the existingruleidentity remain compatible.The CLEAR receipt applies to the original head only. No new review verdict is claimed for
6bbda331f9.