Skip to content

fix: preserve foreign prompts in pi scrub - #10

Merged
rynfar merged 2 commits into
mainfrom
codex/review-pi-7
Sep 24, 2026
Merged

rynfar merged 2 commits into
mainfrom
codex/review-pi-7

Conversation

@rynfar

@rynfar rynfar commented Sep 24, 2026

Copy link
Copy Markdown
Owner

Change

Incorporates #7 through an authored cherry-pick. Whitespace cleanup now runs only after a targeted block is removed, so unrelated prompts retain their exact bytes. A separate maintainer commit tests the plugin boundary and corrects adapter-scope documentation.

Source fa9366c33c1b93b8866d514a58dc95a9cfc0a2b8 → authored cherry-pick 8732fd2d9bedc9c206517204ca3373c90e4c503e (Serge Baranov, original AuthorDate preserved). Maintainer test/docs commit: 70d2725.

Validation

  • On current main with the source PR's tests added, bun test src/__tests__/scrub.test.ts failed the two exact-byte foreign-prompt assertions (9 pass, 2 fail).
  • On this branch, npm ci, npm test (13 pass), npm run build, and npm pack --dry-run passed.
  • Live macOS run: actual Pi 0.72.1 default prompt through an isolated Meridian 1.76.3 proxy and the built plugin to the real Claude Agent SDK / claude-haiku-4-5. The pre-plugin hook saw both Pi identity and Pi documentation; the SDK query contained neither and retained generic identity. Pi returned successfully. Artifact: /tmp/pi-scrub-live-e2e.mjs; report/log directory printed as pi-scrub-live-nnT3De.

The plugin-level regression also checks that a foreign adapter's context object and prompt bytes are unchanged, while a matching Pi prompt retains its other request fields.

Co-authored-by: Serge Baranov sbaranov@gmail.com

CrazyCoder and others added 2 commits September 24, 2026 01:21
The two cleanup passes at the end of scrubPiFingerprints ran unconditionally:

    .replace(/\n{3,}/g, "\n\n")
    .replace(/\s+$/, "")

They exist to repair the gaps the removals above leave behind, but they applied
to every prompt — including prompts with no pi fingerprint at all. Any prompt
containing a run of 3+ newlines or trailing whitespace therefore came back
modified.

That matters because of #4: the plugin is deliberately registered for EVERY
adapter and self-scopes by content, and index.ts states the contract as "only
rewrites the prompt when pi's identity fingerprint is actually present, and is
otherwise an exact no-op". Since #4 that contract is load-bearing — the plugin
now sees Claude Code, OpenCode and other harnesses' system prompts, and quietly
reflowed all of them. index.ts also only propagates a new context when the
string changed, so the plugin appeared to act on essentially every request.

Gate the cleanup on one of the removals having matched. Whitespace normalization
still runs whenever a fingerprint was actually removed, so the original intent
is preserved.

The suite already asserted this guarantee ("is a no-op on prompts without pi
fingerprints") but its fixture contained neither a 3+ newline run nor trailing
whitespace, so it could not catch it. Added two fixtures that do, plus one
asserting the cleanup still runs on a real pi prompt. Both new no-op tests fail
before this change and pass after; 11/11 green.
@rynfar
rynfar merged commit 54e0706 into main Sep 24, 2026
1 check passed
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.

2 participants