Expand description
assets — the db.md asset layer.
Raw assets (PDFs, recordings, large exports — typically binaries too heavy
for Git) belong to a store but live outside the content plane. A content
file (the wrapper) declares one via an asset: / assets: frontmatter
key; this module records each in the root-level assets.jsonl manifest:
store-relative path, SHA-256, size, media type, the declaring wrapper(s),
and whether it is required for byte-completeness.
Any in-store file may be declared — including a markdown content file, whose
bytes are then integrity-tracked here while the content layer keeps parsing,
indexing, and validating it as usual. paths still omits markdown, so an
ignore mechanism fed from it can never hide a content file from the VCS.
The manifest is a pure projection of (wrappers + asset files on disk):
every field is derivable, so a scan where the bytes are present
reproduces it byte-for-byte, exactly like index.jsonl. db.md never
transports the bytes and never names a storage provider; that is the
hosting/transport layer’s job, keyed off the SHA-256. This module never
shells out to git and never touches the network.
Six operations — three writes, three reads:
scan(write) discover declared assets, hash present files, rewrite the manifestrefresh(write) re-hash one declared asset and update its manifest rowrefresh_wrapper(write) reconcile every declaration in one wrapper and update the manifest onceverify(read) prove the local store is byte-complete for required assetsstatus(read) report present / missing without failingpaths(read) the store-relative path list (for an ignore mechanism)
Path safety: every declared path is validated store-relative (no .., no
absolute, no escape) via crate::store::ensure_path_within_store wherever
a path is read or resolved, so a poisoned manifest can never make scan
hash, or a restore write, outside the store.
Structs§
- Asset
Record - One asset record — one line of
assets.jsonl. - Asset
State - One asset’s local state, used by
statusandverify. - Asset
Supersession - A value-free, append-only asset replacement declaration.
- Declaration
- A single
asset:/assets:declaration read from a wrapper’s frontmatter. - Refresh
Report - Result of
refresh. A refresh is the bounded write-through counterpart to the full-storescan: it re-hashes one declared asset without touching unrelated bytes. - Refresh
Wrapper Report - Result of
refresh_wrapper. This is the bounded batch counterpart torefresh: every asset declared by one wrapper is reconciled, while unrelated wrappers and bytes are untouched. - Scan
Report - Result of
scan. - Status
Report - Result of
status. - Verify
Report - Result of
verify.
Constants§
- MANIFEST_
FILE - The manifest file name at the store root.
- SUPERSEDES_
ASSET_ KEY - Frontmatter key used by an append-only wrapper to state that its single declared asset is the portable replacement for an older asset coordinate.
Functions§
- asset_
supersession - Parse the optional append-only asset supersession contract from typed frontmatter. The wrapper must declare exactly one required replacement asset; the older coordinate stays in the manifest as optional evidence.
- asset_
supersession_ from_ yaml_ map - Raw-map equivalent of
asset_supersessionfor the validation sweep. - declarations_
from_ yaml_ map - Read declarations from an already-parsed YAML mapping. Used by
crate::validate, which holds the parsed mapping and need not re-read the file. Equivalent todeclared_assetsbut keyed off a raw map. - declared_
assets - Read all
asset:/assets:declarations from a parsed frontmatter. - normalize_
asset_ path - Normalize a declared asset path to a CANONICAL store-relative forward-slash
string, rejecting absolute paths and any
../ root component. This is the lexical guard;crate::store::ensure_path_within_storeis the resolved-path guard applied before any disk read. - paths
- The cataloged asset paths, sorted ascending. The VCS-neutral list a harness
feeds into a
.gitignoremanaged block or a sync-service exclude. db.md itself never writes any ignore file. - read_
manifest - Read
assets.jsonlinto records, deduped by path (last line wins) and sorted by path ascending. A missing manifest is an empty store, not an error. A malformed line is anInvalidDataerror (the CLI surfaces it;crate::validateflags it leniently asASSET_MANIFEST_MALFORMED). - refresh
- Re-hash one asset and write just its canonical manifest record.
- refresh_
wrapper - Reconcile every asset declaration in one wrapper and write the canonical
manifest once. This is for bounded generators that own one wrapper with a
changing set of assets: it avoids a full-store
scanand avoids N manifest rewrites through repeatedrefreshcalls. - scan
- Walk every content file, read its
asset/assetsdeclarations, hash the present files, and (re)write the manifest. The manifest is a projection: a path no longer declared by any wrapper drops out. Bytes absent locally but previously cataloged are preserved (the eviction / disk-relief case) since they cannot be re-hashed.dry_runcomputes without writing;untrackedadditionally reports non-markdown files undersources/that no wrapper declares. Never writes when nothing changed (keeps the Git diff and the--dry-run-then-scan idempotent). - status
- Report which cataloged assets are present locally and how many bytes remain
to restore. Never fails on a missing asset (that is
verify’s job); it does fail on a malformed manifest. - verify
- Check that every required asset (plus optional, under
include_optional) is present locally and matches the manifest.quick= presence + size only (fast); otherwise a full SHA-256 re-hash. This is a SWEEP (O(asset bytes) in deep mode), never a loop op.completeis true iff nothing is missing or corrupt in the considered set. - verify_
projection - Verify the byte completeness of an intentionally partial projection.
Exact listed paths may be absent and are reported as
projected_missing; if a listed path is present it is still hashed and any corruption blocks. Unlisted missing assets and every corrupt asset remain blocking. - write_
manifest - Write the manifest atomically (temp + fsync + rename through the store’s held root capability), records sorted by path ascending. An empty record set removes the file.