Skip to content

land: pi-external-access-ask - #741

Queued
aft-alfonso[bot] wants to merge 12 commits into
mainfrom
land/pi-external-access-ask
Queued

aft-alfonso[bot] wants to merge 12 commits into
mainfrom
land/pi-external-access-ask

Conversation

@aft-alfonso

@aft-alfonso aft-alfonso Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Accepted agent delivery; branch-keyed search descriptor included.


Summary by cubic

Adds pi.external_access_ask (on by default) so Pi asks about outside-project file access only in its terminal UI, and headless sessions allow it instead of refusing it.

  • Print, JSON, and RPC sessions now read/write outside files without asking; previously they failed with a "no screen to show a prompt on" denial. Engine floors (sandbox.read_deny, restrict_to_project_root: true, credentials) still refuse in every mode.
  • Only the user config can turn the setting off; a project config may turn it on but never off, and is warned when it tries.
  • On OMP, AFT tools now declare approval tiers (read/write/exec) as a function of their arguments, so OMP's own tools.approvalMode decides when to prompt; calls naming a path outside the project report exec. The tier check follows symbolic links and parses hashline and apply_patch targets; unparseable or unresolvable cases report exec.
  • Tools registered after session start (the powershell slot and bash on live config reloads) now go through the registration funnel, keeping their OMP loadMode and approval tier.
  • Non-outside-path engine asks (bash rules, escalations, unknown kinds) are never auto-approved.
  • The Pi plugin config schema now accepts a pi block at all; previously any pi key failed validation and was dropped.

Written for commit d8f46e2. Summary will update on new commits.

View guided diff Turn on auto-fix

RetriggerView in GreptileConfidence Score: 5/5

The latest changes appear safe to merge; no new actionable issues were found.

Summary

Adds pi.external_access_ask and lets OMP decide when to ask through each tool’s declared tier.

  • Pi asks about outside-project access only in its terminal UI.
  • OMP asks based on each AFT tool call’s approval tier.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Initial registration, late PowerShell, or bash reload] --> B[Shared registration funnel]
  B --> C{Host}
  C -->|OMP| D[Attach loadMode and approval tier]
  C -->|Pi| E[Keep Pi tool metadata]
  D --> F[Register tool]
  E --> F
Loading

Reviews (4) · Last reviewed commit: "mason: re-register live bash through the..." · Reviewed by Greptile

ualtinok and others added 6 commits October 22, 2026 14:57
Plain Pi: outside-project access asks only in Pi's own terminal UI and only
while the new `pi.ask_outside_access` setting is on (default on). Off, or in a
print, JSON or RPC session, AFT approves the engine's outside ask itself, which
is the behaviour from before AFT asked: floors (credentials, CortexKit data,
sandbox.read_deny) and a configured restrict_to_project_root are engine
denials, never asks, so they still refuse. The "no screen to show a prompt on"
denial is removed, and nothing waits on an RPC client.

A project tier may turn the setting on but never off (TypeScript loaders and
the Rust resolver, which reports the dropped key). The Pi loader's schema now
accepts the `pi` block at all; before, any `pi` key (tool_presentation too)
failed validation and was dropped.

OMP: OMP does not tell extension tools its approval mode, so AFT never asks
there. Each AFT tool declares an OMP approval tier as a function of its
arguments (read / write / exec, and exec when a path argument is outside the
session's project), so OMP's own mode decides: prompts in write and
always-ask, never in yolo or --auto-approve. Upstream Pi gets no approval
field.

Two outside-permissions tests encoded the removed denial ("a refusal or
missing UI never sends approved IDs" for the no-context half, and "a session
without Pi's own screen is denied at once"); they now assert the decided
behaviour instead: no prompt, and the approved retry reads the file.

Co-authored-by: alfonso-aft <289616620+alfonso-aft@users.noreply.github.com>
Tools canonicalize alias spellings through their own prepareArguments, which
the tier check runs first; listing the alias kept a retired argument name in
source that the publication vocabulary audit refuses.

Co-authored-by: alfonso-aft <289616620+alfonso-aft@users.noreply.github.com>
… asks

docs/config.md and the Pi README describe the setting: on by default, only
user config can turn it off, print/JSON/RPC sessions never ask, and on OMP
OMP's tools.approvalMode decides with outside-path calls reported as exec.

The no-prompt branch approves only engine asks of kind external_directory
with outside: grant IDs (now a named predicate, isOutsideAccessAsk). A new
test feeds bash-rule, escalation, unknown-kind, mislabelled and mixed asks
through every mode and setting and asserts none is approved or prompted.

Co-authored-by: alfonso-aft <289616620+alfonso-aft@users.noreply.github.com>
The setting has not shipped, so there is no alias for the old name. Renamed in
both plugin config schemas and merges, the project-tier warning key, the Rust
RawPi field, merge and dropped-key name, build-schema.ts and the regenerated
aft.schema.json, docs/config.md, the Pi README, the release note and tests.

Co-authored-by: alfonso-aft <289616620+alfonso-aft@users.noreply.github.com>
Co-authored-by: alfonso-aft <289616620+alfonso-aft@users.noreply.github.com>
Co-authored-by: alfonso-aft <289616620+alfonso-aft@users.noreply.github.com>
Comment thread packages/pi-plugin/src/omp-approval.ts Outdated
Comment thread packages/pi-plugin/src/omp-approval.ts
ualtinok and others added 3 commits October 22, 2026 15:07
A hashline edit carries every target inside its patch string, so the tier
check saw no paths and a patch could edit an outside file or MV a project
file outside without OMP asking. Section headers and MV destinations
(docs/hashline.md) and apply_patch Add/Update/Delete/Move-to lines are now
checked like path arguments; a patch the check cannot parse is exec, so the
gate fails toward asking.

Co-authored-by: alfonso-aft <289616620+alfonso-aft@users.noreply.github.com>
The outside check compared only the written path, so an in-project link to an
outside file (or a path under a linked directory) stayed at its read or write
tier. Both the root and the target are now resolved to their real location
(realpathSync, or the nearest existing ancestor's real path plus the missing
components), synchronously; a resolution error other than not-found reports
exec, so the gate fails toward asking.

Co-authored-by: alfonso-aft <289616620+alfonso-aft@users.noreply.github.com>
Comment-only: the check reports exec for unresolvable paths and unreadable
patch targets, keeps the tool's tier for arguments its own preparation
rejects, and the patch scanners extract targets without validating the full
grammar.

Co-authored-by: alfonso-aft <289616620+alfonso-aft@users.noreply.github.com>
@ualtinok
ualtinok added this pull request to the merge queue Oct 22, 2026
Any commits made after this event will not be merged.
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Oct 22, 2026
ualtinok and others added 3 commits October 22, 2026 16:29
…t rule

The real-Pi RPC suite still expected the removed no-screen denial. RPC
sessions are never asked about outside access, so it now checks that an
existing outside file is read with its content and no prompt, a nonexistent
outside path gives the ordinary not-found result with no prompt, and a file
under ~/.local/share/cortexkit (a floor) is still refused.

Co-authored-by: alfonso-aft <289616620+alfonso-aft@users.noreply.github.com>
At session_start index.ts registered the powershell slot on the raw Pi API,
so on OMP it missed loadMode "essential" (OMP showed only a summary under
xd://) and its approval tier. registerLatePowershellTool binds the same funnel
as the first registration pass. The OMP top_level registration test now also
registers powershell after the first pass, through an OMP-shaped API, and
checks loadMode and tier on every tool.

Co-authored-by: alfonso-aft <289616620+alfonso-aft@users.noreply.github.com>
When a live config reload flipped bash.runon_enabled, index.ts registered
the replacement bash slot on the raw Pi API, so on OMP it lost loadMode
"essential" and its approval tier. reregisterBashTool binds the funnel
first. No other registration after the first pass reaches the raw API:
session_start powershell, the revision-read refresh and the first pass all
bind the funnel, and the config-error-state view sits beneath the funnel
(now stated in its comment and covered by a test).

Co-authored-by: alfonso-aft <289616620+alfonso-aft@users.noreply.github.com>
@ualtinok
ualtinok added this pull request to the merge queue Oct 22, 2026
Any commits made after this event will not be merged.
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.

1 participant