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

Save and exact replay — open decision register (aligned direction, unsettled details)

Created Updated

The direction is the natural next layer around Crosswalker’s existing primitives, but the generic reproducible-build sketch that produced it must not be implemented verbatim.

QuestionAnswer
Does it conflict with schema-as-primitive?No — provided stored recipes stay canonical and schema-validated
Does it conflict with the closed 5-mechanism grammar?No — provided the binding never gains row-dependent target behavior
Does it conflict with render(Recipe, ConceptIdentity)?No — the binding sits around the pure function, not inside it
Does it conflict with the RecipeDocument preservation boundary?No — it is the natural completion of it. (RecipeDocument is the wrapper that keeps a saved recipe byte-faithful to the original it was derived from, patching rather than rebuilding it.)
Does it conflict with artifact roles and authority?No — provided the new objects stay subtypes, bindings, descriptors, and index state
Can it be implemented as originally sketched?No — eight decisions below are load-bearing and unanswered

Illustration 1 — it is a join, not a chain

Section titled “Illustration 1 — it is a join, not a chain”

The roadmap currently reads source bytes → reusable configuration → output. That is ontologically wrong: source bytes do not produce the recipe. They are independent inputs joined by a binding.

Illustration 2 — five digests, five different questions

Section titled “Illustration 2 — five digests, five different questions”

The single biggest correction. The existing computeRecipeHash() at src/generation/hash.ts is not a recipe-artifact digest, and must not be repurposed as one.

metadata.based_on.hash currently stores the effective target hash of an ancestor. Silently redefining it would break existing ancestry semantics.

Illustration 3 — what is allowed to live where

Section titled “Illustration 3 — what is allowed to live where”

These are this register’s own gates. The sibling primitives reconciliation register (the log tracking proposed upgrades to the core building blocks every imported note is made of) has its own three gates — Gate 1 — schema fields, Gate 2 — cleanup, Gate 3 — language — and its Gate 1 must land before D1 below. Always name the register when citing a gate.

Gate 1 — before the design specification

Section titled “Gate 1 — before the design specification”

Sequencing: D1 must be decided after the primitives reconciliation register’s Gate 1 (schema fields), because adding Tier 1 fields after digests are locked would invalidate stored hashes.

Ratified 2026-09-06 — Gate 1 is closed. The options below are preserved as the record of what was considered; the owner’s answers are:

#Ratified answer
D1(a) a separate recipe_document_digest; every existing hash and ancestry field keeps its current meaning and stored value; sha256-<hex> is the only accepted syntax
D2(a) a closed set of explicit parser, destination, and write-policy override fields; no arbitrary or free-form parameters
D3(a) equivalence of Crosswalker-managed content, excluding run metadata that legitimately changes and user-owned edits. Tightened: byte-identical whole files are neither promised nor implemented as an opt-in check now
D4(c) verified reselection and optional retained copies with explicit per-binding status. Tightened: explicit opt-in is required before any retained copy of a source file is stored, unconditionally; ordinary in-memory parsing is not what this gates. Location, quota, and the mobile path remain separate open questions

Full rationale and non-commitments: Gate 1 ratification. This unblocks the design specification only — nothing below has been implemented, and D5–D8 remain open.

#DecisionOptionsConnects to
D1Hash taxonomy. Add a full canonical recipe digest (a fingerprint identifying the exact recipe revision) without disturbing the existing effective-target hash (which answers only “did output-affecting behavior change?”). Also pick one wire syntax.(a) new recipe_document_digest field, leave recipe.hash alone; (b) rename recipe.hash to effective_target_hash with migration. Syntax: keep sha256-<hex> everywhere, or allow sha256:<hex>v0.1 schema spec · Terminology · Recipe fidelity · spec/tier1.schema.json, spec/recipe.schema.json, src/generation/hash.ts
D2Binding parameter surface. A binding is the record joining a saved recipe to the specific inputs it ran against: which file, which sheet, where output goes, what to do on conflict. A free-form parameter bag would create a hidden sixth mechanism.(a) closed parser/destination/policy union only, no general parameters; (b) additive Recipe Schema change declaring typed parameter slotsTarget-structure synthesis · Hierarchy primitives · ETL and import
D3What “exact replay” promises. Byte-identical whole files are not currently achievable because produced_at, producer version, and user_preserve (the regions of a note the user owns and the tool must never overwrite) all vary.(a) managed-projection equivalence, excluding execution-scoped provenance and user-owned regions; (b) byte-identical only into a clean destinationConventions · Consistency models · src/generation/provenance.ts, src/generation/frontmatter-merge.ts
D4Source retention. A hash verifies bytes; it does not recover them.(a) retain bytes by default in a content-addressed store; (b) verified reselection only; (c) both, with explicit per-binding status. Plus: vault-visible vs plugin-private, quota, license/privacy warningsOntology lifecycle · Acquire · System architecture · v0.1.7 milestone
#DecisionOptionsConnects to
D5Lineage semantics. Today, customizing a recognized recipe forks it to <id>-custom with based_on ancestry. An “active revision pointer” would blur that.(a) storage snapshots only, keep fork semantics; (b) true revision chains per logical recipe; (c) both, explicitly distinguishedRecipe fidelity · Artifact roles · src/import/recipe-document.ts
D6SavedConfig coexistence. SavedConfig is the older “remember my setup” object. Legacy saved setups are fingerprint-bound convenience state, not portable recipes.(a) keep both, no migration; (b) explicit opt-in convert with blocker reporting; (c) deprecate new SavedConfig creationUI lexicon · UI parity audit · v0.1 schema spec
#DecisionOptionsConnects to
D7Audit manifest overlap. Earlier audit research proposed a snapshot manifest.json whose fields now overlap the Execution Record (the record of what one run actually did) plus the Package Manifest (the record of what a distributed bundle contains).(a) retire the audit-specific manifest; (b) keep it as a package_kind: audit-snapshot Package Manifest; (c) keep three contracts (not recommended)Artifact roles · v0.1.8 milestone · Ch 28 deliverable C
D8Signed git: default or opt-in. The v0.1 stack pivot committed to git plus signed commits (a cryptographic guarantee that a change came from a specific, verifiable person) as the audit floor; the current v0.1.8 page makes signing opt-in.(a) restore signed-by-default; (b) keep opt-in and downgrade public language from “audit trail” to “version history”v0.1 stack pivot · v0.1.8 milestone · Tradeoffs
Already decidedWhere
The binding role exists and is not a new artifact familyArtifact roles and authority
Execution Record and Package Manifest stay separate and laterArtifact-role synthesis
RecipeDocument.original is preservation authority; save the patched canonical recipe, never the editor modelRecipe fidelity synthesis
Source paths, URLs, and byte hashes stay out of ImportRecipespec/recipe.schema.json source block
source.version is a compatibility declaration; verified run facts outrank itv0.1 schema spec
Retained bytes stay Tier 0 inputs, never Tier 1 authority or Knowledge SetsSystem architecture
Direct Tier 1 producers stay first-class without any recipe or replay bindingETL and import
Every lifecycle capability needs a UI; config is the escape hatchUI parity audit
MappingSet identity stays independent of parser column mappingArtifact roles and authority
Save and replay is infrastructure for version migration, not the migration loop itselfOntology evolution

These are facts about the current code, not decisions. They become work once Gate 1 closes.

GapWhere
sha256Hex() takes a string; exact source hashing needs a byte-oriented pathsrc/generation/hash.ts
Generation call sites never pass sourceHash, though provenance can emit itsrc/generation/generation-engine.ts, src/generation/provenance.ts
Draft resume reparses the current file with no digest comparisonsrc/import/import-wizard.ts
Drafts persist only the selected sheet; header row, JSON iterator, and filter are droppedsrc/import/draft-store.ts
Destination and write policy live in workflow state, not in any durable bindingsrc/import/draft-store.ts
Mobile storage for retained bytes is unproven and currently scheduled at RCv0.1-RC milestone

The linear acceptance chain appears in three places and should be restated as the join shown in Illustration 1:

  1. Write the Crosswalker-native design specification in .workspace/, with worked examples and acceptance cases.
  2. Implement identity and binding primitives, test-first, no storage or UI.
  3. Add portable storage and the retained-object store, mobile-proven.
  4. Build the library and replay UI.
  5. Prove full NIST CSF 2.0 and NIST SP 800-53 replay.

Small sequential waves, reviewed between each. Not one large fan-out.