Expand description
assets — the db.md asset layer.
Raw binary assets (PDFs, recordings, large exports) belong to a store but
are too heavy for Git. 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.
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
VibeCraft layer’s job, keyed off the SHA-256. This module never shells out
to git and never touches the network.
Four operations — one write, three reads:
scan(write) discover declared assets, hash present files, rewrite the manifestverify(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. - Declaration
- A single
asset:/assets:declaration read from a wrapper’s frontmatter. - 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.
Functions§
- 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). - 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. - write_
manifest - Write the manifest atomically (temp + fsync + rename, via
write_atomic), records sorted by path ascending. An empty record set removes the file.