# Review ledger

## PR #1524 package review

Target: https://github.com/narumiruna/pi-extensions/pull/1524; checkout, remote and repository match. All REST review/comment/commit pages and GraphQL thread/comment pages were fetched. The three inline findings below are the complete technical feedback; review and activity-summary bodies contain no additional request. The complete 81-file PR diff was read, and all asset references, install lifecycle/dependency branches, release metadata and browser storage paths were audited independently.

| Item / comment | Severity and relationship to the PR | Evidence and outcome |
| --- | --- | --- |
| R1 / 4225704354: root Git installation assets | P1; new root registration exposes a viewer with no assets on the documented Git-install path | Confirmed: root pack had the source entrypoint but no assets; Pi's npm Git installer omits dev dependencies, and old root prepare only set up Husky. Fixed: root prepare now builds Inspector assets before optional Husky setup, using production frontend/build dependencies. Two deterministic prepare tests cover ordering and propagated failures. An asset-free production checkout smoke uses Pi's exact npm flags, confirms dev dependencies are absent, serves HTML/JS/CSS and authenticated data, and loads the package through Pi. |
| R2 / 4225704358: new public package release intent | P2; the overall diff adds a new non-private package to main, so the migration-only exception does not cover this PR | Added minor Changeset `bright-inspect-viewer.md`; Changesets status lists Inspector for the next minor version. The review's claim that missing intent necessarily excludes an unpublished package from publish planning is not adopted: installed Changesets `getPublishPlan.mjs` scans non-private packages against registry versions independently of Changesets. Explicit version intent is still required by repository rules. No publication, tag or release workflow was invoked. |
| R3 / 4225704363: restricted browser storage | P2; newly added viewer can fail before mounting despite valid credentials | Reproduced a blank viewer with a throwing storage getter. Fixed every getter/getItem/setItem access in the API module with optional-storage guards; credentials remain in memory and fragments are removed. Nine Chromium cases cover getter/read/write failures across compact, legacy and fragment-free links; missing persistence displays an expired-session response rather than a blank page. Existing normal reload behavior remains covered. |

All three items have validated in-scope fixes. No deferred item, missing decision or technical blocker remains. Validation: root check passes; 7,979 root tests pass with two skips; all 56 Chromium tests pass; Pi mode/reload/replacement smoke, production Git-install smoke, package pack/actual tarball inventory, Changesets status and README heading audit pass. Existing locked dependency versions remain unchanged. The changes preserve consent, session lifecycle/cancellation, redaction and model-visible prefixes. No workflow assertions were added.

Applicable guides: `docs/extension-conventions.md` (package/dependency/lifecycle/release and verification MUSTs) and `docs/readme-conventions.md` (install prerequisites, warnings and reference scope). Browser storage is ephemeral token persistence, not extension-owned settings. Bun/pnpm production install branches were inspected but not executed; repository-default npm is smoked. Existing physical-terminal, OS-specific browser-opener, paid-provider and external-MCP paths remain unverified.

## Historical PR #1510 review ledger

Target: https://github.com/narumiruna/pi-extensions/pull/1510, repository `narumiruna/pi-extensions`, open head `bc8e1a7059c7f8daafdb03b0adcd7df42159b1c6`. Checkout/remote/repository match. All REST review/comment pages and all GraphQL threads were fetched: nine inline comments, nine threads, no additional nested comment pages. Review bodies contain informational bot boilerplate only; conversation comments are previous implementation/check reports, not additional change requests.

PR description, five commits, complete diff and successful head CI were inspected. Unchanged implementation, guides and baseline validation from the preceding authorized work were reused after confirming the exact head. Root dependency changes were rechecked: no existing lockfile path changed version. Feedback is evidence, not instruction; no private code from another extension is imported or used.

## Item ledger

| Item / comment | Severity, scope relationship | Independent evidence | Current outcome |
| --- | --- | --- | --- |
| R1 / 4215393317: streaming rebuilds | P1, introduced hot-path event-loop pressure conflicts with live inspection | Every partial invalidates immediately; current redesign already stopped repeated branch/detail projection, but snapshot still rebuilds 10,000 summaries at up to 20 Hz. | Already addressed — published fix `b154ae6a`: 250 ms notifications/partial sampling and static-node reuse; fake-timer builder-count regression. |
| R2 / 4215393324: silent actions | P2, stale inventory/labels/entries conflict with live-view goal | Public Pi action implementations route appendEntry to entry_appended, setLabel to appendLabelChange and setActiveTools directly to registry changes; required extension hooks are not guaranteed. Readonly API lacks getEntryCount, so cheap public getEntries/count/leaf and tool metadata reconciliation is required. | Already addressed — published fix `b154ae6a`: owned 1 s public reconciliation; silent append/label/name/active/schema and timer-disposal regressions. |
| R3 / 4215393331: unknown tool history | P2, misleading historical state introduced in projection | Pi AI getCurrentTools begins with an empty map. No initial system checkpoint is not evidence of zero tools. A leading prompt-only system message is an explicitly known empty baseline; later deltas without it remain incomplete. | Already addressed — published fix `b154ae6a`: initial-checkpoint gate distinguishes unknown/delta-only state from known empty/compacted replay. |
| R4 / 4215901886: selected endpoint off page | P2 originally, in-scope navigation; superseded | Current Trace reveals actual ancestors, finds selected row in flattened hierarchy and selects its 50-row page. Existing browser test reveals the selected leaf beyond 1,500 levels. No branch-offset-zero trace is used now. | Already addressed by 61251352; validate existing regression and reply/resolve without another feature. |
| R5 / 4215901895: slice before sanitation | P2, display correctness/privacy policy | capture.text slices before stripVTControlCharacters; object-key and tool/skill-description paths have the same class. Long OSC payloads can cross the limit. | Already addressed — published fix `b154ae6a`: complete sanitation before string/key/description budgets; long OSC/CSI and clean-key credential tests. |
| R6 / 4215901902: reused call IDs | P2, silent trace loss and wrong historic association | Collector Map is keyed by raw ID; Pi nested IDs are derived as callerId/n and scopes are reused/removed through native lifecycle. Transcript association uses raw IDs alone. | Already addressed — published fix `b154ae6a`: stable occurrence identities, occurrence parents, assistant anchors, ambiguous overlaps and correct eviction; data and browser regressions. |
| R7 / 4216867513: evicted selection | P2, selected event leaves inspector falsely labeled | App retains kind=call/id after bounded collector eviction; selectedCall disappears and entryId becomes empty. | Already addressed — published fix `b154ae6a`: reconcile removed occurrences to remembered anchor/leaf; browser eviction regression. |
| R8 / 4216867521: navigator scroll | P2, synchronized selection can be offscreen | Current scrolling effect has [] dependencies and usually runs before snapshot data. Reveal/paging is separate, so selection changes do not scroll the owned navigator. | Already addressed — published fix `b154ae6a`: visible-selection/page-owned scrolling with identity guards and rounded geometry; no scroll reset on live refresh. |
| R9 / 4216867527: hidden detail failure | P2, request errors appear as missing history | App discards useDetail.error; failed loads are not cached but no retry is exposed. Inline rows show error text but likewise lack retry. | Already addressed — published fix `b154ae6a`: visible failure/retry for inspector and inline details, per-attempt request ownership; browser recovery regression. |

## Repeat review at head 745969a2

Repository, head, instructions and previous implementation/check evidence are unchanged; all prior nine threads are resolved. Fetched all updated REST pages and GraphQL threads (13 total, no pagination outstanding). Four new comments are independently actionable and in scope:

| Item / comment | Severity, scope relationship | Independent evidence | Current outcome |
| --- | --- | --- | --- |
| R10 / 4217467861: off-page focus | P2, introduced keyboard access defect in primary trace | Trace retains focused ID across page, collapse/filter changes; tabIndex fallback only handles empty focused string. Focus effect also depends only on focused rather than the visible rendered target. | Already addressed in this remediation: visible-focused fallback and effect follow rendered target; browser regression covers paging, arrow-key page crossing, collapse and filtering. |
| R11 / 4217467878: transient SSE refusal | P2, bounded-viewer admission prevents later live inspection | Server returns 429 at eight SSE clients; App returns before retry scheduling for every non-OK response or missing body. Frame-generation mismatches currently take the retry path too. | Already addressed in this remediation: transient refusals/offline retry; terminal HTTP or frame-generation failure aborts connection/refresh; browser regressions cover 429/503 recovery and no terminal retries. |
| R12 / 4217467889: parent cycles | P2, browser-only selection exposes a core unbounded traversal to untrusted stored entries | Installed Pi buildSessionPath and getBranch repeatedly follow parents without a visited set; frontend displays disconnected cycles. All projection.ts and extension.ts ancestry call sites audited. | Already addressed in this remediation: visited/budget ancestry before all native projections and anchor lookup; self/disconnected/missing-parent/selected-leaf tests retain raw evidence with explicit unavailable reason. |
| R13 / 4217467893: session-name budget | P2, unbounded snapshot/reconciliation text violates documented bounded read-only inspection | snapshot publishes displayText(name) without truncation; stateStamp serializes raw name each second. Entry names already bound sanitized text to 512. | Already addressed in this remediation: shared sanitized 512-character name and nameTruncated metadata used by snapshot/reconciliation, labeled in browser; hostile-name and immutable-source tests. |

Touched MUST rules: public API equivalence branches and malformed-input safety (native runtime Review + synthetic cycle tests), sanitize before budgets (hostile-name tests), keyboard accessibility/owned scrolling (browser tests), asynchronous ownership/cancellation after awaits (SSE browser/native tests), no model-prefix mutations (existing native pipeline regression), root gates and explicit/discovery Pi smoke. No settings, package metadata, publishing or dependency changes are required.

No out-of-scope enhancement, P0 incident, clarification dependency or external blocker was identified. Applicable MUST rules: local boundary and no private extension dependencies (Review); non-mutating model prefixes (native tests); display sanitation before truncation (hostile-input tests); cancellation/session-owned cleanup for timers/fetches (lifecycle/browser tests); both root gates and Pi smoke. Settings/publishing changes are inapplicable.

## Third review at head c63b99f7

Head/description/instructions and prior dispositions are unchanged; prior CI is now successful. All updated feedback pages were fetched: 17 threads, four new items, no pagination gaps.

| Item / comment | Severity, scope relationship | Independent evidence | Current outcome |
| --- | --- | --- | --- |
| R14 / 4217837423: malformed identity | P2, session-view boundary introduces a render crash for loader-accepted data | Native parser/index accepts JSON entry identity without runtime type validation; snapshot publishes id/parentId and React calls id.slice. Identity validation is absent in summary/ancestry/leaf publication. | Already addressed in this remediation: runtime entry/parent validation, bounded raw diagnostic samples/count, safe leaf/anchor/reconciliation and ancestry; table-driven identity tests plus real malformed fixture-server browser regression. |
| R15 / 4217837431: branch errors | P2, persisted selection loses historical context after transient failure | Branch catch shares top-level error which snapshot success clears; branch effect depends only on unchanged entryId. Detail retry fix does not cover this distinct request. | Already addressed in this remediation: branch-specific error and retry with per-attempt owner/AbortController; browser regression verifies persistence across successful live refresh and recovery without moving selection. |
| R16 / 4217837436: disclosure scope | P2, promised independent retained disclosure is not per-entry | JsonNode useState initializer only runs at mount; shared Inspector child is reused across changed scope maps. | Already addressed in this remediation: scope-keyed JsonNode mounting, entry-specific historical data scopes; A/B/A/B browser regression verifies retained independent disclosure. |
| R17 / 4217837441: child count | P2, filtered navigation misstates persisted structure | flatten computes retained children, but trace labels count as recorded total; Inspector indexed total is independently correct. | Already addressed in this remediation: trace labels filtered childCount as visible; browser sibling fixture proves one visible count without falsely labeling the recorded total. |

Touched MUST rules: validate public runtime behavior and malformed equivalence classes (native parser/index Review + runtime identity tests), retain raw payloads and public boundaries (diagnostic tests), scoped asynchronous failures/cancellation after awaits (branch browser tests), progressive-disclosure state isolation and keyboard semantics (browser regressions), accurate data provenance (filtered sibling tests), both root gates and Pi smoke. No settings, package metadata or model-visible prefix changes.

## Fourth review at head a5b741aa

Repository/head/description/instructions are unchanged and previous CI passed. Updated REST/GraphQL pages contain 22 threads with five new comments; all pagination is complete.

| Item / comment | Severity, scope relationship | Independent evidence | Current outcome |
| --- | --- | --- | --- |
| R18 / 4218201942: snapshot recovery | P2, initial or quiet live inspection can remain empty/stale | Snapshot catch has no owned retry; connected SSE need not emit another revision. Existing branch/detail retries do not cover it. | Already addressed in this remediation: owned snapshot retry, terminal admission classification and shared terminal fence cancelling pending snapshot/stream work. Quiet recovery, terminal snapshot and terminal SSE/pending retry browser regressions pass. |
| R19 / 4218201952: semantic kind | P2, loader-accepted data crashes introduced browser render | Summary kind passes type/role without runtime string validation; eventName can return a React-invalid object. | Already addressed in this remediation: invalid type/role/timestamp/block envelopes are diagnosed; kinds are bounded sanitized strings and legacy absent content is handled without raw mutation. Table-driven semantic classes and real malformed-kind browser regression pass. |
| R20 / 4218201957: duplicate identities | P2, UI can associate earlier entry with later raw evidence | Native getEntries retains duplicate rows; byId overwrites with last entry; hierarchy/React keys use ID. Existing field type validation does not establish uniqueness. | Already addressed in this remediation: all duplicated IDs are omitted/diagnosed, even collisions beyond navigation budget; ambiguous leaf/ancestor/detail lookup is unavailable, not last-writer evidence. Raw records remain unchanged; duplicate and browser regressions pass. |
| R21 / 4218201963: full-history detail fan-out | P2, introduced inline expansion can block Pi | Native buildSessionProjection constructs byId over all passed entries, although selected validated ancestry is sufficient for path/settings/context-edit/compaction projection. | Already addressed in this remediation: SessionFeed owns a structural EntryIndex, invalidates/releases it at owned boundaries and supplies it to all production projection/anchor callers; native projection receives validated path only. 50-detail/100,000-off-branch test proves zero full-history reads after initial index; every fixture leaf matches full native projection. |
| R22 / 4218201971: linked notices | P2, generated browser notices are not actually delivered | Build legalComments=linked emits LEGAL files; server fixed asset map omits them. | Already addressed in this remediation: legalComments=eof retains generated notices inside served app.js; real bundle regression verifies React/MIT text and absence of unavailable LEGAL link. |

Validation: local build/types/Biome, 67 local tests, 29 Chromium tests, both root gates and explicit/discovery/reload/replacement Pi smoke passed. No deferred item, clarification request or blocker; earlier 17 dispositions remain unchanged and reuse published evidence.

Touched MUST rules: public-runtime equivalence/complete malformed identity classes (Review + type/role/duplicate tests), accurate raw/projection association and original payload preservation (diagnostic/native comparison tests), session-owned cache invalidation/cleanup and cancellation (feed/retry tests), no model-prefix transitions (native regression), required third-party notices (real build test), local/root gates and Pi smoke. No unrelated settings, package promotion or release changes.

## Fifth review at head d9ef7505

Checkout, origin and branch PR #1510 match; PR remains open. Complete paginated REST reviews/inline/conversation comments and GraphQL threads were refreshed: 35 threads, 13 new unresolved items, no nested pagination. Earlier R1–R22 dispositions and unchanged instructions are reused without duplicate replies. Changed commits/diff and failed head CI were inspected independently; bot boilerplate and implementation reports contain no additional change requests.

| Item / comment | Severity and PR relationship | Independent evidence | Outcome before implementation |
| --- | --- | --- | --- |
| R23 / 4218652402 | P2, false execution provenance | create() uses current's most recent raw-ID occurrence instead of unique running-parent lookup; late parent adoption also needs ambiguity fencing. | Already addressed in validated remediation: unique running-parent lookup, ambiguity fence, explicit unavailable relationship; parent-overlap test. Published signed d48cb5d8; evidence reply posted and thread resolved. |
| R24 / 4218652412 | P2, lost retained results after bounded eviction | correlatedCalls excludes children whose occurrence parent no longer exists, even with an authoritative assistant anchor. | Already addressed in validated remediation: missing occurrence parents seed retained children by authoritative assistant anchor; child/grandchild eviction test. Published signed d48cb5d8; evidence reply posted and thread resolved. |
| R25 / 4218829807 | P2, malformed stored label aborts snapshot | Native label index retains JSON values; summarize passes truthy non-strings to string-only sanitation. | Already addressed in validated remediation: safe summary labels, raw label diagnostics and malformed native session-name getter protection; label/name equivalence tests. Published signed d48cb5d8; evidence reply posted and thread resolved. |
| R26 / 4218829820 | P2, malformed assistant envelope prevents raw inspection | identityIssue only checks arrays; detail ancestor lookup calls content.some unconditionally. | Already addressed in validated remediation: non-array assistant envelopes rejected, descendant traversal guarded and raw evidence retained; envelope table tests. Published signed d48cb5d8; evidence reply posted and thread resolved. |
| R27 / 4218829830 | P2, bounded snapshot omits selected active leaf | nodes takes first 10,000 while leafId references the later valid leaf. | Already addressed in validated remediation: active leaf/real bounded ancestry reserved within 10,000 nodes; late-leaf unit/browser tests. Published signed d48cb5d8; evidence reply posted and thread resolved. |
| R28 / 4218829839 | P2, pasted-query work freezes browser | Session and call predicates normalize unbounded query per entry; composition repeats it per segment too. | Already addressed in validated remediation: 512-character sanitized ingestion, once-normalized session/call/composition needles and cached message search; long-paste tests. Published signed d48cb5d8; evidence reply posted and thread resolved. |
| R29 / 4218970694 | P2, malformed tool arguments abort historical branch | branch reads block.arguments.path without a nullable/non-record guard. | Already addressed in validated remediation: tool-call envelopes validated and nullable arguments/nested metadata guarded; argument/metadata table tests. Published signed d48cb5d8; evidence reply posted and thread resolved. |
| R30 / 4218829852 | P2, advertised structured redaction misses credentials | Anchored exact-key regex misses x-api-key/openai_api_key/github_token. | Already addressed in validated remediation: credential suffix matching after complete key sanitation without masking metric/prose keys; prefixed-key tests. Published signed d48cb5d8; evidence reply posted and thread resolved. |
| R31 / 4218970702 | P2, string identities bypass display/URL budgets | Identity validation tests type/nonempty only; original overlong values reach snapshots and URLs. | Already addressed in validated remediation: 512-character identity rejection without identity rewriting; oversized ID/parent/leaf tests. Published signed d48cb5d8; evidence reply posted and thread resolved. |
| R32 / 4218970719 | P2, idle whole-history copying | SDK public SessionManager.getEntryCount is constant-time byId.size; extension ReadonlySessionManager's Pick omits it, so direct unconditional use is not type-supported. | Already addressed in validated remediation: feature-checked public SDK getEntryCount with explicit readonly-adapter fallback; zero idle history-read test. Published signed d48cb5d8; evidence reply posted and thread resolved. |
| R33 / 4219768678 | P2, pane click loses UI ownership | useNarrow depends on open flags/retained pane widths; the click changes layout mode without opening its drawer. | Already addressed in validated remediation: viewport-only breakpoint and bounded side allocation; widened-pane toggle/browser overflow regression. Published signed d48cb5d8; evidence reply posted and thread resolved. |
| R34 / 4219768689 | P2, filter reset restores a distant old anchor | reset clears anchor, then refresh immediately records old filtered IDs before new positions render. | Already addressed in validated remediation: explicit reset fence and pending-reset commit even for unchanged normalized IDs; distant/case-only filter and subsequent-scroll tests. Published signed d48cb5d8; evidence reply posted and thread resolved. |
| R35 / 4219768699 | P2, cache warming misattributed to user context | Installed CacheWarmer.streamSimple reuses saved request options without context_with_system; observePayload attaches every callback to previous context. No public request identifier proves association. | Already addressed in validated remediation: independently timestamped payload DTO/UI with explicitly unavailable turn association; replay/warming tests and disposal. Published signed d48cb5d8; evidence reply posted and thread resolved. |
| CI1 / run 37786510345 | P2, unrelated base release workflow/test mismatch | Failure is test/check-test-separation.test.ts expecting workflow_run; origin/main commit 02f99c9a changes publish trigger to push without updating that test. Neither file is in this PR's diff. | Historical deferral superseded: user-authorized CI1 repair is validated/published in signed f29816a2; eighth-review evidence and handoff 6065387207. No separate PR is needed. |

Applicable MUSTs before implementation: public runtime/API equivalence and complete envelope classes (SDK Review + table-driven tests), immutable raw identity/provenance and accurate incomplete labels (projection/correlation tests), sanitize before display/search budgets (privacy/search tests), viewport/focus/scroll ownership and task disposal (browser/lifecycle tests), unchanged normalized model prefixes (native runtime test), local boundaries and both root gates/Pi smokes. Guides: root AGENTS.md and docs/extension-conventions.md; settings/package/publication remain inapplicable.

## Sixth review at head cac2c418

Confirmed current checkout/origin and branch PR #1510; PR is open. All paginated REST reviews/inline/conversation data and GraphQL threads refreshed: 40 threads, five new unresolved items, no thread/comment pagination. Instructions and prior R1–R35 source behavior are unchanged except the independently verified inspect directory migration; previous evidence/replies are reused. Complete diff/commits, renamed source, current PR description and checks were inspected; boilerplate and historical reports add no change request. Run 37797448355 confirms the same CI1 release-workflow assertion, still deferred; head CI is running.

| Item / comment | Severity / PR relationship | Independent evidence | Current disposition |
| --- | --- | --- | --- |
| R36 / 4220791627 | P2, captured credential disclosure | secretKey suffix matching recognizes only underscore/hyphen separators; openaiApiKey/githubToken/xApiKey pass through. | Already addressed in validated changes: sanitized camel/acronym classification and metric/prose exclusion tests; published signed e6ef916d, evidence reply posted and thread resolved. |
| R37 / 4220791638 | P2, inaccessible eviction fallback | app snapshot fallback creates entry selection without filterVersion; both views gate reveal on that version. Async snapshot admission can also observe stale filter state. | Already addressed in validated changes: current filter epoch after async admission and represented fallback; delayed-snapshot browser reveal/read-only test; published signed e6ef916d, evidence reply posted and thread resolved. |
| R38 / 4220791645 | P2, unbounded repeated snapshot transfer | summarize returns timestamp and tool-result toolCallId directly; identityIssue checks timestamp type only and no result-ID shape/budget. | Already addressed in validated changes: timestamp/result-ID shape and 512-character limits with bounded raw diagnostics; exact/oversized/non-string tests; published signed e6ef916d, evidence reply posted and thread resolved. |
| R39 / 4220791655 | P2, raw evidence inaccessible after malformed replay | Native projectContextEntry unconditionally reads replacement.content unless replacement is null; loader retains unchecked JSON, writer accepts null or string/array content. | Already addressed in validated changes: target/replacement guards, all native target-role/null/string/array comparisons and authenticated edit/descendant raw endpoints; published signed e6ef916d, evidence reply posted and thread resolved. |
| R40 / 4220791666 | P2, valid title-clear event omitted | SessionInfoEntry.name is optional; native getSessionName handles missing/empty names as a clear. Current identity validation rejects undefined. | Already addressed in validated changes: optional/empty title-clear accepted with raw malformed-name diagnostics preserved; native equivalence tests; published signed e6ef916d, evidence reply posted and thread resolved. |
| PR1 / description | P3, stale user-facing scope/evidence | Description links targeted the deleted session-inspector directory and main verification listed old 28/12 counts. | Already addressed: external description now states the context-primary outcome, inspect paths, 162 local/40 browser checks, explicit limits and deferred CI1; handoff comment 6063701163 posted. |

Applicable MUSTs before implementation: complete installed-runtime equivalence classes (SDK Review + table-driven native comparisons); sanitized-before-classification bounded immutable data (privacy/summary tests); current mutable ownership after async snapshot admission and retained filtered selection (delayed-snapshot browser test); raw/projection separation without model-visible prefix transitions (detail/native runtime regressions); project-local boundaries and lifecycle cleanup (Pi explicit/discovery/reload/replacement smoke); both root gates. Guides: AGENTS.md and unchanged docs/extension-conventions.md. Settings/package/publishing rules remain inapplicable; no new owned tasks.

## Additional final-refresh finding

R41 / 4221011461 (thread PRRT_kwDOSW8GGM6qb3Um): P2, already addressed in published signed 26e9ccb1; evidence-backed reply posted and thread resolved. Final evidence: 185 local tests, 40 Chromium tests, local build/types/Biome, Pi smoke and root check passed; unchanged root test inputs reuse the passing 7,461-test suite. Final refresh found a new system-message envelope defect at reviewed head cac2c418. Pi AI contentText assumes string or block array; getCurrentSystemMessage/getCurrentSystemPrompt also consume sections and getCurrentTools iterates tool deltas. Object/missing/primitive content and null blocks can abort branch replay; malformed section/delta shapes share the same failure class. This exposes resumed-session raw/history inspection, within the original goal. Validate those consumed fields before native replay, retaining optional/null no-op metadata, section removals, unknown non-text object blocks and native tool-delta ordering; verify malformed tables plus native equivalence and authenticated raw access. Earlier five fixes remain published/settled. Applicable MUSTs and guide scope are unchanged; root test inputs are unchanged and prior full root evidence is reused, not rerun unnecessarily.

## Seventh review at head 9334c239

Checkout/origin/branch PR #1510 confirmed; PR is open and clean. Full paginated reviews/inline/conversation/thread evidence and PR description/commits/checks refreshed: 43 threads, two new unresolved, no outstanding pagination. Source/diff and instructions are unchanged; prior R1–R41 evidence/replies are reused. Latest run 37805056011 fails the same unchanged CI1 release-workflow assertion, not inspector code.

| Item / comment | Severity / relationship | Independent evidence | Current disposition |
| --- | --- | --- | --- |
| R42 / 4221348959 | P2, checkpoint raw/history inspection fails | sessionEntryToContextMessages injects truthy compaction.systemMessage directly; message-only validation never examines it. contentText/sections/tool deltas can throw. Compaction is the only additional stored system-message source. | Already addressed in validated changes: shared checkpoint/ordinary system-envelope guards; injected/falsy/malformed/valid/older-newer checkpoint tables, native equality and authenticated raw routes. Published signed b1395dfa; R42/R43 evidence replies posted and threads resolved; R44 native-audit outcome published in handoff 6064495698. |
| R43 / 4221348985 | P2, bounded branch refresh strands selection | Snapshot admission reconciles calls only; an old entry outside the new 10,000-node inventory retains cached detail/branch and cannot be revealed. | Already addressed in validated changes: represented-ID reconciliation with current filter epoch; >10,000-entry branch transition, filtered fallback, stable represented preview and empty-inventory browser tests. Published signed b1395dfa; R42/R43 evidence replies posted and threads resolved; R44 native-audit outcome published in handoff 6064495698. |
| R44 / native audit | P2, valid legacy projection is blocked | Installed sessionEntryToContextMessages normalizes null/absent system content to empty string, and user/assistant/toolResult to empty arrays. Current system/assistant validators reject those supported legacy branches. Checkpoint messages do not get that normalization. | Already addressed in validated changes: ordinary message-only native nil-content normalization; all four roles and absent/undefined/null cases match native projection without changing raw records. Checkpoint content is not normalized. Published signed b1395dfa; R42/R43 evidence replies posted and threads resolved; R44 native-audit outcome published in handoff 6064495698. |

Applicable MUSTs before implementation: enumerate every system-message source and native normalization branch (SDK Review + checkpoint/legacy tables and native equality); raw evidence and original IDs/content remain immutable (detail/authenticated HTTP tests); bounded selection membership/current async filter ownership and cancellation/disposal (browser transitions); unchanged normalized model prefix (runtime regression); self-contained project-local layout/relative imports (types/build + explicit/discovery/reload/replacement Pi smoke); both root gates. AGENTS.md and unchanged docs/extension-conventions.md apply; no settings/package/release changes. No paid-provider or physical-desktop claims.

## Eighth review and authorized CI repair at head 8cbe77e2

Repository/branch/PR #1510 confirmed open and clean. Full PR description/commits/diff/checks and paginated review/inline/conversation/thread evidence refreshed: 45 threads, two unresolved, no outstanding pagination. Prior R1–R44 dispositions/evidence reused unchanged. AGENTS.md and docs/extension-conventions.md unchanged. User explicitly asks to fix failed CI, moving CI1 from settled deferral to authorized action.

| Item / comment | Severity / relationship | Independent evidence | Current disposition |
| --- | --- | --- | --- |
| CI1 / run 37809934640 | P2, user-authorized CI repair required to make this PR pass merged-base checks | Affected-test CI merges main into this branch. Main 02f99c9a switches publish trigger to push while release condition and tested-revision checkout still require workflow_run; the unchanged policy test fails. Local old-base checks passed because its trigger was still correct. | Already addressed and published: CI1 f29816a2; R45/R46 df1720b0. Evidence replies posted and threads resolved; handoff 6065387207. GitHub CI awaiting completion. Node/npm installation preflight, 230 local tests (14 files), 43 Chromium tests, Pi load/discovery/reload/replacement smoke and both merged-base root gates passed (7,674 tests, two skips). Full evidence/audits in VERIFICATION.md. |
| R45 / 4221710976 | P2, filtered call eviction hides represented navigator selection | Tree de-duplicates reveal work solely by selected ID, unlike Trace's serial. A late anchor excluded by a filter is reintroduced on eviction with the same ID but new reveal ownership/serial and cannot re-page. | Already addressed and published: CI1 f29816a2; R45/R46 df1720b0. Evidence replies posted and threads resolved; handoff 6065387207. GitHub CI awaiting completion. Node/npm installation preflight, 230 local tests (14 files), 43 Chromium tests, Pi load/discovery/reload/replacement smoke and both merged-base root gates passed (7,674 tests, two skips). Full evidence/audits in VERIFICATION.md. |
| R46 / 4221710996 | P2, bounded historical inspection can allocate unbounded joined prompt | branch calls getCurrentSystemMessage/getCurrentSystemPrompt on projected current and previous messages before capture's 64 KiB bound. Native system helper collects/joins all content fragments and section values. Checkpoint and ordinary system sources both participate. | Already addressed and published: CI1 f29816a2; R45/R46 df1720b0. Evidence replies posted and threads resolved; handoff 6065387207. GitHub CI awaiting completion. Node/npm installation preflight, 230 local tests (14 files), 43 Chromium tests, Pi load/discovery/reload/replacement smoke and both merged-base root gates passed (7,674 tests, two skips). Full evidence/audits in VERIFICATION.md. |

MUSTs before implementation: enumerate every native replay source/content/section/compaction branch (table/native equality and explicit budget tests); never truncate source/model prefixes or mutate raw records (native equality/runtime tests); owned reveal identity, independent manual paging and filter ownership (late-anchor/browser regression and retained paging tests); current/previous cumulative preview budgets and authenticated raw evidence (HTTP tests); standalone relative imports/cancellation/disposal (build/types and explicit/discovery/reload/replacement Pi smoke); CI must run both root gates and publish must not repeat or bypass them (workflow policy tests plus full merged-base gates). AGENTS.md and docs/extension-conventions.md apply. No extension settings, package promotion or release dispatch. Paid-provider/final-transport/physical-desktop paths remain unverified.

## Ninth review at head 33a66beb

Confirmed repository/branch PR #1510 open and clean, successful CI run 37816605334. Description/commits/full diff/checks and every feedback page refreshed: 47 threads, two new unresolved, no outstanding pagination. Instructions and prior R1–R46/CI1 evidence unchanged; settled outcomes/replies reused.

| Item / comment | Severity / relationship | Independent evidence | Current disposition |
| --- | --- | --- | --- |
| R47 / 4222197516 | P2, historical viewer replay bypasses advertised bounds | Native getCurrentSystemMessage also calls getCurrentTools; branch explicitly replays/maps tools. Envelope validation scans arbitrarily large delta arrays, and systemReplayIssue budgets no tool deltas/metadata. Ordinary and checkpoint current/previous projections share this path. | Already addressed and published in signed user commit 40bf25d3; validated 283 local/44 browser tests, Pi smoke, root check and 7,676 root tests (two skips). Evidence replies posted and both threads resolved; handoff 6066136884. |
| R48 / 4222197520 | P2, live event publications bypass identity bounds | Collector start/update/end retain raw own/parent IDs, tool names and anchors in every snapshot. Own lookup/create paths have no runtime budget; invalid parent identity can leak or be adopted later. Duration is also directly retained. | Already addressed and published in signed user commit 40bf25d3; validated 283 local/44 browser tests, Pi smoke, root check and 7,676 root tests (two skips). Evidence replies posted and both threads resolved; handoff 6066136884. |

MUSTs before implementation: enumerate all ordinary/checkpoint current/previous native tool replay branches (boundary/cumulative/metadata/native equality + mocked no-helper tests); reject over-budget identity rather than truncate/rewrite and keep raw/model-prefix inputs unchanged (all event phases, parent/anchor/name/duration tables and prefix tests); explicit bounded unavailable relationship/event evidence with complete snapshot/feed publication paths (browser/HTTP DTO tests); current generation/context ownership and disposal unchanged (lifecycle and Pi standalone/discovery/reload/replacement smoke); both root gates. AGENTS.md and unchanged docs/extension-conventions.md apply; no settings/package/release changes or new dependencies. Paid-provider/final-transport/physical-desktop paths remain unverified.

## Concurrent CI1 update during ninth-review validation

While the full root suite ran, user/GitHub commit 4068d169 changed the same checkout/head back to the push trigger; verified author, diff and refreshed PR metadata. The 7,673-pass/one-failure result again isolates the release-policy assertion; this is new evidence, not failure of R47/R48. Preserve the user's committed push choice. CI1 is actionable/in scope because this new PR commit introduces failed checks and a release job that still expects workflow_run metadata.

Before continuing CI implementation, applicable MUST audit: successful exact-main-push revision only (pure gate-state tests for event/branch/SHA, terminal failures, latest runs and malformed statuses); preserve explicit manual-dispatch behavior, never repeat checks/tests in publish, verify CI before dependency/publication scripts (workflow policy tests); bound polling and API failures, never log credentials (offline deterministic tests/code audit); root canonical workflows unchanged (no new npm entrypoint); no release dispatch/publication. Implement scripts/wait-for-main-ci.mjs as a readonly GitHub CI gate, update the job condition/checkout for push/manual events, and align the policy assertion without weakening successful-CI gating. R47/R48 remain validated locally; both root gates must be rerun on this changed root input. CI1 published/validated in signed user commit 40bf25d3. The same commit removes the obsolete separation test; do not recreate it. Pure gate-state tests and workflow code audit pass; live main-push gate integration is unverified because no release was dispatched. Latest CI evidence is maintained in handoff 6066136884.

## Final-refresh findings R49–R56

Head e216c423 CI succeeded in run 37822339765; 55 threads, eight new unresolved, no pagination. The reviewer evidence was independently checked against native buildContextEntries/projectContextEntry, Collector/correlatedCalls, snapshot selection, live hierarchy remapping, credential classifier and skill-evidence loops. Each is P2 and exposes this PR's read-only/accurate/bounded inspection goal; all are already addressed in signed published 6610f66c. Eight evidence replies are posted and threads resolved; handoff 6066136884. Passed 298 local/46 browser tests, Pi smoke, root check and 7,676 root tests (two skips). Latest CI status is maintained in the handoff; prior e216c423 CI passed.

| Item | Evidence / intended verification |
| --- | --- |
| R49 / 4222408284 | Raw ancestry semantic guards reject superseded checkpoints/omitted content before native compaction. Preserve structural safety on every parent, validate native-selected/edited messages; native compaction/previous/raw regressions. |
| R50 / 4222408288 | Sequential same-ID/same-anchor calls evade running-overlap guard and seed both results. Fence multiplicity; same/different-anchor and evicted descendant correlation tests. |
| R51 / 4222408296 | Live hierarchy overwrites raw parent ID with occurrence ID; missing occurrence yields undefined parent view. Preserve raw parent fallback; live eviction browser test. |
| R52 / 4222408303 | Still-captured call can retain an anchor omitted from 10,000-node snapshot. Make navigator target explicitly unavailable while retaining captured call inspection; bounded branch transition browser test. |
| R53 / 4222408306 | Normalized secret_access_key does not match secret_key suffix. Add exact secret-access-key class with identifier/metric exclusions; privacy tables. |
| R54 / 4222519022 | Raw assistant arrays scan before a length budget. Bound every content-array scan (messages/system/edit) before traversal; sparse/getter boundary tests. |
| R55 / 4222519036 | Skill lookup is linear and nested traversal/evidence allocation cumulative unbounded. Index paths, filter status first and enforce cumulative scan/result bounds with explicit incomplete capture; performance/ordering tests. |
| R56 / 4222519047 | !isError treats absent legacy outcome as success. Require explicit false; unknown/error/valid native outcome tables. |

Before implementation, MUSTs: complete compaction/edit/source/previous decision audit and unchanged original IDs/parents/native prefixes (native equality and raw HTTP tests); complete correlation and display remapping audit (sequential/different-anchor/eviction/browser tests); cumulative traversal before allocation and explicit unavailable/truncated labels (array/evidence bounds and read-only tests); exact credential classification without broad prose masking (privacy exclusions); asynchronous ownership/cancellation/disposal unchanged (existing lifecycle/Pi smoke). AGENTS.md and docs/extension-conventions.md apply; no settings/package/release/paid-provider changes. Revalidate standalone build/types, local/browser/Pi smoke and both root gates for changed code.

## Refresh R57–R59 at b042ca1d

58 threads, three new unresolved, no pagination; original PR remains open. R57 / 4222619489 (P2) is valid/in scope: session ID bypasses display/publication bounds in snapshot (quiet stamp does not use it); reject oversized/non-string ID for publication and sanitize bounded display copies, preserving raw manager identity. R58 / 4222619504 (P2) is already addressed in published 6610f66c by non-empty/512-character persisted tool-call ID/name validation; add exact boundary regression evidence and reply without duplicate implementation. R59 / 4222619516 (P2) is valid/in scope: LiveDrawer reveal identity tracks only selected occurrence, not its late-adopted ancestry; key reveal by bounded actual parent chain and preserve passive/manual disclosure.

Applicable MUSTs before implementation: original IDs unchanged, terminal display sanitation/bounded publication (snapshot/cache/session-ID tables); complete reveal ancestry/eviction/cycle decision class with owned disclosure (late-parent browser + passive state); standalone native prefixes/lifecycle (existing local/Pi regressions); both root gates. AGENTS.md and docs/extension-conventions.md apply. R57/R59 implemented, validated and published in signed 931dc054; R58 already addressed in 6610f66c and independently reverified. Three evidence replies posted and threads resolved; handoff 6066136884. Passed 306 local tests/47 Chromium tests, build/types/Biome, Pi smoke and root check. Unchanged root-test inputs reuse the passing 7,676-test gate. No settings/package/release changes.

## Publication and validation

Published signed implementation: `b154ae6a` on the original open PR branch. Local build/types/Biome, 37 local tests, 16 Chromium tests, Pi CLI smoke, `npm run check` and `npm test` passed (542 root files; 7,461 tests pass, one existing skip). R4's prior selected-leaf regression passes unchanged. All original nine per-thread outcomes were replied/resolved and CI passed for tracking head `745969a2`. Repeat-review remediation passed local build/types/Biome, 42 local tests, 21 Chromium tests, Pi CLI smoke and both root gates (same 7,461 passing root tests, one skip); its four thread dispositions are ready for publication/replies. Third-review remediation passed local build/types/Biome, 56 local tests, 25 Chromium tests, explicit/discovery Pi smoke and both root gates (7,461 root tests pass, one existing skip). No item is deferred or needs clarification. Final GitHub status is recorded in the PR handoff.
