@erichll/pi-auto-review 0.3.5 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +37 -0
- package/README.md +184 -179
- package/package.json +8 -8
- package/src/broker/broker.ts +5 -5
- package/src/config.json +2 -1
- package/src/index.ts +1221 -113
- package/src/policy.ts +1206 -82
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,42 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.5.0 - 2026-08-20
|
|
4
|
+
|
|
5
|
+
- **Safer evidence selection.** Review only request-linked tool calls, paired
|
|
6
|
+
results, current-task user intent, and bounded security evidence. Compaction
|
|
7
|
+
summaries cannot restore authorization, raw revocations override model
|
|
8
|
+
allows, and missing mandatory evidence fails closed before a model call.
|
|
9
|
+
- **Independent, smaller reviewer requests.** Use one compact canonical request
|
|
10
|
+
envelope and a byte-stable policy prefix, reducing fixed input from 2,011 to
|
|
11
|
+
1,396 characters. Independent SSE calls prevent prior review state from
|
|
12
|
+
carrying into later approvals while preserving cache/routing identity.
|
|
13
|
+
- **Explicit token limits.** Add tighten-only `maxReviewerInputTokens` with an
|
|
14
|
+
8,192 default and conservative UTF-8 accounting across the complete prompt.
|
|
15
|
+
Lower the default `maxTokens` from 1,600 to 256 after sequential real-model
|
|
16
|
+
validation at 384 and 256; the legal range remains 256–4,096.
|
|
17
|
+
- **Typed, bounded retries.** Share one deadline across each review, disable
|
|
18
|
+
provider-internal retries, and allow at most two actual model calls. Only
|
|
19
|
+
format errors, recognized connection/5xx failures, and bounded 429 responses
|
|
20
|
+
retry; deterministic and unknown failures remain terminal and fail closed.
|
|
21
|
+
- **Privacy-bounded telemetry.** Record per-attempt usage and per-review
|
|
22
|
+
summaries for both reviewer entry points using stable status/error codes and
|
|
23
|
+
prompt-part counts, without logging evidence text, provider errors,
|
|
24
|
+
credentials, headers, or URL query values.
|
|
25
|
+
|
|
26
|
+
## 0.4.0 - 2026-08-19
|
|
27
|
+
|
|
28
|
+
- **Credential-exfiltration hardening.** Expand deterministic terminal denies to cover
|
|
29
|
+
`.env` variants, common credential files, additional file readers and encoders,
|
|
30
|
+
shell substitutions, staged variables, redirects, and multi-stage pipelines that
|
|
31
|
+
upload credentials to network sinks. Template files such as `.env.example` and
|
|
32
|
+
`.env.sample` remain reviewable.
|
|
33
|
+
- **Reviewer refresh safety.** Re-resolve reviewer model/provider metadata for each
|
|
34
|
+
review, reacquire authentication for each attempt, and bind the reviewer session
|
|
35
|
+
identity to the endpoint and authentication fingerprint so provider or OAuth
|
|
36
|
+
refreshes cannot reuse a stale connection.
|
|
37
|
+
- **Compatibility.** Require Pi 0.84.1+ and permission-system 25.1.0+ to match the
|
|
38
|
+
current reviewer and forwarded-permission contracts.
|
|
39
|
+
|
|
3
40
|
## 0.3.5 - 2026-08-13
|
|
4
41
|
|
|
5
42
|
- Raise the default model-review `timeoutMs` from 45s to 90s and the default
|
package/README.md
CHANGED
|
@@ -1,139 +1,138 @@
|
|
|
1
1
|
# @erichll/pi-auto-review
|
|
2
2
|
|
|
3
|
-
A model-backed boundary
|
|
3
|
+
A fail-closed, model-backed boundary reviewer for the Pi coding agent.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
filesystem and network boundary requests without creating a second approval
|
|
9
|
-
system.
|
|
5
|
+
The extension participates in `@gotgenes/pi-permission-system` as the
|
|
6
|
+
`pi-auto-review` authorizer and exposes a process-local broker for OS sandbox
|
|
7
|
+
adapters. The npm package and reviewer model have separate names:
|
|
10
8
|
|
|
11
|
-
|
|
9
|
+
- package: `@erichll/pi-auto-review`
|
|
10
|
+
- authorizer: `pi-auto-review`
|
|
11
|
+
- default reviewer model: `codex-auto-review`
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
## Install and enable
|
|
14
|
+
|
|
15
|
+
Install the package outside the agent-writable workspace:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
pi install npm:@erichll/pi-auto-review
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Add it to the permission-system authorizer chain:
|
|
22
|
+
|
|
23
|
+
```json
|
|
24
|
+
{
|
|
25
|
+
"authorizerChain": ["pi-auto-review"]
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
The configured reviewer provider and model must also be registered in Pi.
|
|
16
30
|
|
|
17
31
|
## Security model
|
|
18
32
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
1.
|
|
22
|
-
2.
|
|
23
|
-
3.
|
|
24
|
-
4.
|
|
25
|
-
|
|
26
|
-
Model approval cannot override `pi-permission-system`'s bounded-delegation
|
|
27
|
-
checkpoint. In version 24, an authorizer's `allow` on `path` or
|
|
28
|
-
`external_directory` is still downgraded to `defer`. In an interactive v24 TUI,
|
|
29
|
-
`autoConfirmBoundedAllows` can bind that exact model allow to the immediately
|
|
30
|
-
following local permission dialog and complete it as `auto_approved`. The
|
|
31
|
-
default enables this bridge only for `external_directory`; `path`, non-TUI
|
|
32
|
-
modes, UI mismatches, and reviewer defers still reach the human terminal.
|
|
33
|
-
Sandbox adapters should use concrete surfaces such as `filesystem-read`,
|
|
34
|
-
`filesystem-write`, and `network`.
|
|
35
|
-
|
|
36
|
-
The TUI bridge is request-ID-bound, expires after ten seconds, is consumed
|
|
37
|
-
once, and recognizes the v24 inline permission component before completing it.
|
|
38
|
-
Any event ordering, request, mode, component, or shared-UI wrapper mismatch
|
|
39
|
-
fails closed to the original dialog. This is a compatibility bridge around the
|
|
40
|
-
v24 delegation envelope, not permission-system authority-chain API.
|
|
41
|
-
|
|
42
|
-
The broker stops automatic review for a turn after three consecutive denials
|
|
43
|
-
or ten denials in the rolling last fifty reviews. An explicit denial is
|
|
44
|
-
returned to the agent with an instruction not to pursue the same outcome
|
|
45
|
-
through a workaround.
|
|
46
|
-
|
|
47
|
-
## User-facing feedback
|
|
48
|
-
|
|
49
|
-
In interactive UI sessions, the extension shows short operator feedback that is
|
|
50
|
-
separate from agent denial reasons:
|
|
51
|
-
|
|
52
|
-
1. Footer status while review is in flight:
|
|
53
|
-
`auto-review: reviewing <surface> · <target>`
|
|
54
|
-
2. A toast when the decision lands:
|
|
55
|
-
- allowed
|
|
56
|
-
- allowed + auto-confirming the local dialog
|
|
57
|
-
- allowed but local confirmation still required
|
|
58
|
-
- deferred to you
|
|
59
|
-
- denied
|
|
60
|
-
- circuit-breaker stopped after repeated denials
|
|
61
|
-
|
|
62
|
-
These notices are best-effort UX only; missing or broken UI delivery never
|
|
63
|
-
changes the security decision.
|
|
64
|
-
|
|
65
|
-
## Exact human retry override
|
|
66
|
-
|
|
67
|
-
In interactive TUI mode, `/approve` shows up to ten recent model denials from
|
|
68
|
-
the current session. Selecting one authorizes exactly one unchanged retry and
|
|
69
|
-
automatically asks the agent to perform it. The authorization:
|
|
70
|
-
|
|
71
|
-
- is bound to the complete request hash, including cwd, command, requested and
|
|
72
|
-
resolved paths, destination, tool input, and agent;
|
|
73
|
-
- expires after 60 seconds and is consumed once;
|
|
74
|
-
- is passed to the reviewer as a separate host-generated
|
|
75
|
-
`trusted-user-override` evidence block;
|
|
76
|
-
- does not directly allow anything—the reviewer can still deny or defer; and
|
|
77
|
-
- is checked only after deterministic hard denies, so critical tenant and
|
|
78
|
-
security-control policy cannot be overridden.
|
|
33
|
+
Requests pass through these controls in order:
|
|
34
|
+
|
|
35
|
+
1. deterministic hard denies;
|
|
36
|
+
2. bounded model review;
|
|
37
|
+
3. the local permission terminal when required; and
|
|
38
|
+
4. an exact, expiring, one-use grant for an external sandbox adapter.
|
|
79
39
|
|
|
80
|
-
|
|
81
|
-
|
|
40
|
+
The model cannot override hard denies or grant authority directly. External
|
|
41
|
+
adapters must consume the exact grant before retrying an operation. Changing
|
|
42
|
+
the command, path, resolved path, destination, cwd, agent, or tool input
|
|
43
|
+
invalidates that grant.
|
|
82
44
|
|
|
83
|
-
|
|
45
|
+
Permission-system v24 downgrades authorizer allows on `path` and
|
|
46
|
+
`external_directory` to `defer`. In an interactive TUI,
|
|
47
|
+
`autoConfirmBoundedAllows` can bind the exact model allow to the immediately
|
|
48
|
+
following recognized permission dialog. The bridge is request-ID-bound,
|
|
49
|
+
expires after ten seconds, and is consumed once. Mode, component, request, or
|
|
50
|
+
event-order mismatches leave the original human dialog in place.
|
|
84
51
|
|
|
85
|
-
|
|
52
|
+
Automatic review stops for the current turn after three consecutive denials or
|
|
53
|
+
ten denials in the last fifty reviews. An explicit denial tells the agent not
|
|
54
|
+
to pursue the same outcome through a workaround.
|
|
86
55
|
|
|
87
|
-
|
|
88
|
-
2. Optional user-global overlay at
|
|
89
|
-
`~/.pi/agent/extensions/pi-auto-review/config.json`
|
|
90
|
-
3. Optional project tighten-only file at `.pi/pi-auto-review.json`
|
|
56
|
+
## Configuration
|
|
91
57
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
58
|
+
Configuration is resolved in this order:
|
|
59
|
+
|
|
60
|
+
1. package defaults in `src/config.json`;
|
|
61
|
+
2. optional trusted user overlay at
|
|
62
|
+
`~/.pi/agent/extensions/pi-auto-review/config.json`; and
|
|
63
|
+
3. optional project tighten-only settings at `.pi/pi-auto-review.json`.
|
|
64
|
+
|
|
65
|
+
Use the user-global file for normal customization. It may set any legal key:
|
|
95
66
|
|
|
96
67
|
```json
|
|
97
|
-
// ~/.pi/agent/extensions/pi-auto-review/config.json
|
|
98
68
|
{
|
|
69
|
+
"model": "provider/reviewer-model",
|
|
99
70
|
"autoConfirmBoundedAllows": ["external_directory", "path"]
|
|
100
71
|
}
|
|
101
72
|
```
|
|
102
73
|
|
|
103
|
-
Package
|
|
74
|
+
Package defaults:
|
|
104
75
|
|
|
105
76
|
```json
|
|
106
77
|
{
|
|
107
78
|
"model": "codex-auto-review",
|
|
108
79
|
"reasoning": "low",
|
|
109
|
-
"timeoutMs":
|
|
110
|
-
"maxTokens":
|
|
111
|
-
"retries":
|
|
80
|
+
"timeoutMs": 90000,
|
|
81
|
+
"maxTokens": 256,
|
|
82
|
+
"retries": 2,
|
|
112
83
|
"maxUserTranscriptTokens": 1200,
|
|
113
84
|
"maxToolTranscriptTokens": 1200,
|
|
114
85
|
"maxRelevantResultTokens": 800,
|
|
86
|
+
"maxReviewerInputTokens": 8192,
|
|
115
87
|
"failureMode": "deny",
|
|
116
88
|
"grantTtlMs": 60000,
|
|
117
89
|
"autoConfirmBoundedAllows": ["external_directory", "path"]
|
|
118
90
|
}
|
|
119
91
|
```
|
|
120
92
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
Set `autoConfirmBoundedAllows` to `[]` to keep every bounded allow manual, or
|
|
125
|
-
include `"path"` as well to opt into the same TUI bridge for the cross-cutting
|
|
126
|
-
path surface.
|
|
93
|
+
`failureMode: "deny"` is the default. `"defer"` falls through to the human
|
|
94
|
+
terminal. Set `autoConfirmBoundedAllows` to `[]` to keep every bounded allow
|
|
95
|
+
manual.
|
|
127
96
|
|
|
128
|
-
|
|
97
|
+
Project configuration may only lower timeouts, token/evidence limits, retries,
|
|
98
|
+
and grant TTL, set `failureMode` to `"deny"`, or remove auto-confirmed
|
|
99
|
+
surfaces. It cannot select a model, raise a trusted limit, or weaken fail-closed
|
|
100
|
+
behavior. Invalid configuration disables the reviewer for that session.
|
|
129
101
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
102
|
+
### Deadlines and retries
|
|
103
|
+
|
|
104
|
+
`timeoutMs` is one deadline shared by model resolution, authentication, model
|
|
105
|
+
attempts, and retry delays. Each attempt receives only the remaining time.
|
|
106
|
+
Provider-internal retries are disabled, and a review makes at most two actual
|
|
107
|
+
model calls even when the public `retries` value is higher.
|
|
135
108
|
|
|
136
|
-
|
|
109
|
+
Valid decisions, output-length stops, timeouts, aborts, authentication/model/
|
|
110
|
+
request errors, and unknown failures do not retry. Empty, non-JSON, or
|
|
111
|
+
schema-invalid output and recognized connection, temporary 5xx, or 429
|
|
112
|
+
failures may retry once when the retry budget and deadline allow it. A
|
|
113
|
+
`Retry-After` above five seconds or beyond the remaining deadline fails closed.
|
|
114
|
+
Format retries preserve the canonical request and selected evidence and append
|
|
115
|
+
only a fixed, budget-checked schema correction.
|
|
116
|
+
|
|
117
|
+
## Operator feedback and exact retry
|
|
118
|
+
|
|
119
|
+
Interactive sessions show a best-effort footer while review is running and a
|
|
120
|
+
short result toast for allow, local confirmation, defer, deny, or circuit
|
|
121
|
+
breaker outcomes. UI delivery never changes the authorization result.
|
|
122
|
+
|
|
123
|
+
In an interactive TUI, `/approve` lists up to ten recent model denials from the
|
|
124
|
+
current session. Selecting one asks the agent to retry exactly that request.
|
|
125
|
+
The host-generated override:
|
|
126
|
+
|
|
127
|
+
- binds the complete request hash;
|
|
128
|
+
- expires after 60 seconds and is consumed once;
|
|
129
|
+
- remains separate from untrusted user/tool evidence;
|
|
130
|
+
- still goes through deterministic hard denies and model review; and
|
|
131
|
+
- cannot be reissued for the same request semantics in that session.
|
|
132
|
+
|
|
133
|
+
It is authorization evidence, not a direct allow.
|
|
134
|
+
|
|
135
|
+
## Boundary broker API
|
|
137
136
|
|
|
138
137
|
The extension publishes a process-local service at:
|
|
139
138
|
|
|
@@ -141,7 +140,7 @@ The extension publishes a process-local service at:
|
|
|
141
140
|
Symbol.for("pi-auto-review:boundary-approval-broker")
|
|
142
141
|
```
|
|
143
142
|
|
|
144
|
-
Adapters should
|
|
143
|
+
Adapters should use the exported helper:
|
|
145
144
|
|
|
146
145
|
```ts
|
|
147
146
|
import {
|
|
@@ -156,118 +155,124 @@ const request: BoundaryRequest = {
|
|
|
156
155
|
operation: "connect",
|
|
157
156
|
cwd: "/workspace/project",
|
|
158
157
|
command: "npm install",
|
|
159
|
-
destination: "registry.npmjs.org:443"
|
|
158
|
+
destination: "registry.npmjs.org:443",
|
|
160
159
|
};
|
|
161
160
|
|
|
162
|
-
const
|
|
163
|
-
const decision = await
|
|
161
|
+
const broker = getBoundaryBroker();
|
|
162
|
+
const decision = await broker?.review(request, {
|
|
164
163
|
sessionId: "pi-session-id",
|
|
165
164
|
scopeKey: "pi-session-id:turn-id",
|
|
166
|
-
issueGrant: true
|
|
165
|
+
issueGrant: true,
|
|
167
166
|
});
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
When `decision.kind` is `allow`, an external sandbox adapter must consume the
|
|
171
|
-
returned grant before retrying:
|
|
172
167
|
|
|
173
|
-
```ts
|
|
174
168
|
if (
|
|
175
169
|
decision?.kind === "allow" &&
|
|
176
170
|
decision.grant &&
|
|
177
|
-
|
|
171
|
+
broker?.consumeGrant(request, "pi-session-id", decision.grant.token)
|
|
178
172
|
) {
|
|
179
173
|
// Retry this exact operation once inside the OS sandbox.
|
|
180
174
|
}
|
|
181
175
|
```
|
|
182
176
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
-
|
|
194
|
-
a
|
|
195
|
-
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
Unrelated
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
177
|
+
Grants expire after `grantTtlMs` and cannot be reused.
|
|
178
|
+
|
|
179
|
+
## Reviewer context and token budgets
|
|
180
|
+
|
|
181
|
+
The reviewer receives one compact canonical request plus bounded, explicitly
|
|
182
|
+
untrusted evidence. Selection is deterministic rather than semantic:
|
|
183
|
+
|
|
184
|
+
- the latest raw user message is the authorization anchor;
|
|
185
|
+
- older user messages require an exact request/tool/requester association, an
|
|
186
|
+
exact trusted retry, or a bounded narrowing/revocation rule;
|
|
187
|
+
- tool calls require an exact tool-call ID, exact structured request fields, a
|
|
188
|
+
surface profile, or a security-combination classification; and
|
|
189
|
+
- selected results stay paired with their producer and are limited to exact
|
|
190
|
+
results, deletion prechecks, Git push context, matching branch protection,
|
|
191
|
+
and Sandbox Runtime process evidence.
|
|
192
|
+
|
|
193
|
+
Unrelated reads, directory listings, builds, tests, assistant prose, and old
|
|
194
|
+
task history are excluded. Vague continuation text cannot restore older
|
|
195
|
+
authorization. Raw revocations override model allows. Compaction and branch
|
|
196
|
+
summaries are risk context only; they never count as user authorization.
|
|
197
|
+
|
|
198
|
+
The current operation appears once as stable, key-sorted JSON. Duplicate exact
|
|
199
|
+
tool-call arguments collapse to an ID/name/reason linkage shell, while fields
|
|
200
|
+
not represented by the request remain available as evidence. This compact
|
|
201
|
+
reviewer representation does not affect request hashes, grants, overrides, or
|
|
202
|
+
audit evidence.
|
|
203
|
+
|
|
204
|
+
`maxReviewerInputTokens` covers the fixed policy, canonical request, override,
|
|
205
|
+
evidence, omissions, JSON framing, and a 64-token provider-framing reserve. Its
|
|
206
|
+
legal range is 2,048–32,768. Because no matching tokenizer is bundled, the
|
|
207
|
+
`conservative:utf8` estimator counts every UTF-8 byte as one token.
|
|
208
|
+
|
|
209
|
+
When over budget, the host removes secondary reasons, older structured tool
|
|
210
|
+
matches, then optional producer/result units, re-estimating after each step. It
|
|
211
|
+
never silently removes the canonical request, exact override, latest user
|
|
212
|
+
evidence, security-combination evidence, exact tool linkage, or a required
|
|
213
|
+
surface profile. If mandatory evidence does not fit, review fails closed before
|
|
214
|
+
calling the model. More than four security-combination candidates also fails
|
|
215
|
+
closed locally.
|
|
216
|
+
|
|
217
|
+
## Sandbox integration
|
|
218
|
+
|
|
219
|
+
This package exposes the broker contract but does not intercept OS sandbox
|
|
220
|
+
events itself. Adapters translate a concrete boundary into a `BoundaryRequest`
|
|
221
|
+
and consume the exact grant before allowing it.
|
|
222
|
+
|
|
223
|
+
This monorepo's `pi-sandbox` adapter uses Anthropic Sandbox Runtime. Filesystem
|
|
224
|
+
policy is static and fail-closed; unmatched public network destinations use the
|
|
225
|
+
broker for one connection. Each Bash command or built-in subagent session owns
|
|
226
|
+
an independent Sandbox Runtime broker process. Adapter implementations should
|
|
227
|
+
use the package's `./sandbox` export and must not create broad permanent rules
|
|
228
|
+
in `.pi/sandbox.json`.
|
|
220
229
|
|
|
221
230
|
## Trust boundary
|
|
222
231
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
```bash
|
|
228
|
-
pi install npm:@erichll/pi-auto-review
|
|
229
|
-
```
|
|
230
|
-
|
|
231
|
-
Pi places user npm packages under `~/.pi/agent/npm/` and Git packages under
|
|
232
|
-
`~/.pi/agent/git/`, outside the project workspace. For local development only:
|
|
232
|
+
Production copies must live outside the agent-writable workspace. Pi installs
|
|
233
|
+
user npm and Git packages under `~/.pi/agent/npm/` and `~/.pi/agent/git/`.
|
|
234
|
+
Workspace-loaded copies are rejected unless local development explicitly opts
|
|
235
|
+
in:
|
|
233
236
|
|
|
234
237
|
```bash
|
|
235
238
|
PI_AUTO_REVIEW_ALLOW_UNTRUSTED_DEV=1 pi --approve
|
|
236
239
|
```
|
|
237
240
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
retries, and grant TTL, or set `failureMode` to `deny`. It may remove entries
|
|
242
|
-
from `autoConfirmBoundedAllows`, but cannot add a surface not enabled by the
|
|
243
|
-
trusted configuration. It cannot select a model, weaken fail-closed behavior,
|
|
244
|
-
or raise a trusted limit. Invalid user-global or project configuration disables
|
|
245
|
-
the reviewer for that session.
|
|
241
|
+
Writes to the installed reviewer package, its user-global configuration,
|
|
242
|
+
project and global security configuration, and the global audit directory are
|
|
243
|
+
deterministically denied.
|
|
246
244
|
|
|
247
|
-
|
|
248
|
-
directory (`~/.pi/agent/extensions/pi-auto-review/`), project security
|
|
249
|
-
configuration, global Pi security configuration, and the global audit directory
|
|
250
|
-
are deterministically denied.
|
|
245
|
+
## Telemetry and smoke testing
|
|
251
246
|
|
|
252
|
-
|
|
247
|
+
Every actual model call emits an internal `review_attempt`; each approval emits
|
|
248
|
+
one `review_complete`. Events contain stable status/error classes, timings,
|
|
249
|
+
usage counters, evidence metadata, and prompt-part counts. They do not contain
|
|
250
|
+
prompt or response text, provider errors, credentials, headers, or URL query
|
|
251
|
+
values. Usage is marked `unknown_provenance` when pi-ai cannot distinguish
|
|
252
|
+
provider counters from initialized values, and `unavailable` when absent.
|
|
253
253
|
|
|
254
|
-
For a controlled smoke test,
|
|
255
|
-
|
|
254
|
+
For a controlled real-model smoke test, load only the provider, reviewer,
|
|
255
|
+
sandbox, and audit listener:
|
|
256
256
|
|
|
257
257
|
```bash
|
|
258
258
|
PI_AUTO_REVIEW_ALLOW_UNTRUSTED_DEV=1 \
|
|
259
259
|
PI_AUTO_REVIEW_SMOKE_AUDIT_PATH=/tmp/pi-auto-review-smoke-audit.jsonl \
|
|
260
|
+
PI_AUTO_REVIEW_BASELINE_ID=reviewer-check \
|
|
261
|
+
PI_AUTO_REVIEW_BASELINE_CACHE_STATE=cold \
|
|
262
|
+
PI_AUTO_REVIEW_BASELINE_RUN_ORDER=1 \
|
|
263
|
+
PI_AUTO_REVIEW_BASELINE_SAMPLE_SET=reviewer-v1 \
|
|
264
|
+
PI_AUTO_REVIEW_SMOKE_TRIGGER=baseline-v1 \
|
|
260
265
|
pi --no-extensions --no-skills --no-prompt-templates --no-context-files \
|
|
261
266
|
--no-builtin-tools --no-session --print \
|
|
262
|
-
--extension /trusted/path/to/
|
|
267
|
+
--extension /trusted/path/to/provider/extensions/index.ts \
|
|
263
268
|
--extension ./packages/pi-auto-review/src/index.ts \
|
|
264
269
|
--extension ./packages/pi-sandbox/src/index.ts \
|
|
265
270
|
--extension ./scripts/real-model-smoke-audit.ts \
|
|
266
|
-
--model provider/
|
|
267
|
-
"
|
|
271
|
+
--model provider/reviewer-model \
|
|
272
|
+
"Run the configured synthetic reviewer baseline sample, then reply done."
|
|
268
273
|
```
|
|
269
274
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
275
|
+
The listener submits filesystem-write, network, delete, Git-push, and forwarded
|
|
276
|
+
subagent boundaries. No represented operation is executed; the main-agent
|
|
277
|
+
request is aborted after the samples finish. `--no-builtin-tools` ensures Bash
|
|
278
|
+
comes from `pi-sandbox` rather than Pi's built-in implementation.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@erichll/pi-auto-review",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Model-backed boundary approval broker for Pi",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -47,15 +47,15 @@
|
|
|
47
47
|
"test": "node --disable-warning=ExperimentalWarning --experimental-loader ./test/typescript-loader.mjs --test test/*.test.ts"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
|
50
|
-
"@earendil-works/pi-ai": "
|
|
51
|
-
"@earendil-works/pi-coding-agent": "
|
|
52
|
-
"@gotgenes/pi-permission-system": "
|
|
50
|
+
"@earendil-works/pi-ai": "^0.84.1",
|
|
51
|
+
"@earendil-works/pi-coding-agent": "^0.84.1",
|
|
52
|
+
"@gotgenes/pi-permission-system": "^25.1.0"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
|
-
"@earendil-works/pi-ai": "0.
|
|
56
|
-
"@earendil-works/pi-coding-agent": "0.
|
|
57
|
-
"@gotgenes/pi-permission-system": "
|
|
58
|
-
"@types/node": "^
|
|
55
|
+
"@earendil-works/pi-ai": "^0.84.1",
|
|
56
|
+
"@earendil-works/pi-coding-agent": "^0.84.1",
|
|
57
|
+
"@gotgenes/pi-permission-system": "^25.1.0",
|
|
58
|
+
"@types/node": "^26.2.0",
|
|
59
59
|
"typescript": "^6.0.3"
|
|
60
60
|
}
|
|
61
61
|
}
|
package/src/broker/broker.ts
CHANGED
|
@@ -110,11 +110,11 @@ export class BoundaryApprovalBroker {
|
|
|
110
110
|
let review: BoundaryReview;
|
|
111
111
|
try {
|
|
112
112
|
review = await this.#reviewer(request, { userOverride });
|
|
113
|
-
} catch
|
|
114
|
-
const reason =
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
113
|
+
} catch {
|
|
114
|
+
const reason = "Automatic review is unavailable.";
|
|
115
|
+
this.audit("review_failure", request, {
|
|
116
|
+
errorClass: "reviewer_unavailable",
|
|
117
|
+
});
|
|
118
118
|
if (this.#failureMode === "defer") {
|
|
119
119
|
this.#breaker.record(context.scopeKey, false);
|
|
120
120
|
return {
|
package/src/config.json
CHANGED
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
"model": "codex-auto-review",
|
|
3
3
|
"reasoning": "low",
|
|
4
4
|
"timeoutMs": 90000,
|
|
5
|
-
"maxTokens":
|
|
5
|
+
"maxTokens": 256,
|
|
6
6
|
"retries": 2,
|
|
7
7
|
"maxUserTranscriptTokens": 1200,
|
|
8
8
|
"maxToolTranscriptTokens": 1200,
|
|
9
9
|
"maxRelevantResultTokens": 800,
|
|
10
|
+
"maxReviewerInputTokens": 8192,
|
|
10
11
|
"failureMode": "deny",
|
|
11
12
|
"grantTtlMs": 60000,
|
|
12
13
|
"autoConfirmBoundedAllows": ["external_directory", "path"]
|