Cache Fingerprints
This document explains cache invalidation and regeneration behavior for:
scripts/build-metadata-cache.mjsscripts/build-components-cache.mjs
Fingerprinting is used for components cache invalidation. Metadata now prioritizes existing descriptions and only uses Gemini when needed.
Why Fingerprints Exist
Each pattern gets a deterministic hash (sha256) from a set of source inputs.
If the hash did not change, the script skips regeneration for that pattern.
If the hash changed, the script regenerates that pattern only.
Note:
- This applies to components cache invalidation.
- Metadata no longer uses fingerprint equality as a skip gate.
Pipeline Order
build:artifacts runs in this order:
build-metadata-cache.mjsbuild-components-cache.mjs- artifacts report finalization
Metadata runs first because it refreshes the shared description cache. Components can still run independently when description data is incomplete.
Metadata Processing Logic
Metadata no longer uses fingerprint equality as a hard skip gate.
For each pattern, description resolution follows this order:
- previous metadata cache description
public/search-index.jsondescription- Notion
Descriptionproperty (when available) - Gemini generation (only if all previous sources are missing/invalid)
Output file:
public/components/components-metadata.json
Components Fingerprint
Defined in buildFingerprint(...) inside scripts/build-components-cache.mjs.
Inputs used in the components fingerprint payload:
appVersiongeneratorVersionidtitleslugtags(from search index entry)referenceImages(resolved from search entry image fields)
Components Skip Logic
Components skips a pattern when:
--forceis not set- previous component artifact exists
- previous
sourceFingerprintequals current components fingerprint
Otherwise components regenerates that pattern, writes public/components/code/<id>.tsx, and updates components status.
Metadata And Components Independence
Components no longer depend on metadata descriptions for invalidation.
Description context for components is resolved as:
- metadata description (if valid)
- search-index description (if valid)
- empty description (continue using title/tags/image context)
Artifacts finalization now reports components without descriptions as warnings, not hard failures.
Gemini Cost Implications
- Metadata calls Gemini only when no valid existing description is found from cache/search/Notion.
- Components remains a Gemini code-generation stage.
- Components fingerprint stability keeps component Gemini calls bounded.
If component fingerprints are stable, components are skipped and no new component Gemini call is made for those patterns.
Limit and Safety Notes
To test safely with a subset:
npm run build:artifacts -- --limit=3
Both metadata and components now honor npm-style limit propagation in the artifacts pipeline, so the subset stays consistent.
Quick Debug Checklist
- Check metadata cache source + limit:
cat public/components/components-metadata.json | jq '.source, .stats'
- Check description source and status for one pattern:
cat public/components/components-metadata.json | jq '.items[] | select(.id=="343e4bae-3d76-80b4-872a-c0ebf5b4ed4c") | {id, lastProcessedAt, status, description}'
- Check component status fingerprint:
cat public/components/components-status.json | jq '.items[] | select(.id=="343e4bae3d7680b4872ac0ebf5b4ed4c") | {id, sourceFingerprint, generatedAt, generatorVersion, status}'
- Force one subset regeneration when validating prompt/fingerprint changes:
npm run build:artifacts -- --limit=3 --force
Expected Behavior Summary
- Metadata always re-evaluates each selected pattern and only generates descriptions when needed.
- Components fingerprint controls component artifact refresh.
- Components and descriptions are independent build concerns.
- Runtime description resolution remains metadata-first with search fallback.