Skip to content
🚧 Early alpha — building the foundation. See the roadmap →

Recipe library: Gate 2 settled (D5 fork lineage, D6 saved setups kept)

Created Updated
#DecisionSettledWhy in one line
D5Lineage: what happens when you save an edited recipe(a) Snapshots plus fork. Saving creates a new recipe carrying metadata.based_on (the record of which recipe, and which revision of it, this one started from). A recipe you saved yourself may also be replaced in place, behind a confirm, with the old file sent to the trash. A built-in recipe is never replacedAdditive, and adds no new artifact noun
D6Coexistence with the older saved setups(a) for v0.1.7: keep both, no migration. Saved setups keep working exactly as before; recipes are the portable, shareable artifact. The opt-in converter (b) stays a tracked follow-upNothing a user already relies on changes

D5, fork rather than revision chains. Revision chains would introduce a “logical recipe” with an active-revision pointer: a new identity, a new lifecycle and a new place for drift, with no user need behind it yet. That fails the artifact-roles discipline (a new noun needs independent identity, lifecycle, authority and consumers). Fork semantics already existed (customizing a recognized recipe stamps based_on), so the library reuses the one lineage field instead of inventing a second. Replace-in-place covers the common “I fixed my own recipe” case without a chain, and only for recipes the user owns. If chains are ever needed, they can be layered on top of based_on additively. The review queue’s suggestion to group forks by ancestry in the library so they read as versions is not in this slice: each card shows its “Based on” line, and grouping waits until real libraries show the ten-forks pain the queue predicted.

D6, keep both. A saved setup is matched to a source by fingerprint and lives in plugin settings; it is convenience state, not a portable recipe. Converting them would have to guess intent for setups that do not translate losslessly, and the project’s chosen-never-guessed rule forbids guessing. The review queue recommended (b), an explicit opt-in converter that reports what cannot carry across, and deprecating new saved setups only after it ships. That sequencing is kept: (a) now is the first step of it, not a rejection of it. The converter is real UI work with its own test surface, so it is tracked as an additive follow-up rather than bundled into the library slice, and saved-setup creation is not deprecated.

CallRulingWhy
Where saved recipes liveOne .json file per recipe in _crosswalker/import-recipes/, each file exactly a schema-valid import recipe (no wrapper). The recipe field is the identity; the file name is a readable label and is never read for meaningA plain file is the escape hatch and the sharing unit. A sibling folder keeps the query-recipe loader, which reads _crosswalker/recipes/, from ever seeing import recipes. Identity follows the identity, never path rule (first-run log). This replaces the _crosswalker/recipes/import/ path the milestone page originally sketched
Public termRecipe in the UI (“Save as recipe”, “Browse import recipes”); ImportRecipe stays the machine-contract nameShort, already used in the wizard’s recognized-source card, and it reads in any domain

The v0.1.7 milestone Track 1 library slice: save from the wizard, a library match offered (never preselected) on Step 1, a browse/inspect/export/import/duplicate/rename/delete browser, and a settings entry. Delivery detail lives in CHANGELOG.md — Unreleased.

Still open after this page: Track 2 run binding, “Run again” and source-drift status, the D4 opt-in source copy, and the full NIST CSF 2.0 and SP 800-53 replay proofs. Gate 3 (D7, D8) lands at v0.1.8.