@erichll/pi-auto-review 0.15.0 → 0.15.2

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 CHANGED
@@ -1,291 +1,7 @@
1
1
  # Changelog
2
2
 
3
- ## 0.15.0 - 2026-08-29
3
+ ## 0.15.2 - 2026-09-02
4
4
 
5
- - Fix a deterministic reviewer-unavailable denial for large CJK tool inputs.
6
- The reviewer input estimator counted one token per UTF-8 byte, tripling the
7
- estimate for CJK text, so multi-kilobyte Chinese payloads (e.g. a long plan
8
- document submitted through a tool call) synchronously failed the
9
- `reviewer_input_budget_exceeded` preflight before the reviewer model was
10
- ever called, and the request was denied as "Automatic review is
11
- unavailable." CJK code points now estimate at one token each and remaining
12
- code points at their UTF-8 byte length over three (estimator
13
- `conservative:cjk-aware`).
14
- - Record the denial when a reviewer-unavailable review fails closed, so
15
- `/auto-review-approve` — the recovery command that verdict recommends —
16
- actually has a matching denial to approve. Previously the recommendation
17
- was dead text for this failure class.
18
- - Let an explicit human override (`/auto-review-approve` trusted exact retry)
19
- bypass the reviewer input-budget preflight failure. A sizing estimate is
20
- not a safety verdict and must not veto an already-authorized retry; the
21
- review proceeds with truncated evidence.
22
- - Show "waiting for you" in the review widget while a `ctx.ui` prompt blocks
23
- the session during an active review (pi >= 0.84.4 `ui_prompt_start` /
24
- `ui_prompt_end`). The widget previously kept claiming "Waiting for
25
- <model>…" while pi was actually waiting on the user (permission dialog,
26
- `/review-denials`, break-glass challenge). Completed outcome summaries and
27
- sessions without a live widget are unaffected.
28
- - Fix `/auto-review-approve` and `/auto-review-break-glass` never applying in
29
- real TUI sessions. The exact-match request hash included `toolCallId`, but a
30
- retry is always a brand-new model tool call with a fresh tool call ID, so
31
- the authorization could never match the retried request. The hash now
32
- excludes both retry-minted identifiers (`id` was already excluded).
33
- - Fix break-glass authorization being discarded on every retry. The stored
34
- authorization was bound to the denial-time turn scope, but the command flow
35
- appends a user message (`pi.sendUserMessage`) before the agent retries, so
36
- the retry always lands in a later turn whose scope differs. Consumption now
37
- binds on session and request hash plus the confirmation TTL instead of the
38
- turn scope. The non-critical approve path already behaved this way.
39
- - Reset the turn circuit breaker when a break-glass allow is consumed, so the
40
- human-authorized scope can continue instead of staying blocked for the rest
41
- of the turn. Fresh repeated denials still trip it again after three
42
- consecutive failures.
43
- - Clean up break-glass authorization bookkeeping: an expired authorization
44
- that was never consumed no longer blocks re-approving the same action, and
45
- a fresh denial of an action whose approval was already consumed re-arms
46
- one-shot approval (one approval per denial).
47
-
48
- ## 0.14.0 - 2026-08-28
49
-
50
- - Upgrade `/auto-review-policy-audit` from redacted statistics to an
51
- evidence-driven permission-configuration optimizer. Reports now separate
52
- suggested allow rules, keep-ask rules, and insufficient evidence, and emit a
53
- copyable JSON fragment targeting the selected project or global
54
- permission-system configuration. Suggestions remain advisory and never read
55
- or modify permission configuration.
56
- - Discover candidates from actual audit data without built-in tool, executable,
57
- Git, RTK, package-manager, or read-only command catalogs. Valid observed
58
- surfaces and sanitized Bash templates—including unknown tools and write
59
- operations—can qualify after the configured minimum number of successful
60
- ask-path approvals. Denials, gate failures, unavailable confirmations,
61
- forwarded requests, and structurally unsafe Bash variants block a suggestion.
62
- - Migrate the policy-audit database transactionally to schema v2. Existing
63
- aggregate counts and `collecting_since` are preserved, while the new
64
- `recommendations_since` boundary prevents pre-migration data from producing
65
- allow suggestions. Valid custom tool names and sanitized Bash templates are
66
- retained for reporting. Templates replace paths, URLs, assignments, quoted
67
- values, and option values with wildcards; raw commands and non-Bash tool
68
- arguments or inputs remain excluded.
69
-
70
- ## 0.13.0 - 2026-08-28
71
-
72
- - Add compatibility with `@gotgenes/pi-permission-system` 27.1 directional
73
- `path_*` and `external_directory_*` surfaces while retaining the original
74
- surface in authorization evidence, UI binding, logs, and policy audits.
75
- - Keep the permission-system peer range at `^27.0.0` so existing 27.x bare
76
- `path` and `external_directory` integrations remain supported.
77
-
78
- ## 0.12.0 - 2026-08-27
79
-
80
- - Add the private policy audit
81
- compare current-project or anonymous global surface/command hotspots, denial
82
- rates, approval sources, and rule-hit fingerprints; then review repeatedly
83
- approved read-only operations as candidates for narrowly scoped `allow`
84
- rules. Mutation, project execution, network, arbitrary-shell, unknown, and
85
- custom-tool activity is called out as keep-`ask` evidence rather than an
86
- automatic relaxation. The report does not edit policy or claim that an
87
- unobserved rule is unused.
88
- - Add default-on, 180-day permission-policy auditing backed by built-in
89
- `node:sqlite`. Permission decisions are immediately reduced to fixed command,
90
- risk, path-class, source, and anonymous rule-hit aggregates; raw commands,
91
- paths, URLs, credentials, request IDs, and project names are never stored.
92
- - Add `/auto-review-policy-audit` as an extension-owned custom-entry report.
93
- It is not registered as an Agent tool or packaged skill, so audit reporting
94
- adds no tool schema or skill metadata to the model context. Reports default
95
- to the current project and can explicitly show an anonymous global aggregate.
96
- - Require Node.js 22.13.0 or newer. No SQLite CLI, system library, npm SQLite
97
- package, RTK, or historical permission-log import is required.
98
-
99
- ## 0.11.1 - 2026-08-25
100
-
101
- - Align the package version with `@erichll/pi-sandbox` `0.11.1`. No
102
- pi-auto-review runtime or public API changes.
103
-
104
- ## 0.11.0 - 2026-08-24
105
-
106
- - **Structured network destination.** Network approval requests now carry
107
- separate host, port, and protocol fields alongside the existing combined
108
- destination string. One-shot grants bind each component independently, so a
109
- grant issued for one host-port-protocol combination cannot be reused for a
110
- different one.
111
- - **Deferred reviews are more visible.** The review widget now highlights
112
- deferred verdicts with a warning accent instead of the previous muted style,
113
- making pending human decisions easier to spot.
114
-
115
- ## 0.10.0 - 2026-08-22
116
-
117
- - Replace the review footer and newly appended transcript entries with one
118
- above-editor `pi-auto-review` widget. Each permission check independently
119
- replaces the previous display, shows the configured reviewer model while it
120
- runs, and updates in place with its final outcome and metadata. The latest
121
- result remains until the next check and is cleared on session change or
122
- shutdown.
123
- - Prevent late concurrent completions and permission decisions from overwriting
124
- a newer check. A current local denial adds `Local confirmation · denied` to
125
- that result only. Widget failures fall back to notifications without changing
126
- authorization behavior.
127
- - Remove tool-call grouping, timers, capacity eviction, and tool/turn flush
128
- wiring for new feedback while retaining the historical entry renderer. Bound
129
- target and rationale text with visible ellipses, preserve width-aware wrapping,
130
- and keep token, duration, and call-count numbers in the normal metadata color.
131
-
132
- ## 0.9.0 - 2026-08-22
133
-
134
- - Require `@gotgenes/pi-permission-system` `^27.0.0` and register through the
135
- session-keyed `getPermissionsService(sessionId)` locator. Repeated ready
136
- broadcasts are idempotent; session changes, shutdown, and late asynchronous
137
- imports cannot retain or revive a stale authorizer registration. In-process
138
- child nodes register against their own service without replacing the
139
- parent's process-local broker capability.
140
- - Group local TUI review results by `(sessionId, toolCallId)` into one
141
- transcript entry while preserving independent asks, model calls, verdicts,
142
- grants, confirmations, and audit records. Denials flush immediately; tool
143
- start, terminal permission denial, turn/agent/session end, a 60-second TTL,
144
- and bounded-capacity eviction provide lossless fallback flushes. Forwarded,
145
- uncorrelated, and non-TUI reviews remain immediate.
146
- - Add `toolCallId` to each `pi_auto_review_decision` audit entry and retain
147
- compatibility rendering for historical single-result transcript entries.
148
- - Remove the review entry's left quote bar and combine each target with its
149
- rationale and member surface/outcome on one line, keeping model/token/duration
150
- metadata separate.
151
- - Label every displayed model token count with `toks` in both grouped and
152
- single-result output.
153
-
154
- ## 0.8.2 - 2026-08-21
155
-
156
- - Structure interactive review results as headline, target, rationale, and a
157
- meta line with the reviewer model name, input/output tokens, duration, and extra
158
- calls. The TUI renders them as markdown-style quote rows (`│` + `mdQuote`),
159
- with allow/deny verbs and token counts tinted from the theme. The model id is
160
- shown without a provider prefix; audit still records the full `provider/id`.
161
- Local hard denies omit model and token fields because no model ran.
162
-
163
- ## 0.8.1 - 2026-08-21
164
-
165
- - Restore TUI auto-confirm for capped `path` / `external_directory` allows on
166
- permission-system 26.x. `permissions:ui_prompt` no longer carries `message`;
167
- the bridge now binds `requestId` plus `request.value` (falling back to the
168
- display `value`, then the legacy `message`) and fingerprints the live dialog
169
- with those fields. Top-level display `surface` is not treated as the gate.
170
-
171
- ## 0.8.0 - 2026-08-21
172
-
173
- - Add `/auto-review-approve` for exact non-critical denial retries and remove
174
- the unprefixed `/approve` command without a compatibility alias.
175
- - Add interactive `/auto-review-break-glass` for a recent critical model deny.
176
- The high-friction confirmation is bound to the full request hash, session,
177
- scope, and original request ID, expires after 60 seconds, permits one direct
178
- retry, and never bypasses deterministic or protected-write hard denies.
179
- - Add tighten-only `breakGlassEnabled` (default `true`), structured break-glass
180
- allow provenance, and challenge/authorization/consumption/rejection audit
181
- events. Challenge phrases are never included in audit events.
182
-
183
- ## 0.7.0 - 2026-08-20
184
-
185
- - **Named `/home` paths are not a home wipe.** The reviewer prompt now matches
186
- the deterministic hard-deny: recursive forced wipe of `/`, `~`, `$HOME`, or
187
- the home directory itself remains forbidden. A narrow, user-requested delete
188
- of named files or directories under `/home/...` is high-risk, not critical.
189
- High risk without medium/high user authorization defers to the human instead
190
- of denying as if it were a hard deny. The fixed prompt is compacted without
191
- changing those rules.
192
- - **Clearer agent-facing denials.** Authorizer denies still fail closed, but the
193
- teaching reason now states that automatic policy denied the request (not a
194
- human click), forbids rephrasing or circumvention, and points to the exact
195
- retry command
196
- for one exact retry when the user already requested that action. The
197
- permission-system wrapper may still say `User denied`; the reason suffix is
198
- the correction this package can own.
199
-
200
- ## 0.6.0 - 2026-08-20
201
-
202
- - **Remove host user-constraint overlay.** Stop rewriting model allows from
203
- regex matches on user text (`constraintEffect` / `vagueContinuation` /
204
- authorization ceilings). Older messages enter evidence only via an exact
205
- request reference or trusted exact retry. Compaction summaries remain
206
- excluded from user intent. Hard denies, grant hashing, and the reviewer
207
- model are unchanged.
208
-
209
- ## 0.5.0 - 2026-08-20
210
-
211
- - **Safer evidence selection.** Review only request-linked tool calls, paired
212
- results, current-task user intent, and bounded security evidence. Compaction
213
- summaries cannot restore authorization, raw revocations override model
214
- allows, and missing mandatory evidence fails closed before a model call.
215
- - **Independent, smaller reviewer requests.** Use one compact canonical request
216
- envelope and a byte-stable policy prefix, reducing fixed input from 2,011 to
217
- 1,396 characters. Independent SSE calls prevent prior review state from
218
- carrying into later approvals while preserving cache/routing identity.
219
- - **Explicit token limits.** Add tighten-only `maxReviewerInputTokens` with an
220
- 8,192 default and conservative UTF-8 accounting across the complete prompt.
221
- Lower the default `maxTokens` from 1,600 to 256 after sequential real-model
222
- validation at 384 and 256; the legal range remains 256–4,096.
223
- - **Typed, bounded retries.** Share one deadline across each review, disable
224
- provider-internal retries, and allow at most two actual model calls. Only
225
- format errors, recognized connection/5xx failures, and bounded 429 responses
226
- retry; deterministic and unknown failures remain terminal and fail closed.
227
- - **Privacy-bounded telemetry.** Record per-attempt usage and per-review
228
- summaries for both reviewer entry points using stable status/error codes and
229
- prompt-part counts, without logging evidence text, provider errors,
230
- credentials, headers, or URL query values.
231
-
232
- ## 0.4.0 - 2026-08-19
233
-
234
- - **Credential-exfiltration hardening.** Expand deterministic terminal denies to cover
235
- `.env` variants, common credential files, additional file readers and encoders,
236
- shell substitutions, staged variables, redirects, and multi-stage pipelines that
237
- upload credentials to network sinks. Template files such as `.env.example` and
238
- `.env.sample` remain reviewable.
239
- - **Reviewer refresh safety.** Re-resolve reviewer model/provider metadata for each
240
- review, reacquire authentication for each attempt, and bind the reviewer session
241
- identity to the endpoint and authentication fingerprint so provider or OAuth
242
- refreshes cannot reuse a stale connection.
243
- - **Compatibility.** Require Pi 0.84.1+ and permission-system 25.1.0+ to match the
244
- current reviewer and forwarded-permission contracts.
245
-
246
- ## 0.3.5 - 2026-08-13
247
-
248
- - Raise the default model-review `timeoutMs` from 45s to 90s and the default
249
- `retries` from 1 to 2. Approval now tolerates real-world model latency better
250
- while keeping the same bounded transcript surface.
251
-
252
- ## 0.3.4 - 2026-08-08
253
-
254
- - Normalize direct and permission-system v24 forwarded evidence before policy
255
- checks, model review, grant hashing, and audit logging. Forwarded Bash
256
- commands, canonical path boundaries, agent names, and requester session IDs
257
- now remain bound to the exact reviewed request.
258
- - Add an opt-in `PI_AUTO_REVIEW_AUDIT_FILE` JSONL sink for isolated release
259
- verification without changing the normal event-based audit surface.
260
-
261
- ## 0.3.3 - 2026-08-06
262
-
263
- - Fix config validation rejecting multi-segment model ids (`provider/group/model`).
264
- `validateConfig` no longer restricts a model to exactly one `/`; it only rejects
265
- ids with empty segments. Segments are resolved as before: the first segment is
266
- the provider and the rest is the model id.
267
-
268
- ## 0.3.2 - 2026-07-29
269
-
270
- - Load an optional user-global trusted config from
271
- `~/.pi/agent/extensions/pi-auto-review/config.json` as a full overlay on the
272
- package defaults (model, `autoConfirmBoundedAllows`, and other legal keys).
273
- - Keep project `.pi/pi-auto-review.json` tighten-only on top of that trusted
274
- layer.
275
- - Deterministically deny writes to the user-global reviewer config directory.
276
- - Default reviewer model is the bare id `codex-auto-review`; `provider/model`
277
- remains supported. Bare ids resolve against registered available models.
278
- - Show user-facing review feedback in interactive UI: a footer status while the
279
- model is reviewing, then a short toast for allow / deny / defer / auto-confirm
280
- / circuit-breaker outcomes (separate from agent denial reasons).
281
-
282
- ## 0.3.1 - 2026-07-29
283
-
284
- - Bind one-shot approval grants to matched policy evidence as well as the
285
- command, working directory, destination, paths, and other request fields.
286
- - Prevent a grant issued for one Host-IPC trigger from authorizing a request
287
- with different trigger evidence.
288
-
289
- ## 0.3.0 - 2026-07-28
290
-
291
- - Initial public release.
5
+ - No behavior changes. Verified against `@gotgenes/pi-permission-system`
6
+ 29.x with a development baseline of `29.3.0`; the peer range now accepts
7
+ 29.x alongside 28.x.
package/README.md CHANGED
@@ -31,7 +31,7 @@ that dependency is a hard prerequisite (see [Install and enable](#install-and-en
31
31
  > **Prerequisite:** pi-auto-review is an authorizer inside
32
32
  > `@gotgenes/pi-permission-system`. Pi does not auto-install peer packages, so
33
33
  > install the permission system separately (once per machine) before this
34
- > extension. Version 0.10.0 requires permission-system 27.x:
34
+ > extension. This release line supports permission-system 28.x and 29.x:
35
35
 
36
36
  Node.js 22.13.0 or newer is required. Permission auditing uses Node's built-in
37
37
  `node:sqlite`; it does not require a SQLite CLI, system SQLite library, or npm
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@erichll/pi-auto-review",
3
- "version": "0.15.0",
3
+ "version": "0.15.2",
4
4
  "description": "Fail-closed, model-backed approval broker for Pi: deterministically hard-denies dangerous operations, reviews dangerous boundaries with a reviewer model, and issues one-shot expiring grants that OS sandbox adapters must consume before retrying.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -49,12 +49,12 @@
49
49
  "peerDependencies": {
50
50
  "@earendil-works/pi-ai": "^0.84.4",
51
51
  "@earendil-works/pi-coding-agent": "^0.84.4",
52
- "@gotgenes/pi-permission-system": "^27.0.0"
52
+ "@gotgenes/pi-permission-system": ">=28.0.0 <30.0.0"
53
53
  },
54
54
  "devDependencies": {
55
55
  "@earendil-works/pi-ai": "^0.84.4",
56
56
  "@earendil-works/pi-coding-agent": "^0.84.4",
57
- "@gotgenes/pi-permission-system": "27.1.0",
57
+ "@gotgenes/pi-permission-system": "29.3.0",
58
58
  "@types/node": "^26.2.0",
59
59
  "typescript": "^6.0.3"
60
60
  }
@@ -32,6 +32,8 @@ const PERMISSION_RESOLUTIONS = new Set([
32
32
  "user_approved_for_session",
33
33
  "user_denied",
34
34
  "auto_approved",
35
+ "authorizer_allowed",
36
+ "authorizer_denied",
35
37
  "confirmation_unavailable",
36
38
  "gate_error",
37
39
  ]);
@@ -42,6 +42,11 @@ export type PolicyAuditReportOptions = {
42
42
  scope: "current" | "all"; days: number; top: number; minCount: number;
43
43
  };
44
44
 
45
+ // Suggestion evidence must stay strictly human/session-based. Since
46
+ // permission-system v28, decisions made by a registered authorizer chain link
47
+ // (including pi-auto-review's own model review) resolve to `authorizer_allowed`
48
+ // instead of `user_approved`. Counting those here would create a feedback loop:
49
+ // machine review allows → evidence → suggested auto-allow rule → review bypassed.
45
50
  const SUCCESS_RESOLUTIONS = new Set([
46
51
  "user_approved", "user_approved_for_session", "session_approved", "auto_approved",
47
52
  ]);
@@ -70,8 +75,15 @@ function rank(
70
75
  .slice(0, top);
71
76
  }
72
77
 
78
+ // "Reviewed" marks ask-path rows that some reviewer resolved — human clicks and,
79
+ // since permission-system v28, named authorizer links alike — so low-risk
80
+ // candidates stay visible even when only the machine authorizer decides them.
81
+ // Display-only: SUCCESS_RESOLUTIONS still gates suggestion evidence.
73
82
  function reviewed(row: PolicyAuditAggregateRow): boolean {
74
- return ["user_approved", "user_approved_for_session", "user_denied", "auto_approved"].includes(row.resolution);
83
+ return [
84
+ "user_approved", "user_approved_for_session", "user_denied", "auto_approved",
85
+ "authorizer_allowed", "authorizer_denied",
86
+ ].includes(row.resolution);
75
87
  }
76
88
 
77
89
  type CandidateGroup = {