npm run validate:asset-registry currently proves:
every registered asset is valid
It does not prove:
every exported asset is registered
Those are different completeness properties, and only the first is checked. An export directory under assets/exports/ with no manifest entry passes validation today — confirmed while adding readme-poster-impact-2560x756 in #78, which validated clean before it was registered at all.
This matters because assets/manifest.json declares assets/exports/ as its inventoryScope.includedPaths. The registry presents itself as a scan of that directory, so an unregistered export makes the registry quietly incomplete while reporting success. Same shape as the pairedSpread defect in #75: the surface that exists to establish trust is the one asserting something untrue, and it fails in the direction that looks fine.
Proposed invariant
files under assets/exports/
minus an explicit ignore list
must equal
paths declared in the asset registry
Fail on:
- unregistered export directories
- registered paths that no longer exist (already covered — keep)
- duplicate registrations (already covered — keep)
- exports missing
capture.json or equivalent provenance, where required
Allow a small explicit ignore list for .DS_Store, temporary files, README files, and any intentionally excluded working artifacts.
Registration must not be silently inferred from directory names: an entry is a claim someone made, and inferring it would reintroduce the same gap one level down.
Scope
Narrow and separate on purpose. It is a real integrity gap but should not interrupt the current README asset sequence (poster → GIF → context-gap SVG → architecture SVG).
npm run validate:asset-registrycurrently proves:It does not prove:
Those are different completeness properties, and only the first is checked. An export directory under
assets/exports/with no manifest entry passes validation today — confirmed while addingreadme-poster-impact-2560x756in #78, which validated clean before it was registered at all.This matters because
assets/manifest.jsondeclaresassets/exports/as itsinventoryScope.includedPaths. The registry presents itself as a scan of that directory, so an unregistered export makes the registry quietly incomplete while reporting success. Same shape as thepairedSpreaddefect in #75: the surface that exists to establish trust is the one asserting something untrue, and it fails in the direction that looks fine.Proposed invariant
Fail on:
capture.jsonor equivalent provenance, where requiredAllow a small explicit ignore list for
.DS_Store, temporary files, README files, and any intentionally excluded working artifacts.Registration must not be silently inferred from directory names: an entry is a claim someone made, and inferring it would reintroduce the same gap one level down.
Scope
Narrow and separate on purpose. It is a real integrity gap but should not interrupt the current README asset sequence (poster → GIF → context-gap SVG → architecture SVG).