# Changelog

## 0.26.0 - 2026-10-08

- Upgrade Pi development dependencies and peer floors to `^1.1.0`, require
  permission-system `>=40.0.2`, and align the Node engine with Pi
  (`>=22.19.0`). Node types (`^26.6.4`) and TypeScript (`^7.0.2`) already
  match the latest stable registry versions.
- Retry `server_busy` and server-busy provider details within the existing
  two-attempt review budget, aligning with Pi 1.1.0
  ([#10543](https://github.com/earendil-works/pi/issues/10543)).
- Recognize the exact Mistral `finish_reason: "error"` message from pi-ai
  1.0.x as a transient server failure. pi-ai 1.1.0 adds a server-error suffix
  that the existing classifier already recognizes
  ([#10487](https://github.com/earendil-works/pi/issues/10487)); keep unknown,
  authentication, and configuration failures non-retryable.
- Clear staged UI auto-confirmations and one-shot interceptors when Pi 1.1.0
  emits `agent_settled.aborted: true`
  ([#10607](https://github.com/earendil-works/pi/issues/10607)). Preserve
  existing behavior when the field is absent, false, or malformed.

## 0.25.0 - 2026-10-07

- Pass permission-system's matched bash spelling (#910) through the review and
  audit pipeline. The ask payload's `request.matchedSpelling` — the alternate
  spelling the matched rule hit when it did not match the command as typed,
  e.g. the absolute spelling of a relative path argument — is now normalized
  into the reviewer evidence and `BoundaryRequest`, described to the model
  reviewer, carried through hard-deny audits, and persisted in the policy
  audit as an anonymous `spelling_fingerprint` (schema v3; v1 and v2
  databases migrate transactionally). Because `permissions:decision` still
  carries only `matchedPattern`, the spelling is captured from
  authorizer entry (including automatic allow/deny) and
  `permissions:ui_prompt` by request id and joined at record time with a
  bounded FIFO cache; decisions that carry the field directly are used
  as-is. The report grows a "spelling fingerprints" section (v3); the
  spelling stays out of the boundary request hash, which is display-only
  input. On permission-system 39.x the field is simply absent and the audit
  behaves exactly as before. The development baseline moves to ^40.0.2,
  including the /dev/null core-reader exemption fix and bash-chain session
  grant isolation security fix; the peer floor stays `>=39.0.0`. Real
  permission-system integration tests cover alternate spellings, redirect
  exemptions, automatic spelling audits, and sibling-unit isolation.
- Isolate authorizer tests from the real user audit database: ordinary tests
  disable audit collection, while audit integration uses a temporary HOME.
  Schema v3 is a forward migration; upgrade and restart all audit collectors
  rather than leaving pre-v3 sessions writing to the upgraded database.

## 0.24.0 - 2026-10-03

- Raise the `@earendil-works/pi-ai` and `@earendil-works/pi-coding-agent`
  peer floors to `^1.0.0` and the development baselines to `^1.0.0`, plus
  `@types/node` to `^26.6.4`. Raise the
  `@gotgenes/pi-permission-system` development baseline to `^38.0.2`; the peer
  floor stays `>=36.0.0`. Validated against Pi 1.0.0 with
  pi-permission-system 38.0.2 via `tsc --noEmit` and the full test suite: no
  source changes were required, and the authorizer seam this package consumes
  is unchanged.
- Move the example's Pi MCP tool rules under `mcp` (`mcp__atlassian__*`,
  `mcp__pencil__*`) and update the README's MCP guidance to match, because
  pi-permission-system 38.0.0 gates Pi's built-in MCP tools on the `mcp`
  surface instead of their top-level names.

## 0.23.0 - 2026-10-02

- Add opt-in `model: "current"` to review approval requests with the active Pi
  session model and provider, reflecting model changes on subsequent reviews.
- Decide, authorize, and hard-deny on the command that will actually execute,
  not only the rule-matched unit. The permission-system ask payload is now
  normalized into `executedUnit` (what a sudo/env/xargs/inline-shell wrapper
  runs), `fullCommand` (the whole program), and `matchedPattern` (the rule or a
  sentinel such as `<opaque-bash-wrapper>`), and those facts flow into the
  reviewer context and the public `BoundaryRequest`.
- Split deterministic hard denies by family. Structural rules (recursive forced
  wipes of `/`, `~`, or `$HOME`, and TLS/certificate weakening) scan a
  skeleton with quoted literals masked, plus nested shell payloads (`bash -c`,
  `eval`), including shells with options before `-c`. Literal path components
  retain placeholders so named cleanup targets cannot become root/home wipes.
  Other interpreter payloads (`python -c`, `node -e`, `perl -e`, `ruby -e`) and
  heredoc bodies stay raw because shell quoting cannot establish whether their
  strings execute. Inert mentions in shell commit messages and `echo` arguments
  remain excluded. Hard denies scan the full program, outer unit, and executed
  unit independently, preserving wrapper environment settings. Credential and
  redirect rules keep scanning raw text, including quoted credential operands.
- Bound nested interpreter expansion to 32 payloads and 32 KiB of cumulative
  payload text per command fact, shared across recursion levels. Lazy
  extraction stops repeated `eval` chains from producing megabytes of
  overlapping suffixes. On exhaustion, raw-command hard denies retain priority;
  otherwise the request defers to a human without calling the model, including
  on a trusted reviewer retry.
- Bind grants and the exact-retry match to the execution text, so two different
  heredoc bodies gated by the same wrapper unit no longer share one request
  hash. Denial labels and surface inference (`git-push`, `delete`) use the same
  text.
- Bound the reviewer view: `command`, `executedUnit`, and `fullCommand` are each
  cut to 10 KiB, and any cut sets `fullCommandTruncated`. An incomplete program
  now deterministically defers to a human before the model is called; a trusted
  exact-retry override still reaches the reviewer, and local hard denies keep
  priority. Hashing, hard denies, retry matching, and denial labels always use
  the untruncated text.

## 0.22.1 - 2026-10-01

- Fix permission-policy auditing being disabled on Bun with
  `No such built-in module: node:sqlite`. Bun, including Bun-compiled Pi, now
  uses its built-in `bun:sqlite`; Node continues to use `node:sqlite`.
- Preserve audit statistics and request deduplication when switching between
  Node and Bun by sharing the existing database schema and HMAC key.
- Finalize Bun's cached SQLite statements when closing the database so the
  last WAL connection can checkpoint and release its resources.
- Add regression coverage for database migration, redaction, retention,
  failure handling, concurrent Node/Bun writers, and persistent audit reports
  in a real Bun-compiled Pi process.
- Update the permission-system example for current MCP tool names, including
  `codemode`, `tool_search`, `mcp__atlassian__*`, and `mcp__pencil__*`.

## 0.22.0 - 2026-09-30

- Raise the `@earendil-works/pi-ai` and `@earendil-works/pi-coding-agent` peer
  floor to `^0.99.1` and the development baseline to `^0.99.1`. Validated
  against Pi 0.99.1 with `tsc --noEmit` and the full test suite: the extension
  adopts the 0.99 extension surface without code changes.
- Raise the `@gotgenes/pi-permission-system` peer floor to `>=36.0.0` and the
  development baseline to `^36.0.0`. Versions 35.0.3 and 36.0.0 reclassify
  `sed` and `awk` readers and withdraw `find`, `fd`, and `sort` read claims for
  computed and quoted arguments; the broker's evidence normalization and audit
  classification were validated against 36.0.0.
- Sync `examples/pi-permission-system.config.example.json` with the current tool
  set: allow `web_enable`, `subagents_enable`, `contact_supervisor`, and
  `bg_wait`, following the earlier skill/MCP regrouping, the `subagent` and
  `source_check` allowances, the `goal_block` to `goal_blocked` correction, and
  the `fetch_content` promotion from `ask` to `allow`.
- Bump the development `typescript` baseline to `^7.0.2` and migrate the test
  external-ts loader from `ts.transpileModule` (removed in TypeScript 7's new JS
  API) to Node's built-in `stripTypeScriptTypes`.

## 0.21.0 - 2026-09-25

- Raise the `@gotgenes/pi-permission-system` peer floor to `>=34.0.0` and update
  the development baseline to `^34.0.0`. Version 34.0.0 introduces
  syntax-level role projection for redirect targets so non-existent file
  targets are governed by path rules without requiring pre-existence probes.
- Automatically dismiss deferred and pending review widgets when explicit
  user permission decisions (`permissions:decision` with `allow`) occur or when
  a new agent turn begins (`turn_start`), preventing stale `deferred` notices
  from lingering in the TUI indefinitely.
- Unit tests added for deferred widget dismissal on local user confirmation.

## 0.20.1 - 2026-09-24

- Upgrade the development baseline for `@gotgenes/pi-permission-system` to
  `^33.1.1` (the runtime peer remains `>=30.0.0`). Version 33.1 changes how
  permission-system derives its authorizer tool surface and stop-gap
  `before_agent_start` guidance, while retaining a fail-closed runtime peer
  check and schema validation.
- Upgrade the development `@types/node` baseline to `^26.6.2`; the resolved
  version was already current under the previous range.
- Keep `typescript` at `6.0.3`, the latest 6.x release. TypeScript 7.0.2
  remains incompatible with the published-source transform used by the
  permission-system integration tests.
- Sync `examples/pi-permission-system.config.example.json` with the current
  tool split: Pencil and `mcp__pencil`, `update_plan`, and the complete goal
  lifecycle are explicitly allowed. The example passes the permission-system
  33.1.1 runtime schema.
- Type checking and the full package suite pass on the upgraded baselines
  (186 tests).

## 0.20.0 - 2026-09-23

- Require Pi `^0.87.1` for the development and peer dependency of
  `@earendil-works/pi-ai` and `@earendil-works/pi-coding-agent` (validated
  against the published 0.87.1 packages; `compat.d.ts`, the type surface this
  package builds on, is unchanged from 0.86.1).
- Validate against `@gotgenes/pi-permission-system` 33.0.8 (runtime peer stays
  `>=30.0.0`); no rule-semantics change observed.
- Upgrade the development `typescript` baseline: 7.0.2 was evaluated and kept
  on 6.0.3 because TS7 (the native Go compiler) removes the stable
  `transpileModule`/`ModuleKind` JS API used by `test/external-ts-loader.mjs`
  to transpile `pi-permission-system`'s published `.ts` sources.
- Sync `examples/pi-permission-system.config.example.json` with the live
  policy (add `goal_complete`, `obs_recall`, `pencil_read_skill`).

## 0.19.0 - 2026-09-20

- Require Pi `^0.86.0` for both the development and peer dependency of
  `@earendil-works/pi-ai` and `@earendil-works/pi-coding-agent`.
- Migrate the reviewer model call to Pi 0.86's normalized `TranscriptContext`:
  a registered provider `streamSimple` (models.json or extension-registered
  custom providers) now receives `normalizeContext(...)` so the reviewer system
  prompt and tool declarations arrive as the transcript's leading system
  message. Before this change such providers read the removed
  `context.systemPrompt`/`context.tools` and silently reviewed with a fallback
  system prompt and no tools.
- Read the normalized transcript in the authorizer integration tests
  (`getCurrentSystemPrompt` plus the last user message) and assert the leading
  system message, so the fake `streamSimple` observes the same shape the real
  provider adapters receive.

## 0.18.3 - 2026-09-20

- Move the `@gotgenes/pi-permission-system` development dependency to
  `^33.0.1` and refresh the type-check/test surface to Pi `^0.85.1`.
- Add an MCP rule-semantics regression test that locks the 33.x behavior this
  package depends on: a prefix-named tool such as `atlassian_getJiraIssue`
  derives its bare server (`atlassian`) as a candidate instead of an
  unmatchable double-prefixed alias, and MCP rules are evaluated
  last-match-wins across those candidates. A ruleset that puts
  `"*": "allow"` before `"atlassian": "deny"` now denies such a call, and the
  reviewer is shown the tool name as the boundary value.
- Sync `examples/pi-permission-system.config.example.json` with the live
  baseline: add the `mcp__atlassian` namespace-proxy allow and drop the
  redundant bare `atlassian` allow (after 33.0.0 its only reachable effect was
  silently allowing `mcp connect atlassian`, which starts the server). Ordinary
  `atlassian` / `jira` / `confluence` tool calls stay allowed.
- No runtime behavior change in this package: the public authorizer API it
  consumes and the normalized evidence shape are unchanged, and the peer range
  stays `>=30.0.0`. The bump only moves the development surface, so MCP rule
  semantics come from the installed permission-system (33.0.0 made
  prefix-named tools resolve to their bare server and evaluated MCP rules
  last-match-wins).

## 0.18.2 - 2026-09-17

- Treat empty or whitespace-only `.pi/pi-auto-review.json` files as missing
  configuration instead of throwing `SyntaxError`. This prevents `session_start`
  from disabling automatic reviews for an entire session when Linux bubblewrap
  creates a 0-byte mount point stub for deny-write paths (fixes #6).
- Apply the same empty-file tolerance to the user-global config loader.
- Remove redundant files from `protectedFiles` in `guards.ts` (`settings.json`,
  `permissions.json`, and unused `sandbox.json`) so workspaces can configure
  standard settings without triggering security tampering hard-denials.

## 0.18.1 - 2026-09-11

- Animate the live `reviewing` label in the above-editor widget with a
  left-to-right light sweep while the reviewer model is evaluating a boundary check.
- Paint shimmer frames at an 80ms interval cycling theme colors (`accent`,
  `muted`, `dim`) without altering the label text length or widget layout width.
- Ensure the animation timer cleanly stops and disposes when the review phase
  completes or the widget is dismissed.
- Export `USER_REVIEW_SWEEP_INTERVAL_MS` and `renderReviewingSweep` for testing
  and custom TUI rendering.

## 0.18.0 - 2026-09-11

- Coordinated release for `@erichll/pi-sandbox 0.18.0`.
- Dismiss the above-editor widget eight seconds after an allow or auto-confirm
  so a successful check does not stay on screen until the next review. Denials,
  deferrals, and local-confirmation waits still remain until the next check.
- Raise the `@gotgenes/pi-permission-system` peer floor to `>=30.0.0` and drop
  the upper bound. 29.x is no longer claimed; 32.x does not change the public
  authorizer API this package uses, and later majors are no longer excluded by
  the range.

## 0.17.0 - 2026-09-05

- Coordinated release for `@erichll/pi-sandbox 0.17.0`; the broker API and
  approval behavior are unchanged.
- Align the development pin of `@gotgenes/pi-permission-system` to the 31.1.x
  runtime line and update the authorizer-integration test to the 31.1.1
  internal source layout (the 31.1.1 refactor moved `path-normalizer.ts`).
- Split the 2,778-line `src/index.ts` into a `src/review/` module directory
  (`types`, `consts`, `config`, `audit`, `prompts`, `guards`, `input`,
  `provider`, `complete`) with an internal barrel, matching the existing
  `broker/` and `policy-audit/` conventions; the public export surface of
  `src/index.ts` is unchanged.
- Harden TypeScript checking: enable `noUncheckedIndexedAccess` and
  `noImplicitOverride` across the workspace and fix all 47 newly surfaced
  unguarded-index sites.
- Replace the full custom TypeScript test loader with native Node type
  transformation (`--experimental-transform-types`); a scoped hook now only
  handles the TypeScript sources shipped inside `node_modules`, which Node
  refuses to type-strip.

## 0.16.0 - 2026-09-05

- Coordinated release for `@erichll/pi-sandbox 0.16.0`; the broker API and
  approval behavior are unchanged.

## 0.15.3 - 2026-09-03

- Tolerate a single enclosing ```` ```json ```` or bare Markdown code fence
  around reviewer decisions while preserving strict decision-schema
  validation (fixes reviewer models that fence JSON despite the prompt,
  notably when routed through Claude Code).
- Verify compatibility with `@gotgenes/pi-permission-system` 30.2.0 and
  31.0.0, widen the peer range through 31.x, and move the development baseline
  to 31.0.0.
- Keep permission-system 31 statement-operand audit classification aligned for
  `for`/`select` word lists and `case` subjects without treating case patterns
  as accessed paths.
- Confirm that model auto-confirm stays one-shot and cannot select
  permission-system 30.2's wider both-directions session grant.

## 0.15.2 - 2026-09-02

- No behavior changes. Verified against `@gotgenes/pi-permission-system`
  29.x with a development baseline of `29.3.0`; the peer range now accepts
  29.x alongside 28.x.
