0.91.0 → 0.92.0 — $seed overlays and the !fill → !must_fill rename¶
Two changes land together in 0.92.0:
- Additive: a new system-metadata key,
$seed, lets a document carry the curated starting values that newly-added cards spawn with. - Breaking (authored documents): the placeholder YAML tag
!fillis renamed to!must_fill. There is no alias — a document still written with!fillparses but loses its placeholder status (see below).
Stored documents (the JSON storage DTO) written by 0.82.x–0.91.x keep
loading losslessly; the break is only in Markdown source that uses the old
!fill tag.
What $seed is¶
$seed is a $-prefixed system key on the root block only — like $quill,
a composable card carrying $seed is rejected at parse and on storage load. It
is a mapping keyed by composable card-kind; each entry is a sparse overlay —
the user fields (plus an optional reserved $body string) a freshly-added card
of that kind should start with:
~~~
$quill: usaf_memo@0.2.0
$kind: main
$seed:
indorsement:
from: 49 FW/CC
signature_block:
- "JANE A. DOE, Col, USAF"
- "Commander"
~~~
Adding a new indorsement now seeds from / signature_block from the overlay
while every untouched field still flows from the quill's schema example:
(overlay › example › absent). Like $ext, $seed round-trips through Markdown
and storage and is stripped before backends — it never appears in rendered
output. It is validated only advisorily (Quill::validate, warning severity)
and never gates render. The model lives in the prose/canon/CARDS.md design doc.
seedCard takes an optional overlay¶
seedCard now accepts the per-kind overlay so a card added to a
template-derived document inherits its curated values. Read the overlay from the
document and hand it to the quill:
WASM / TypeScript
// before
const card = quill.seedCard(kind);
// after — pass the document's overlay (a read; it does not mutate the doc)
const card = quill.seedCard(kind, doc.main.seed?.[kind]);
quill.seedCard(kind) (omitting the overlay) still works and yields the bare
schema seed, so unmodified call sites compile and behave as before.
Python
overlay = (doc.main["seed"] or {}).get(kind) # None for the bare schema seed
card = quill.seed_card(kind, overlay) # overlay defaults to None
Rust (core) — the one breaking signature: Quill::seed_card(&self, kind)
becomes Quill::seed_card(&self, kind, overlay: Option<&SeedOverlay>). Pass
None for the bare schema seed (the historical behavior), or layer a document's
overlay by reading it off the main card's $seed map:
doc.main().seed().and_then(|m| m.get(kind)).and_then(SeedOverlay::from_json).
Making the overlay an explicit argument keeps it discoverable.
New accessors¶
- The per-kind overlay is read off the main card's
seedmap —doc.main.seed?.[cardKind](WASM) /doc.main["seed"][cardKind](Python) /doc.main().seed()(Rust, thenSeedOverlay::from_json); feed it straight toseedCard. There is no dedicatedDocument.seedaccessor —$seedis read through the card, exactly like$ext. Document.setSeedNamespace(cardKind, overlay)/removeSeedNamespace(cardKind)— write/clear one kind's overlay, preserving sibling kinds (the seed analogue ofsetExtNamespace). This is how a template author sets the values new cards spawn with.
The Card shape gains an optional seed field (hoisted from $seed, main card
only), mirroring ext.
!fill → !must_fill (breaking)¶
The placeholder tag that marks a field as a must-fill blank is renamed from
!fill to !must_fill — more self-documenting (it conveys obligation) and
aligned with the ⟨⟨…⟩⟩ blueprint sentinel.
~~~ ~~~
$quill: usaf_memo@0.2.0 $quill: usaf_memo@0.2.0
$kind: main $kind: main
subject: !fill → subject: !must_fill
~~~ ~~~
There is no !fill alias. !must_fill is the only recognized fill tag;
every other custom tag — including a now-stale !fill — is treated as a
noncanonical tag: it is dropped with a parse::unsupported_yaml_tag warning,
the scalar value is kept, but the field is no longer marked as a placeholder.
The document still parses, so this is a silent loss of placeholder status (a
warning, not an error). Action: search your Markdown sources and quills for
!fill and rewrite to !must_fill. (rg -l '!fill\b' finds them.)
This release also makes nested placeholders durable: a !must_fill marker on a
value inside a field (an object leaf, a key in an array element) now survives a
storage round-trip via the new per-field nested_fills list in the storage DTO.
Storage: schema quillmark/document@0.92.0¶
The StoredDocument wire format gains a seed payload-item variant and a
per-field nested_fills list (carrying the paths of nested !must_fill
markers), so newly serialized documents carry the tag
quillmark/document@0.92.0. This is transparent: 0.81.x / 0.82.x–0.91.x
blobs migrate forward losslessly on read (V0_81_0 → V0_82_0 → V0_92_0, with
seed absent and nested_fills empty), and re-serialization upgrades the tag.
No action is required for persisted documents.