[PR #2690] [MERGED] perf(artifacts): share sealed inventory and report in inspect_artifact #5314

Closed
opened 2026-10-31 01:05:39 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/2690
Author: @kaoru0822-kitauji
Created: 10/13/2026
Status: ✅ Merged
Merged: 10/13/2026
Merged by: @morluto

Base: main ← Head: perf/artifact-inspection-sealed-inventory


📝 Commits (5)

  • 0d7c46b perf(artifacts): share sealed inventory and report in inspect_artifact
  • 1981e23 Merge remote-tracking branch 'origin/main' into perf/artifact-inspection-sealed-inventory
  • 1d5d057 Merge remote-tracking branch 'origin/main' into perf/artifact-inspection-sealed-inventory
  • 4014ae4 Merge remote-tracking branch 'origin/main' into perf/artifact-inspection-sealed-inventory
  • ed80d29 Merge remote-tracking branch 'origin/main' into perf/artifact-inspection-sealed-inventory

📊 Changes

1 file changed (+10 additions, -2 deletions)

View changed files

📝 src/artifacts/ArtifactProvider.ts (+10 -2)

📄 Description

Problem

inspect_artifact on a large bundle spent much of its CPU re-validating and re-digesting the same payload. On Keynote.app the payload is a 42 MB inventory. A CPU profile of rea inspect-artifact /Applications/Keynote.app showed it being canonically digested into an Evidence ID about four times and zod-parsed about five times:

Boundary Repeated work
createArtifactInspection → parseEvidence re-authenticates the nested inventory Evidence (full parse + clone + ID digest)
createAnalysisExecution → jsonValueSchema.parse clones the inspection report
outer createEvidence parses the envelope with the mutable-result schema
recordEvidence → immutableEvidence → parseEvidence re-authenticates the outer Evidence (parse + ID digest)

Root cause

inspectArtifact owns two freshly parsed values: the inventory and the inspection report. It left both mutable. The Evidence layer already has a zero-copy path for sealed immutable JSON snapshots (freezeJsonSnapshot / immutableEvidenceSnapshots), but these values never qualified for it.

Fix

Seal both exclusively owned values with freezeJsonSnapshot at the point where they're produced. Each downstream boundary then uses the existing immutable path: nested createEvidence remembers the record, parseEvidence hits the snapshot cache, jsonValueSchema.parse returns the sealed report as-is, and the outer Evidence is shared and recorded without re-authentication. No contract or output changes.

Measurements

These are warm runs, three each, on an Apple Silicon Mac, measured with /usr/bin/time -l around rea inspect-artifact <app> --format json. Main and the branch were built from the same base.

Target main (real / user / peak RSS) branch (real / user / peak RSS)
Keynote.app (42 MB result) 7.60 s / 6.76 s / 725 MB 6.46 s / 5.58 s / 588 MB
Anki.app (7.7 MB result) 1.88 s / 2.30 s / 443 MB 1.74 s / 2.17 s / 437 MB

On Keynote that is about 15% less wall time, 17% less user CPU and 19% less peak RSS. Token cost is unchanged: stdout is byte-identical before and after on Keynote and Sublime Text (same SHA-256). Cold-cache runs and the MCP adapter were not measured separately; both share this provider path.

Validation

  • npm run test:focused on every test file that references inspect_artifact / createArtifactInspection (22 files: CLI, MCP, sessions, composition, acceptance, conformance): 138 passed. This shows no downstream consumer mutates the now-sealed report.
  • npm run check:fast passes.

Remaining

createArtifactInspection still re-parses the inventory with artifactInventoryResultSchema, and its final artifactInspectionResultSchema.parse traverses the nested Evidence once more (about 0.25 s on Keynote). Removing those would mean changing what the domain function's unknown input contract validates, so it's left out of this change.

🤖 Generated with Claude Code


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/2690 **Author:** [@kaoru0822-kitauji](https://github.com/kaoru0822-kitauji) **Created:** 10/13/2026 **Status:** ✅ Merged **Merged:** 10/13/2026 **Merged by:** [@morluto](https://github.com/morluto) **Base:** `main` ← **Head:** `perf/artifact-inspection-sealed-inventory` --- ### 📝 Commits (5) - [`0d7c46b`](https://github.com/morluto/rea/commit/0d7c46b103d69cf8678608ae6da43d9c202c00ca) perf(artifacts): share sealed inventory and report in inspect_artifact - [`1981e23`](https://github.com/morluto/rea/commit/1981e23189ff333bd6ebeb50531c046b77225246) Merge remote-tracking branch 'origin/main' into perf/artifact-inspection-sealed-inventory - [`1d5d057`](https://github.com/morluto/rea/commit/1d5d0575320e5db1b7bd69352c6413ba75e59ab5) Merge remote-tracking branch 'origin/main' into perf/artifact-inspection-sealed-inventory - [`4014ae4`](https://github.com/morluto/rea/commit/4014ae4fe8eb37cc6a4135b1a8b394e375ef3b18) Merge remote-tracking branch 'origin/main' into perf/artifact-inspection-sealed-inventory - [`ed80d29`](https://github.com/morluto/rea/commit/ed80d29dd05ab55f3ca6801ded6a0e39e6cb1387) Merge remote-tracking branch 'origin/main' into perf/artifact-inspection-sealed-inventory ### 📊 Changes **1 file changed** (+10 additions, -2 deletions) <details> <summary>View changed files</summary> 📝 `src/artifacts/ArtifactProvider.ts` (+10 -2) </details> ### 📄 Description ## Problem `inspect_artifact` on a large bundle spent much of its CPU re-validating and re-digesting the same payload. On Keynote.app the payload is a 42 MB inventory. A CPU profile of `rea inspect-artifact /Applications/Keynote.app` showed it being canonically digested into an Evidence ID about four times and zod-parsed about five times: | Boundary | Repeated work | | --- | --- | | `createArtifactInspection` → `parseEvidence` | re-authenticates the nested inventory Evidence (full parse + clone + ID digest) | | `createAnalysisExecution` → `jsonValueSchema.parse` | clones the inspection report | | outer `createEvidence` | parses the envelope with the mutable-result schema | | `recordEvidence` → `immutableEvidence` → `parseEvidence` | re-authenticates the outer Evidence (parse + ID digest) | ## Root cause `inspectArtifact` owns two freshly parsed values: the inventory and the inspection report. It left both mutable. The Evidence layer already has a zero-copy path for sealed immutable JSON snapshots (`freezeJsonSnapshot` / `immutableEvidenceSnapshots`), but these values never qualified for it. ## Fix Seal both exclusively owned values with `freezeJsonSnapshot` at the point where they're produced. Each downstream boundary then uses the existing immutable path: nested `createEvidence` remembers the record, `parseEvidence` hits the snapshot cache, `jsonValueSchema.parse` returns the sealed report as-is, and the outer Evidence is shared and recorded without re-authentication. No contract or output changes. ## Measurements These are warm runs, three each, on an Apple Silicon Mac, measured with `/usr/bin/time -l` around `rea inspect-artifact <app> --format json`. Main and the branch were built from the same base. | Target | main (real / user / peak RSS) | branch (real / user / peak RSS) | | --- | --- | --- | | Keynote.app (42 MB result) | 7.60 s / 6.76 s / 725 MB | 6.46 s / 5.58 s / 588 MB | | Anki.app (7.7 MB result) | 1.88 s / 2.30 s / 443 MB | 1.74 s / 2.17 s / 437 MB | On Keynote that is about 15% less wall time, 17% less user CPU and 19% less peak RSS. Token cost is unchanged: stdout is byte-identical before and after on Keynote and Sublime Text (same SHA-256). Cold-cache runs and the MCP adapter were not measured separately; both share this provider path. ## Validation - `npm run test:focused` on every test file that references `inspect_artifact` / `createArtifactInspection` (22 files: CLI, MCP, sessions, composition, acceptance, conformance): 138 passed. This shows no downstream consumer mutates the now-sealed report. - `npm run check:fast` passes. ## Remaining `createArtifactInspection` still re-parses the inventory with `artifactInventoryResultSchema`, and its final `artifactInspectionResultSchema.parse` traverses the nested Evidence once more (about 0.25 s on Keynote). Removing those would mean changing what the domain function's `unknown` input contract validates, so it's left out of this change. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-31 01:05:39 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#5314
No description provided.