feat(perps): decouple agentic cache fingerprint from project EAS fingerprint#30569
Merged
Conversation
…erprint The shared build cache that backs `--mode auto` was keyed by the same fingerprint EAS Build and EAS Update use (`scripts/generate-fingerprint.js` via `fingerprint.config.js`). That fingerprint conservatively hashes build outputs (`ios/build/`, `.gradle/`, IDE state, env-populated `xcconfig`/`google-services.json`) on the theory that they could conceivably influence the produced binary. For EAS / OTA that is the right call: never reuse a build whose inputs you cannot vouch for. For the agentic cache it is the wrong call. Build outputs are non-deterministic across worktrees, so two parallel slots on the same commit produce different keys and never share a cached `.app` — the cross-worktree win the cache was designed for never lands. Re-running on the same slot, even on the same branch, can also drift the key as the build itself mutates hashed inputs. Add `scripts/perps/agentic/lib/compute-cache-fp.js`, an agentic-local fingerprint that uses the same `extraSources` (so anything that genuinely affects the binary still participates) but `ignorePaths` the per-worktree build artifacts. `bc_fingerprint` now invokes this instead of the repo-wide script. EAS / OTA pipelines continue to use `scripts/generate-fingerprint.js` and `fingerprint.config.js` unchanged. Verified against three worktrees on the same commit (c06187a, branch=main): mm-1: c7fe9e2161109d4ff2e092e068821a2e9984aac5 mm-5: c7fe9e2161109d4ff2e092e068821a2e9984aac5 mm-6: c7fe9e2161109d4ff2e092e068821a2e9984aac5 A new unit test asserts the fingerprint is unaffected by poisoning an ignored path (`ios/build/`).
Contributor
|
CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes. |
…ss claim
R1 caught two issues with the initial decoupled-fp design:
B1. `ios/*.xcconfig`, `android/app/google-services.json`, and
`android/app/src/main/assets/InpageBridgeWeb3.js` were on the
ignorePaths list. All three are read at build time and embedded in
the produced binary — ignoring them means the cache could serve a
binary built against different secrets / Firebase config / runtime
JS bridge. Remove them.
B2. `createFingerprintAsync` always loads `fingerprint.config.js` and
merges the project config with caller options. The script's claim
of "bypassing" the config was wrong — we extend it. Update the
source comment, README, and bc_fingerprint comment to describe the
actual relationship.
Add `app/core/InpageBridgeWeb3.js` to extraSources so JS-only changes
to the bridge source still invalidate the cache after we ignore the
generated android-asset mirror.
Tests now assert both halves of the boundary:
- poisoning an ignored path (`ios/build/`) must NOT shift the fp
- poisoning a hashed binary-affecting input (`InpageBridgeWeb3.js`)
MUST shift the fp
Verified mm-1 and mm-6 (aligned env state) still converge to the same
fp; mm-5 (different `.ios.env` + missing `google-services.json`)
correctly diverges — the cache only reuses across worktrees when the
actual build inputs match.
…poison R2 found that `createFingerprintAsync(projectRoot, options)` OVERRIDES the config's `extraSources` rather than merging them — passing only the bridge source dropped the six project extraSources from `fingerprint.config.js` (`.yarn/patches`, `.github/workflows`, `.github/scripts`, `react-native.config.js`, `scripts/build.sh`, `scripts/setup.mjs`), regressing coverage relative to the project fingerprint. Mirror the project's extraSources verbatim in `compute-cache-fp.js` and append the bridge source. Update the file header comment to describe the actual override-vs-merge semantics. R2 nits: - Test that mutates `app/core/InpageBridgeWeb3.js` now uses a trap-based restore helper so a fingerprint failure cannot leave the worktree poisoned. - Add a regression test that poisoning a project extraSource (e.g. `scripts/setup.mjs`) shifts the agentic fp, proving the inherited extraSources actually participate. Cross-worktree convergence still works for aligned-env slots (mm-1 ≡ mm-6 on the same env state hash to identical fp); mm-5 correctly diverges because its `.ios.env` differs.
Contributor
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 303aa11. Configure here.
… merge semantics R3 left two non-blocking nits, both addressed: - `_poison_must_shift_fp` no longer clobbers the suite-level EXIT trap. Capture the previous trap via `trap -p EXIT` before layering the temporary restore trap, then re-install the original via `eval`. An early abort inside the helper still triggers `.agent/build-cache` cleanup. - File header comment in `compute-cache-fp.js` was inaccurate: only `extraSources` is overridden by caller options; `ignorePaths` is merged with the config's list. Comment now matches `@expo/fingerprint` 0.15.x behaviour.
…cating extraSources Bugbot caught that manually duplicating the project's extraSources is brittle: future edits to fingerprint.config.js would silently fail to flow into the agentic fingerprint because the explicit options array overrides the config's. `require()` the project config directly and spread its `extraSources` and `ignorePaths` into our options. The agentic fingerprint now stays in sync with `fingerprint.config.js` by construction; we just append the bridge source + per-worktree-artifact ignore paths.
|
geositta
approved these changes
May 22, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.




Description
Adds
scripts/perps/agentic/lib/compute-cache-fp.js, an agentic-local native-build fingerprint, and switches the build cache inbc_fingerprintto use it instead ofscripts/generate-fingerprint.js. The project-wide fingerprint script andfingerprint.config.jsare untouched, so EAS Build, EAS Update, and the OTA fingerprint guard innightly-ota-updates.mdkeep their existing semantics.Why:
--mode auto's shared cache (#30565) was keyed off the same fingerprint EAS/OTA depend on, which conservatively hashes build outputs (ios/build/,.gradle/, IDExcuserdata, env-populatedxcconfig/google-services.json). Those paths diverge per worktree, so two slots on the same commit hashed to different keys and never shared a cached.app— the cross-worktree benefit the cache was designed for never landed. The new fingerprint uses the sameextraSources(so anything that genuinely affects the binary still participates) but ignores the per-worktree noise paths.Verified across three worktrees on the same commit (
c06187a24c, all onmain):Identical → next
--mode autodispatch on any of these slots will install the cached artifact from whichever slot built first.Changelog
CHANGELOG entry: null
Related issues
Follows #30565.
Manual testing steps
Programmatic check the test suite runs:
New section "agentic fp ignores build artifacts" verifies the ignorePaths actually take effect.
Screenshots/Recordings
N/A — script-only change, no UI surface.
Before
N/A
After
N/A
Pre-merge author checklist
test-build-cache.sh)compute-cache-fp.js)Performance checks (if applicable)
Pre-merge reviewer checklist
Note
Medium Risk
Changes the cache key used for agentic preflight native build reuse; incorrect ignore/hashing boundaries could cause stale or mismatched cached binaries across worktrees.
Overview
Decouples the agentic shared native build cache fingerprint from the repo-wide EAS/OTA fingerprint by introducing
scripts/perps/agentic/lib/compute-cache-fp.jsand switchingbc_fingerprintto use it.The new fingerprint inherits
fingerprint.config.jsextraSources(plus explicitly hashesapp/core/InpageBridgeWeb3.js) while addingignorePathsfor per-worktree build outputs (e.g.,ios/build, Xcodexcuserdata,.gradle, NDK.cxx) so cache artifacts can be shared across parallel worktrees.Updates agentic docs to describe the new keying behavior and extends
test-build-cache.shwith boundary tests ensuring ignored paths don’t shift the fingerprint while binary-affecting sources still do (and adjusts the fast-mode failure test to reference the new script).Reviewed by Cursor Bugbot for commit 32aa686. Bugbot is set up for automated code reviews on this repo. Configure here.