Skip to content

fix(server): stop a Pi approval from outliving its session - #16854

Open
Adamulek123 wants to merge 4 commits into
pingdotgg:mainfrom
Adamulek123:fix/v2-pi-approval-session-scope
Open

Adamulek123 wants to merge 4 commits into
pingdotgg:mainfrom
Adamulek123:fix/v2-pi-approval-session-scope

Conversation

@Adamulek123

@Adamulek123 Adamulek123 commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Pi kept session-wide approval grants when the same connection switched to another native Pi session. A matching confirmation in that new session could reuse the earlier grant silently. Clear grants and cancel pending prompts at session registration and rollback boundaries. Ignore late responses to cancelled prompts, and clear grants when turn finalization reports a different or unreadable session identity. Reuse a successful settle probe's state response; keep the existing title/message approval key.

The shared server behavior applies to web, desktop, and mobile.

Scope and approval

Submitted for consideration under the focused obvious-bug exception. A grant for one native Pi session could silently approve an identical prompt after switching sessions. Revoking grants at those boundaries and when session identity cannot be verified fixes that single defect. Only the Pi adapter and its tests change; approval matching within a verified unchanged session stays the same.

No prior maintainer approval is claimed. Macroscope requires human review because this touches the approval boundary. CodeRabbit approval and passing CI do not replace that review.

Verification

  • Independent gpt-6.1-sol verification on 2026-10-08 first reran all 63 tests at the previous head, then integrated main cdd331b and reran all 79 Pi adapter tests successfully. Current main's native-wake ownership, rollback-barrier, and model-selection behavior is preserved.
  • The unreadable-identity case forces both state reads to fail, awaits the terminal event, and races a fresh approval request against an automatic response. A readable unchanged session preserves its grant. The earlier implementation round verified that retaining grants on unreadable identity makes this test fail; that mutation check was not rerun in this round.
  • Targeted type-aware/type-check lint exits zero with the existing unused-layer warning. Server-only TypeScript checking exits zero with no type errors and non-blocking Effect suggestions. Both changed files pass formatting and the PR delta passes whitespace checks.

The simple/pi replay failed on Windows in the earlier verification at both this branch and its actual base commit, with escaped command arguments that do not match the fixture. No live Pi or client pass was run, and native slash-command session switching was not verified. Identical title/message prompts still share grants within one native session.

Implemented with gpt-6.1-sol through the Codex harness.

Pi kept session approvals across thread switches and rollback, so a
permission granted in one thread could silently authorize a later thread.

Clear approvals and cancel pending prompts at session boundaries, reject
late cancelled-prompt responses, and check the bound session at turn
finalize. Key approvals by every payload field except the request id in
canonical order, with wire-level regression coverage for all boundaries.

Model: gpt-6.1-sol (Codex)
@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Oct 7, 2026
The audit found that the expanded approval key cannot distinguish real Pi
confirm payloads, and the metadata test fabricated an unsupported field.
Restore the original title/message key, remove that case and its redundant
wire assertion, and preserve the runtime_request.updated assertions.

Defer the transport send to test cancellation during thread replacement and
empty rollback. Both cases fail when the adapter's late-response guard is
removed. Reuse successful settle-probe state during finalization, and test
same-session reuse, foreign-session invalidation, and failed-probe fallback.

Keep the existing authorization fix, boundary clearing, pending-prompt
cancellation, and late-response guard. Leave user-visible prompt text and
state lookups on finalization paths without a successful probe alone.

Model: gpt-6.1-sol (Codex)
@Adamulek123
Adamulek123 marked this pull request as ready for review October 7, 2026 21:01
@macroscopeapp

macroscopeapp Bot commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — The PR fixes session-scoped Pi approvals and adds strong race and failure-path coverage, but it changes authorization behavior on existing server request paths. Because it can determine whether extension work proceeds silently or requires renewed confirmation, the approval boundary merits human review.

You can add or adjust custom eligibility rules. Learn more.

@coderabbitai

coderabbitai Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Path: .coderabbit.config.ts
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: d541d1c4-57d7-472f-8920-39dce5a1c768
📥 Commits

Reviewing files that changed from the base of the PR and between d9364c2 and 21e3ded.

📒 Files selected for processing (2)
  • apps/server/src/orchestration-v2/Adapters/PiAdapterV2.test.ts
  • apps/server/src/orchestration-v2/Adapters/PiAdapterV2.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 8 remain after this review.


📝 Walkthrough

Walkthrough

PiAdapterV2 now checks cached session approvals against Pi session state during turn finalization. Thread registration and rollback clear approvals and cancel pending prompts. Runtime-request handling stops if a prompt is removed while its response is sending.

Changes

Pi session approval lifecycle

Layer / File(s) Summary
Validate approvals against turn session
apps/server/src/orchestration-v2/Adapters/PiAdapterV2.ts, apps/server/src/orchestration-v2/Adapters/PiAdapterV2.test.ts
Turn finalization checks cached approvals against supplied or fetched Pi state. Tests cover matching confirmation content, unchanged and changed sessions, and failed state reads.
Clear approvals at session boundaries
apps/server/src/orchestration-v2/Adapters/PiAdapterV2.ts, apps/server/src/orchestration-v2/Adapters/PiAdapterV2.test.ts
Thread registration and rollback clear approvals and cancel pending prompts. Runtime-request handling stops if a prompt was removed during sending. Tests cover session boundaries and delayed approval responses.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix

Suggested reviewers: juliusmarminge

Merge Risk: ⚪ Minimal · up to 21e3d

No actionable regression attributable to this change was established. The PR is mergeable after normal checks.

Security Architecture Review

Security architecture risk: 🔵 Low · up to 21e3d

The change narrows approval reuse across sessions, with no demonstrated new authorization bypass. Remaining uncertainty concerns whether delayed approval responses are safely rejected after cancellation.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The demonstrated authority is automatic confirmation of matching prompts within a Pi session runtime. The approval state is local, not a shared tenant-wide grant store. Native downstream privileges and the maximum affected asset scope are not established by the supplied evidence.

Security Findings and Attack Paths

  • inferred — A native session change followed by an identical confirmation before finalization can still encounter the cached-grant lookup. The base already had that lookup and forwarded session-changing prompts; the PR narrows later reuse without demonstrating that it introduced or worsened this pre-existing window.
  • observed — The delayed-send test observes cancellation followed by a confirmed response with the same native request ID. It proves that local grants are not restored, but its fake does not establish whether native Pi rejects the late confirmation. This is an unresolved consumer-contract gap, not a verified new exploit.

Trust Boundaries and Controls

  • observed — The adapter uses native sessionFile metadata to decide whether existing approval authority survives finalization. Local revocation and pending-object identity checks protect adapter state; the fire-and-forget response interface provides no acknowledgement of native cancellation enforcement.

Resilience and Maintainability Implications

  • observed — Tests cover grant revocation at session and rollback boundaries, delayed responses, unchanged-session retention, foreign identity, and failure of both identity reads. These provide evidence for local recovery and revocation behavior, but do not replace native-consumer validation.

Hardening Proposals

  • proposed — Establish and validate the native contract for stale-response rejection, prompt-ID isolation, and competing cancellation and confirmation messages before treating local cancellation as an end-to-end authorization guarantee.
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly and concisely identifies the main change: preventing Pi approval grants from outliving their native session.
Description check ✅ Passed The description explains the problem, fix, scope, approval exception, verification results, limitations, and review requirements. The problem and change details appear before the section headings inst…
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

aliceisjustplaying added a commit to aliceisjustplaying/t3code that referenced this pull request Oct 8, 2026
Keep upstream migration IDs 59 and 60; move YSK to 61 and repair historical fork ledgers atomically after applying missing schema changes.

Adapt selected upstream fixes for Pi approvals, MCP images, workspace discovery, provider worker starvation, concurrent worktree launches, primary runtime ownership, session refresh, DPoP URLs and embedded-render scrolling. Preserve fork lifecycle and notice behavior, and close the approval and authentication gaps found in review.

Adapted from pingdotgg#16854, pingdotgg#15879, pingdotgg#17190, pingdotgg#16790, pingdotgg#17197, pingdotgg#17172, pingdotgg#17075, pingdotgg#17037, pingdotgg#17065.

Co-authored-by: Adamulek123 <adam.bogucki2018@gmail.com>
Co-authored-by: anntnzrb <anntnzrb@proton.me>
Co-authored-by: Wout Stiens <71498452+StiensWout@users.noreply.github.com>
Co-authored-by: Lakshmi Tanmay <lakshmi@voltcrash.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Jake Leventhal <jakeleventhal@me.com>
Co-authored-by: Malte Sussdorff <malte.sussdorff@cognovis.de>
Co-authored-by: sheehanmunim <sheehanmunim@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Dara Adedeji <daraadedeji07@gmail.com>
Co-authored-by: Joseph Vidal <josephv4000@gmail.com>

This branch has not been deployed

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

Labels

size:M 30-99 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant