From ea6fd5c7bbb1434a920cb94eb0dcb2cf494f3845 Mon Sep 17 00:00:00 2001 From: "Claude (Emil)" Date: Fri, 9 Oct 2026 17:38:43 +0000 Subject: [PATCH 1/2] Re-lay out the fixtures under ns//; the re-founding note MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Issue #152 (PRD issue 9, §3.11; rulings 63 and 68). The fifteen committed fixture stores under `ledger-cli/tests/fixtures/` move their `sets/` and `log/` under `.decisions/ns//` with `git mv` — `fixture.ledger` for the twelve class fixtures and `pass`, `fixture.coverage`, `fixture.forked`, `fixture.two-clocks` for the rest — no file's content changed, and `UPDATE_FIXTURES=1 cargo test -p ledger-cli --test gate` finds nothing to refresh (checked: no fixture file modified). The staging shim issue 1 left in the test helpers goes: `stage_fixture`, `stage_fixture_into`, `stage_workspace` and the flat branch of `stage_store_into` become plain copies (`fixture_copy`, `copy_fixture_into`, `workspace_copy`, `copy_store_into`), and the flat fallbacks in `gate.rs`'s and `digests.rs`'s fixture walkers go. `legacy_layout.rs` lays the `pass` fixture flat itself, byte for byte, to build its v1.8 history; `scalars.rs` reads the fixture's set from its namespace directory. The tests of §3.11: item 1 (flat paths) was done by issue 1, with the shim removed here; item 2 (meaning changed under rulings 47 and 68) by issues 5, 6 and 8; item 3 (the flat era in history) by issue 2; item 4 (D6 by landing) is issue 12's. A grep over the test sources finds no flat path left. Protocol: the Appendix C note "Namespaces become independent; a store with shared authority is re-founded" lands as the PRD drafted it, headed with no format number (no format bump here; the draft said "and format 8"); the v1.9 note's two sentences that pointed at this issue now point at the note and at the fixtures; Appendix B row. No class added; no digest moves. Stacked on #162 (issue 8). Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01GgRcHXmnAu43hChNxhnqxU --- ledger-cli/tests/common/mod.rs | 90 +++++-------------- ledger-cli/tests/digests.rs | 12 +-- ledger-cli/tests/export.rs | 2 +- ledger-cli/tests/export_verifier.rs | 8 +- .../log/01KZPMA8HF297MMN8232TM4FCE.yml | 0 .../log/01KZPMA8J24KD92JZQTDC6Y6B4.yml | 0 .../log/01KZPMA8JPQSTRM3X8E7R0S1KA.yml | 0 .../log/01KZPMA8KCK8XJWJTB98QBFZ27.yml | 0 .../log/01KZPMA8M3D597TGJJ8W2NA04B.yml | 0 .../log/01KZPMA8MXG2CAYGBS3X827NAY.yml | 0 .../log/01KZPMA8NTBFYDABGM1ZHFC4SG.yml | 0 .../log/01KZPMA8PSTE42V7GE8H747PG7.yml | 0 .../log/01KZPMA8QWE8B74CGR8M5RC1MX.yml | 0 .../log/01KZPMA8S0K9SNDXXK4NS2ZWFA.yml | 0 .../log/01KZPMA8T68ZYVCJZXG9Z07FYW.yml | 0 .../log/01KZPMA8VERG1CGNA3JWWADRF1.yml | 0 .../log/01KZPMA8WVA4P7GEDV915Y5GG8.yml | 0 .../log/01KZPMA8YA7J3H1HQT79599BDJ.yml | 0 .../log/01KZPMA8ZWBD1ADF7GP27HGH6S.yml | 0 .../sets/coverage-fixture.yml | 0 .../log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml | 0 .../log/01K2C4YQJ3F8M0PT5W7NZ9RDY0.yml | 0 .../log/01K2C4YQJ3F8M0PT5W7NZ9RDY1.yml | 0 .../{ => ns/fixture.forked}/sets/forked.yml | 0 .../log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml | 0 .../fixture.ledger}/sets/ledger-fixture.yml | 0 .../log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml | 0 .../fixture.ledger}/sets/ledger-fixture.yml | 0 .../log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml | 0 .../fixture.ledger}/sets/ledger-fixture.yml | 0 .../log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml | 0 .../fixture.ledger}/sets/ledger-fixture.yml | 0 .../log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml | 0 .../fixture.ledger}/sets/ledger-fixture.yml | 0 .../log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml | 0 .../fixture.ledger}/sets/ledger-fixture.yml | 0 .../log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml | 0 .../fixture.ledger}/sets/ledger-fixture.yml | 0 .../log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml | 0 .../fixture.ledger}/sets/ledger-fixture.yml | 0 .../log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml | 0 .../fixture.ledger}/sets/ledger-fixture.yml | 0 .../log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml | 0 .../fixture.ledger}/sets/ledger-fixture.yml | 0 .../log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml | 0 .../fixture.ledger}/sets/ledger-fixture.yml | 0 .../log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml | 0 .../fixture.ledger}/sets/ledger-fixture.yml | 0 .../log/01K2000000000000000000000A.yml | 0 .../log/01K2ZZZZZZZZZZZZZZZZZZZZZZ.yml | 0 .../fixture.two-clocks}/sets/two-clocks.yml | 0 ledger-cli/tests/format_history.rs | 2 +- ledger-cli/tests/gate.rs | 21 ++--- ledger-cli/tests/graph.rs | 12 +-- ledger-cli/tests/landed_header.rs | 2 +- ledger-cli/tests/legacy_layout.rs | 4 +- ledger-cli/tests/revisit_format.rs | 2 +- ledger-cli/tests/scalars.rs | 2 +- ledger/spec/ledger-protocol.md | 58 ++++++++++-- 59 files changed, 105 insertions(+), 110 deletions(-) rename ledger-cli/tests/fixtures/coverage/.decisions/{ => ns/fixture.coverage}/log/01KZPMA8HF297MMN8232TM4FCE.yml (100%) rename ledger-cli/tests/fixtures/coverage/.decisions/{ => ns/fixture.coverage}/log/01KZPMA8J24KD92JZQTDC6Y6B4.yml (100%) rename ledger-cli/tests/fixtures/coverage/.decisions/{ => ns/fixture.coverage}/log/01KZPMA8JPQSTRM3X8E7R0S1KA.yml (100%) rename ledger-cli/tests/fixtures/coverage/.decisions/{ => ns/fixture.coverage}/log/01KZPMA8KCK8XJWJTB98QBFZ27.yml (100%) rename ledger-cli/tests/fixtures/coverage/.decisions/{ => ns/fixture.coverage}/log/01KZPMA8M3D597TGJJ8W2NA04B.yml (100%) rename ledger-cli/tests/fixtures/coverage/.decisions/{ => ns/fixture.coverage}/log/01KZPMA8MXG2CAYGBS3X827NAY.yml (100%) rename ledger-cli/tests/fixtures/coverage/.decisions/{ => ns/fixture.coverage}/log/01KZPMA8NTBFYDABGM1ZHFC4SG.yml (100%) rename ledger-cli/tests/fixtures/coverage/.decisions/{ => ns/fixture.coverage}/log/01KZPMA8PSTE42V7GE8H747PG7.yml (100%) rename ledger-cli/tests/fixtures/coverage/.decisions/{ => ns/fixture.coverage}/log/01KZPMA8QWE8B74CGR8M5RC1MX.yml (100%) rename ledger-cli/tests/fixtures/coverage/.decisions/{ => ns/fixture.coverage}/log/01KZPMA8S0K9SNDXXK4NS2ZWFA.yml (100%) rename ledger-cli/tests/fixtures/coverage/.decisions/{ => ns/fixture.coverage}/log/01KZPMA8T68ZYVCJZXG9Z07FYW.yml (100%) rename ledger-cli/tests/fixtures/coverage/.decisions/{ => ns/fixture.coverage}/log/01KZPMA8VERG1CGNA3JWWADRF1.yml (100%) rename ledger-cli/tests/fixtures/coverage/.decisions/{ => ns/fixture.coverage}/log/01KZPMA8WVA4P7GEDV915Y5GG8.yml (100%) rename ledger-cli/tests/fixtures/coverage/.decisions/{ => ns/fixture.coverage}/log/01KZPMA8YA7J3H1HQT79599BDJ.yml (100%) rename ledger-cli/tests/fixtures/coverage/.decisions/{ => ns/fixture.coverage}/log/01KZPMA8ZWBD1ADF7GP27HGH6S.yml (100%) rename ledger-cli/tests/fixtures/coverage/.decisions/{ => ns/fixture.coverage}/sets/coverage-fixture.yml (100%) rename ledger-cli/tests/fixtures/forked/.decisions/{ => ns/fixture.forked}/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml (100%) rename ledger-cli/tests/fixtures/forked/.decisions/{ => ns/fixture.forked}/log/01K2C4YQJ3F8M0PT5W7NZ9RDY0.yml (100%) rename ledger-cli/tests/fixtures/forked/.decisions/{ => ns/fixture.forked}/log/01K2C4YQJ3F8M0PT5W7NZ9RDY1.yml (100%) rename ledger-cli/tests/fixtures/forked/.decisions/{ => ns/fixture.forked}/sets/forked.yml (100%) rename ledger-cli/tests/fixtures/l001/.decisions/{ => ns/fixture.ledger}/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml (100%) rename ledger-cli/tests/fixtures/l001/.decisions/{ => ns/fixture.ledger}/sets/ledger-fixture.yml (100%) rename ledger-cli/tests/fixtures/l002/.decisions/{ => ns/fixture.ledger}/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml (100%) rename ledger-cli/tests/fixtures/l002/.decisions/{ => ns/fixture.ledger}/sets/ledger-fixture.yml (100%) rename ledger-cli/tests/fixtures/l003/.decisions/{ => ns/fixture.ledger}/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml (100%) rename ledger-cli/tests/fixtures/l003/.decisions/{ => ns/fixture.ledger}/sets/ledger-fixture.yml (100%) rename ledger-cli/tests/fixtures/l004/.decisions/{ => ns/fixture.ledger}/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml (100%) rename ledger-cli/tests/fixtures/l004/.decisions/{ => ns/fixture.ledger}/sets/ledger-fixture.yml (100%) rename ledger-cli/tests/fixtures/l005/.decisions/{ => ns/fixture.ledger}/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml (100%) rename ledger-cli/tests/fixtures/l005/.decisions/{ => ns/fixture.ledger}/sets/ledger-fixture.yml (100%) rename ledger-cli/tests/fixtures/l006/.decisions/{ => ns/fixture.ledger}/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml (100%) rename ledger-cli/tests/fixtures/l006/.decisions/{ => ns/fixture.ledger}/sets/ledger-fixture.yml (100%) rename ledger-cli/tests/fixtures/l007/.decisions/{ => ns/fixture.ledger}/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml (100%) rename ledger-cli/tests/fixtures/l007/.decisions/{ => ns/fixture.ledger}/sets/ledger-fixture.yml (100%) rename ledger-cli/tests/fixtures/l008/.decisions/{ => ns/fixture.ledger}/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml (100%) rename ledger-cli/tests/fixtures/l008/.decisions/{ => ns/fixture.ledger}/sets/ledger-fixture.yml (100%) rename ledger-cli/tests/fixtures/l010/.decisions/{ => ns/fixture.ledger}/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml (100%) rename ledger-cli/tests/fixtures/l010/.decisions/{ => ns/fixture.ledger}/sets/ledger-fixture.yml (100%) rename ledger-cli/tests/fixtures/l013/.decisions/{ => ns/fixture.ledger}/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml (100%) rename ledger-cli/tests/fixtures/l013/.decisions/{ => ns/fixture.ledger}/sets/ledger-fixture.yml (100%) rename ledger-cli/tests/fixtures/l014/.decisions/{ => ns/fixture.ledger}/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml (100%) rename ledger-cli/tests/fixtures/l014/.decisions/{ => ns/fixture.ledger}/sets/ledger-fixture.yml (100%) rename ledger-cli/tests/fixtures/pass/.decisions/{ => ns/fixture.ledger}/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml (100%) rename ledger-cli/tests/fixtures/pass/.decisions/{ => ns/fixture.ledger}/sets/ledger-fixture.yml (100%) rename ledger-cli/tests/fixtures/two-clocks/.decisions/{ => ns/fixture.two-clocks}/log/01K2000000000000000000000A.yml (100%) rename ledger-cli/tests/fixtures/two-clocks/.decisions/{ => ns/fixture.two-clocks}/log/01K2ZZZZZZZZZZZZZZZZZZZZZZ.yml (100%) rename ledger-cli/tests/fixtures/two-clocks/.decisions/{ => ns/fixture.two-clocks}/sets/two-clocks.yml (100%) diff --git a/ledger-cli/tests/common/mod.rs b/ledger-cli/tests/common/mod.rs index f4f54a1a..d227c3e4 100644 --- a/ledger-cli/tests/common/mod.rs +++ b/ledger-cli/tests/common/mod.rs @@ -314,87 +314,43 @@ pub fn both(out: &Output) -> String { format!("{}{}", String::from_utf8_lossy(&out.stdout), String::from_utf8_lossy(&out.stderr)) } -/// A scratch copy of a committed fixture store, laid out under -/// `.decisions/ns//` (LP-3.34). The fixtures under -/// `tests/fixtures/` are still in the flat layout until issue 9 re-lays -/// them out; until then this stages each one the way the loader reads. -pub fn stage_fixture(name: &str) -> tempfile::TempDir { +/// A scratch copy of a committed fixture store under `tests/fixtures/`, +/// laid out as the loader reads it, `.decisions/ns//` (LP-3.34). +pub fn fixture_copy(name: &str) -> tempfile::TempDir { let dir = tempfile::tempdir().expect("tempdir"); - stage_fixture_into(name, dir.path()); + copy_fixture_into(name, dir.path()); dir } -/// Stage the fixture `name` into `root`'s store; returns its one namespace. -pub fn stage_fixture_into(name: &str, root: &Path) -> String { +/// Copy the fixture `name` into `root`'s store, byte for byte; returns its +/// one namespace. +pub fn copy_fixture_into(name: &str, root: &Path) -> String { let from = Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/fixtures").join(name).join(".decisions"); - let namespaces = stage_store_into(&from, root); + let namespaces = copy_store_into(&from, root); assert_eq!(namespaces.len(), 1, "a fixture holds one namespace: {namespaces:?}"); namespaces.into_iter().next().expect("one namespace") } -/// A scratch copy of this repository's own store, staged the same way: the -/// store is flat until issue 10 re-lays it out, and the loader reads only -/// `ns//`. -pub fn stage_workspace() -> tempfile::TempDir { +/// A scratch copy of this repository's own store. +pub fn workspace_copy() -> tempfile::TempDir { let dir = tempfile::tempdir().expect("tempdir"); let from = Path::new(env!("CARGO_MANIFEST_DIR")).join("..").join(".decisions"); - stage_store_into(&from, dir.path()); + copy_store_into(&from, dir.path()); dir } -/// Stage the store at `from` (a `.decisions/` directory, flat or per -/// namespace) into `root`'s store under `ns//`: a change-set -/// goes to the namespace its decisions name, a set to the namespace whose -/// versions name it. Bytes are copied, never rewritten. Returns the -/// namespaces staged. -pub fn stage_store_into(from: &Path, root: &Path) -> Vec { - if from.join("ns").is_dir() { - let mut out = Vec::new(); - for ns in std::fs::read_dir(from.join("ns")).expect("ns").flatten().filter(|e| e.path().is_dir()) { - let name = ns.file_name().to_string_lossy().into_owned(); - copy_tree(&ns.path(), &ledger_core::layout::namespace_dir(root, &name)); - out.push(name); - } - out.sort(); - return out; - } - let mut namespaces: std::collections::BTreeSet = std::collections::BTreeSet::new(); - let mut set_homes: std::collections::BTreeMap = std::collections::BTreeMap::new(); - let mut logs: Vec<(std::path::PathBuf, String)> = Vec::new(); - for entry in std::fs::read_dir(from.join("log")).into_iter().flatten().flatten() { - let text = std::fs::read_to_string(entry.path()).expect("read"); - let cs: ledger_core::changeset::ChangeSet = serde_yaml::from_str(&text).expect("a change-set"); - let ns = cs - .decisions - .iter() - .map(|d| d.id.namespace().to_string()) - .chain(cs.versions.iter().map(|v| v.decision.namespace().to_string())) - .chain(cs.acceptances.iter().map(|a| a.decision.namespace().to_string())) - .next() - .unwrap_or_else(|| panic!("{} names no namespace", entry.path().display())); - for v in &cs.versions { - set_homes.entry(v.set.clone()).or_insert_with(|| ns.clone()); - } - namespaces.insert(ns.clone()); - logs.push((entry.path(), ns)); - } - for (path, ns) in logs { - let target = ledger_core::layout::log_dir(root, &ns); - std::fs::create_dir_all(&target).expect("mkdir"); - std::fs::copy(&path, target.join(path.file_name().expect("name"))).expect("copy"); - } - for entry in std::fs::read_dir(from.join("sets")).into_iter().flatten().flatten() { - let stem = entry.path().file_stem().expect("stem").to_string_lossy().into_owned(); - let ns = set_homes - .get(&stem) - .cloned() - .or_else(|| (namespaces.len() == 1).then(|| namespaces.iter().next().cloned()).flatten()) - .unwrap_or_else(|| panic!("set `{stem}` is named by no version, and the store speaks several namespaces")); - let target = ledger_core::layout::sets_dir(root, &ns); - std::fs::create_dir_all(&target).expect("mkdir"); - std::fs::copy(entry.path(), target.join(entry.file_name())).expect("copy"); - } - namespaces.into_iter().collect() +/// Copy the store at `from` (a `.decisions/` directory) into `root`'s +/// store, namespace by namespace. Bytes are copied, never rewritten. +/// Returns the namespaces copied, sorted. +pub fn copy_store_into(from: &Path, root: &Path) -> Vec { + let mut out = Vec::new(); + for ns in std::fs::read_dir(from.join("ns")).expect("a store under ns/").flatten().filter(|e| e.path().is_dir()) { + let name = ns.file_name().to_string_lossy().into_owned(); + copy_tree(&ns.path(), &ledger_core::layout::namespace_dir(root, &name)); + out.push(name); + } + out.sort(); + out } fn copy_tree(from: &Path, to: &Path) { diff --git a/ledger-cli/tests/digests.rs b/ledger-cli/tests/digests.rs index ede2cd6a..6371c031 100644 --- a/ledger-cli/tests/digests.rs +++ b/ledger-cli/tests/digests.rs @@ -19,19 +19,13 @@ fn workspace() -> PathBuf { Path::new(env!("CARGO_MANIFEST_DIR")).join("..") } -/// Every log directory of a store: `.decisions/ns//log` (LP-3.34), or -/// the flat `.decisions/log` of a store not yet re-laid out. +/// Every log directory of a store: `.decisions/ns//log` (LP-3.34). fn log_dirs_of(root: &Path) -> Vec { - let mut out: Vec = ledger_core::layout::namespaces(root) + ledger_core::layout::namespaces(root) .into_iter() .map(|ns| ledger_core::layout::log_dir(root, &ns)) .filter(|d| d.is_dir()) - .collect(); - let flat = root.join(".decisions/log"); - if flat.is_dir() { - out.push(flat); - } - out + .collect() } fn log_dirs() -> Vec { diff --git a/ledger-cli/tests/export.rs b/ledger-cli/tests/export.rs index 71117a2c..c9c9fd55 100644 --- a/ledger-cli/tests/export.rs +++ b/ledger-cli/tests/export.rs @@ -28,7 +28,7 @@ fn text(out: &Output) -> String { /// A scratch copy of the conformant fixture, so tests can write exports. fn scratch() -> tempfile::TempDir { - common::stage_fixture("pass") + common::fixture_copy("pass") } fn namespace_of_fixture(dir: &Path) -> String { diff --git a/ledger-cli/tests/export_verifier.rs b/ledger-cli/tests/export_verifier.rs index acfb521a..99d7c408 100644 --- a/ledger-cli/tests/export_verifier.rs +++ b/ledger-cli/tests/export_verifier.rs @@ -73,11 +73,11 @@ fn bytes_rebuilt_from_the_export_equal_the_signed_bytes_over_every_fixture() { let fixtures = std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/fixtures"); let mut names: Vec = std::fs::read_dir(&fixtures).expect("fixtures").flatten().map(|e| e.file_name().to_string_lossy().into_owned()).collect(); names.sort(); - // Each fixture staged under `ns//`, the signed store, and - // this repository's own store: 91 acceptances signed by nobody yet, + // Each fixture, the signed store, and this repository's own store: 91 + // acceptances signed by nobody yet, // whose bytes the export must still rebuild exactly. - let mut staged: Vec = names.iter().map(|n| common::stage_fixture(n)).collect(); - staged.push(common::stage_workspace()); + let mut staged: Vec = names.iter().map(|n| common::fixture_copy(n)).collect(); + staged.push(common::workspace_copy()); let mut roots: Vec = staged.iter().map(|d| d.path().to_path_buf()).collect(); roots.push(signed.path().to_path_buf()); let mut checked = 0; diff --git a/ledger-cli/tests/fixtures/coverage/.decisions/log/01KZPMA8HF297MMN8232TM4FCE.yml b/ledger-cli/tests/fixtures/coverage/.decisions/ns/fixture.coverage/log/01KZPMA8HF297MMN8232TM4FCE.yml similarity index 100% rename from ledger-cli/tests/fixtures/coverage/.decisions/log/01KZPMA8HF297MMN8232TM4FCE.yml rename to ledger-cli/tests/fixtures/coverage/.decisions/ns/fixture.coverage/log/01KZPMA8HF297MMN8232TM4FCE.yml diff --git a/ledger-cli/tests/fixtures/coverage/.decisions/log/01KZPMA8J24KD92JZQTDC6Y6B4.yml b/ledger-cli/tests/fixtures/coverage/.decisions/ns/fixture.coverage/log/01KZPMA8J24KD92JZQTDC6Y6B4.yml similarity index 100% rename from ledger-cli/tests/fixtures/coverage/.decisions/log/01KZPMA8J24KD92JZQTDC6Y6B4.yml rename to ledger-cli/tests/fixtures/coverage/.decisions/ns/fixture.coverage/log/01KZPMA8J24KD92JZQTDC6Y6B4.yml diff --git a/ledger-cli/tests/fixtures/coverage/.decisions/log/01KZPMA8JPQSTRM3X8E7R0S1KA.yml b/ledger-cli/tests/fixtures/coverage/.decisions/ns/fixture.coverage/log/01KZPMA8JPQSTRM3X8E7R0S1KA.yml similarity index 100% rename from ledger-cli/tests/fixtures/coverage/.decisions/log/01KZPMA8JPQSTRM3X8E7R0S1KA.yml rename to ledger-cli/tests/fixtures/coverage/.decisions/ns/fixture.coverage/log/01KZPMA8JPQSTRM3X8E7R0S1KA.yml diff --git a/ledger-cli/tests/fixtures/coverage/.decisions/log/01KZPMA8KCK8XJWJTB98QBFZ27.yml b/ledger-cli/tests/fixtures/coverage/.decisions/ns/fixture.coverage/log/01KZPMA8KCK8XJWJTB98QBFZ27.yml similarity index 100% rename from ledger-cli/tests/fixtures/coverage/.decisions/log/01KZPMA8KCK8XJWJTB98QBFZ27.yml rename to ledger-cli/tests/fixtures/coverage/.decisions/ns/fixture.coverage/log/01KZPMA8KCK8XJWJTB98QBFZ27.yml diff --git a/ledger-cli/tests/fixtures/coverage/.decisions/log/01KZPMA8M3D597TGJJ8W2NA04B.yml b/ledger-cli/tests/fixtures/coverage/.decisions/ns/fixture.coverage/log/01KZPMA8M3D597TGJJ8W2NA04B.yml similarity index 100% rename from ledger-cli/tests/fixtures/coverage/.decisions/log/01KZPMA8M3D597TGJJ8W2NA04B.yml rename to ledger-cli/tests/fixtures/coverage/.decisions/ns/fixture.coverage/log/01KZPMA8M3D597TGJJ8W2NA04B.yml diff --git a/ledger-cli/tests/fixtures/coverage/.decisions/log/01KZPMA8MXG2CAYGBS3X827NAY.yml b/ledger-cli/tests/fixtures/coverage/.decisions/ns/fixture.coverage/log/01KZPMA8MXG2CAYGBS3X827NAY.yml similarity index 100% rename from ledger-cli/tests/fixtures/coverage/.decisions/log/01KZPMA8MXG2CAYGBS3X827NAY.yml rename to ledger-cli/tests/fixtures/coverage/.decisions/ns/fixture.coverage/log/01KZPMA8MXG2CAYGBS3X827NAY.yml diff --git a/ledger-cli/tests/fixtures/coverage/.decisions/log/01KZPMA8NTBFYDABGM1ZHFC4SG.yml b/ledger-cli/tests/fixtures/coverage/.decisions/ns/fixture.coverage/log/01KZPMA8NTBFYDABGM1ZHFC4SG.yml similarity index 100% rename from ledger-cli/tests/fixtures/coverage/.decisions/log/01KZPMA8NTBFYDABGM1ZHFC4SG.yml rename to ledger-cli/tests/fixtures/coverage/.decisions/ns/fixture.coverage/log/01KZPMA8NTBFYDABGM1ZHFC4SG.yml diff --git a/ledger-cli/tests/fixtures/coverage/.decisions/log/01KZPMA8PSTE42V7GE8H747PG7.yml b/ledger-cli/tests/fixtures/coverage/.decisions/ns/fixture.coverage/log/01KZPMA8PSTE42V7GE8H747PG7.yml similarity index 100% rename from ledger-cli/tests/fixtures/coverage/.decisions/log/01KZPMA8PSTE42V7GE8H747PG7.yml rename to ledger-cli/tests/fixtures/coverage/.decisions/ns/fixture.coverage/log/01KZPMA8PSTE42V7GE8H747PG7.yml diff --git a/ledger-cli/tests/fixtures/coverage/.decisions/log/01KZPMA8QWE8B74CGR8M5RC1MX.yml b/ledger-cli/tests/fixtures/coverage/.decisions/ns/fixture.coverage/log/01KZPMA8QWE8B74CGR8M5RC1MX.yml similarity index 100% rename from ledger-cli/tests/fixtures/coverage/.decisions/log/01KZPMA8QWE8B74CGR8M5RC1MX.yml rename to ledger-cli/tests/fixtures/coverage/.decisions/ns/fixture.coverage/log/01KZPMA8QWE8B74CGR8M5RC1MX.yml diff --git a/ledger-cli/tests/fixtures/coverage/.decisions/log/01KZPMA8S0K9SNDXXK4NS2ZWFA.yml b/ledger-cli/tests/fixtures/coverage/.decisions/ns/fixture.coverage/log/01KZPMA8S0K9SNDXXK4NS2ZWFA.yml similarity index 100% rename from ledger-cli/tests/fixtures/coverage/.decisions/log/01KZPMA8S0K9SNDXXK4NS2ZWFA.yml rename to ledger-cli/tests/fixtures/coverage/.decisions/ns/fixture.coverage/log/01KZPMA8S0K9SNDXXK4NS2ZWFA.yml diff --git a/ledger-cli/tests/fixtures/coverage/.decisions/log/01KZPMA8T68ZYVCJZXG9Z07FYW.yml b/ledger-cli/tests/fixtures/coverage/.decisions/ns/fixture.coverage/log/01KZPMA8T68ZYVCJZXG9Z07FYW.yml similarity index 100% rename from ledger-cli/tests/fixtures/coverage/.decisions/log/01KZPMA8T68ZYVCJZXG9Z07FYW.yml rename to ledger-cli/tests/fixtures/coverage/.decisions/ns/fixture.coverage/log/01KZPMA8T68ZYVCJZXG9Z07FYW.yml diff --git a/ledger-cli/tests/fixtures/coverage/.decisions/log/01KZPMA8VERG1CGNA3JWWADRF1.yml b/ledger-cli/tests/fixtures/coverage/.decisions/ns/fixture.coverage/log/01KZPMA8VERG1CGNA3JWWADRF1.yml similarity index 100% rename from ledger-cli/tests/fixtures/coverage/.decisions/log/01KZPMA8VERG1CGNA3JWWADRF1.yml rename to ledger-cli/tests/fixtures/coverage/.decisions/ns/fixture.coverage/log/01KZPMA8VERG1CGNA3JWWADRF1.yml diff --git a/ledger-cli/tests/fixtures/coverage/.decisions/log/01KZPMA8WVA4P7GEDV915Y5GG8.yml b/ledger-cli/tests/fixtures/coverage/.decisions/ns/fixture.coverage/log/01KZPMA8WVA4P7GEDV915Y5GG8.yml similarity index 100% rename from ledger-cli/tests/fixtures/coverage/.decisions/log/01KZPMA8WVA4P7GEDV915Y5GG8.yml rename to ledger-cli/tests/fixtures/coverage/.decisions/ns/fixture.coverage/log/01KZPMA8WVA4P7GEDV915Y5GG8.yml diff --git a/ledger-cli/tests/fixtures/coverage/.decisions/log/01KZPMA8YA7J3H1HQT79599BDJ.yml b/ledger-cli/tests/fixtures/coverage/.decisions/ns/fixture.coverage/log/01KZPMA8YA7J3H1HQT79599BDJ.yml similarity index 100% rename from ledger-cli/tests/fixtures/coverage/.decisions/log/01KZPMA8YA7J3H1HQT79599BDJ.yml rename to ledger-cli/tests/fixtures/coverage/.decisions/ns/fixture.coverage/log/01KZPMA8YA7J3H1HQT79599BDJ.yml diff --git a/ledger-cli/tests/fixtures/coverage/.decisions/log/01KZPMA8ZWBD1ADF7GP27HGH6S.yml b/ledger-cli/tests/fixtures/coverage/.decisions/ns/fixture.coverage/log/01KZPMA8ZWBD1ADF7GP27HGH6S.yml similarity index 100% rename from ledger-cli/tests/fixtures/coverage/.decisions/log/01KZPMA8ZWBD1ADF7GP27HGH6S.yml rename to ledger-cli/tests/fixtures/coverage/.decisions/ns/fixture.coverage/log/01KZPMA8ZWBD1ADF7GP27HGH6S.yml diff --git a/ledger-cli/tests/fixtures/coverage/.decisions/sets/coverage-fixture.yml b/ledger-cli/tests/fixtures/coverage/.decisions/ns/fixture.coverage/sets/coverage-fixture.yml similarity index 100% rename from ledger-cli/tests/fixtures/coverage/.decisions/sets/coverage-fixture.yml rename to ledger-cli/tests/fixtures/coverage/.decisions/ns/fixture.coverage/sets/coverage-fixture.yml diff --git a/ledger-cli/tests/fixtures/forked/.decisions/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml b/ledger-cli/tests/fixtures/forked/.decisions/ns/fixture.forked/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml similarity index 100% rename from ledger-cli/tests/fixtures/forked/.decisions/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml rename to ledger-cli/tests/fixtures/forked/.decisions/ns/fixture.forked/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml diff --git a/ledger-cli/tests/fixtures/forked/.decisions/log/01K2C4YQJ3F8M0PT5W7NZ9RDY0.yml b/ledger-cli/tests/fixtures/forked/.decisions/ns/fixture.forked/log/01K2C4YQJ3F8M0PT5W7NZ9RDY0.yml similarity index 100% rename from ledger-cli/tests/fixtures/forked/.decisions/log/01K2C4YQJ3F8M0PT5W7NZ9RDY0.yml rename to ledger-cli/tests/fixtures/forked/.decisions/ns/fixture.forked/log/01K2C4YQJ3F8M0PT5W7NZ9RDY0.yml diff --git a/ledger-cli/tests/fixtures/forked/.decisions/log/01K2C4YQJ3F8M0PT5W7NZ9RDY1.yml b/ledger-cli/tests/fixtures/forked/.decisions/ns/fixture.forked/log/01K2C4YQJ3F8M0PT5W7NZ9RDY1.yml similarity index 100% rename from ledger-cli/tests/fixtures/forked/.decisions/log/01K2C4YQJ3F8M0PT5W7NZ9RDY1.yml rename to ledger-cli/tests/fixtures/forked/.decisions/ns/fixture.forked/log/01K2C4YQJ3F8M0PT5W7NZ9RDY1.yml diff --git a/ledger-cli/tests/fixtures/forked/.decisions/sets/forked.yml b/ledger-cli/tests/fixtures/forked/.decisions/ns/fixture.forked/sets/forked.yml similarity index 100% rename from ledger-cli/tests/fixtures/forked/.decisions/sets/forked.yml rename to ledger-cli/tests/fixtures/forked/.decisions/ns/fixture.forked/sets/forked.yml diff --git a/ledger-cli/tests/fixtures/l001/.decisions/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml b/ledger-cli/tests/fixtures/l001/.decisions/ns/fixture.ledger/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml similarity index 100% rename from ledger-cli/tests/fixtures/l001/.decisions/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml rename to ledger-cli/tests/fixtures/l001/.decisions/ns/fixture.ledger/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml diff --git a/ledger-cli/tests/fixtures/l001/.decisions/sets/ledger-fixture.yml b/ledger-cli/tests/fixtures/l001/.decisions/ns/fixture.ledger/sets/ledger-fixture.yml similarity index 100% rename from ledger-cli/tests/fixtures/l001/.decisions/sets/ledger-fixture.yml rename to ledger-cli/tests/fixtures/l001/.decisions/ns/fixture.ledger/sets/ledger-fixture.yml diff --git a/ledger-cli/tests/fixtures/l002/.decisions/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml b/ledger-cli/tests/fixtures/l002/.decisions/ns/fixture.ledger/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml similarity index 100% rename from ledger-cli/tests/fixtures/l002/.decisions/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml rename to ledger-cli/tests/fixtures/l002/.decisions/ns/fixture.ledger/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml diff --git a/ledger-cli/tests/fixtures/l002/.decisions/sets/ledger-fixture.yml b/ledger-cli/tests/fixtures/l002/.decisions/ns/fixture.ledger/sets/ledger-fixture.yml similarity index 100% rename from ledger-cli/tests/fixtures/l002/.decisions/sets/ledger-fixture.yml rename to ledger-cli/tests/fixtures/l002/.decisions/ns/fixture.ledger/sets/ledger-fixture.yml diff --git a/ledger-cli/tests/fixtures/l003/.decisions/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml b/ledger-cli/tests/fixtures/l003/.decisions/ns/fixture.ledger/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml similarity index 100% rename from ledger-cli/tests/fixtures/l003/.decisions/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml rename to ledger-cli/tests/fixtures/l003/.decisions/ns/fixture.ledger/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml diff --git a/ledger-cli/tests/fixtures/l003/.decisions/sets/ledger-fixture.yml b/ledger-cli/tests/fixtures/l003/.decisions/ns/fixture.ledger/sets/ledger-fixture.yml similarity index 100% rename from ledger-cli/tests/fixtures/l003/.decisions/sets/ledger-fixture.yml rename to ledger-cli/tests/fixtures/l003/.decisions/ns/fixture.ledger/sets/ledger-fixture.yml diff --git a/ledger-cli/tests/fixtures/l004/.decisions/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml b/ledger-cli/tests/fixtures/l004/.decisions/ns/fixture.ledger/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml similarity index 100% rename from ledger-cli/tests/fixtures/l004/.decisions/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml rename to ledger-cli/tests/fixtures/l004/.decisions/ns/fixture.ledger/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml diff --git a/ledger-cli/tests/fixtures/l004/.decisions/sets/ledger-fixture.yml b/ledger-cli/tests/fixtures/l004/.decisions/ns/fixture.ledger/sets/ledger-fixture.yml similarity index 100% rename from ledger-cli/tests/fixtures/l004/.decisions/sets/ledger-fixture.yml rename to ledger-cli/tests/fixtures/l004/.decisions/ns/fixture.ledger/sets/ledger-fixture.yml diff --git a/ledger-cli/tests/fixtures/l005/.decisions/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml b/ledger-cli/tests/fixtures/l005/.decisions/ns/fixture.ledger/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml similarity index 100% rename from ledger-cli/tests/fixtures/l005/.decisions/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml rename to ledger-cli/tests/fixtures/l005/.decisions/ns/fixture.ledger/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml diff --git a/ledger-cli/tests/fixtures/l005/.decisions/sets/ledger-fixture.yml b/ledger-cli/tests/fixtures/l005/.decisions/ns/fixture.ledger/sets/ledger-fixture.yml similarity index 100% rename from ledger-cli/tests/fixtures/l005/.decisions/sets/ledger-fixture.yml rename to ledger-cli/tests/fixtures/l005/.decisions/ns/fixture.ledger/sets/ledger-fixture.yml diff --git a/ledger-cli/tests/fixtures/l006/.decisions/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml b/ledger-cli/tests/fixtures/l006/.decisions/ns/fixture.ledger/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml similarity index 100% rename from ledger-cli/tests/fixtures/l006/.decisions/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml rename to ledger-cli/tests/fixtures/l006/.decisions/ns/fixture.ledger/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml diff --git a/ledger-cli/tests/fixtures/l006/.decisions/sets/ledger-fixture.yml b/ledger-cli/tests/fixtures/l006/.decisions/ns/fixture.ledger/sets/ledger-fixture.yml similarity index 100% rename from ledger-cli/tests/fixtures/l006/.decisions/sets/ledger-fixture.yml rename to ledger-cli/tests/fixtures/l006/.decisions/ns/fixture.ledger/sets/ledger-fixture.yml diff --git a/ledger-cli/tests/fixtures/l007/.decisions/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml b/ledger-cli/tests/fixtures/l007/.decisions/ns/fixture.ledger/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml similarity index 100% rename from ledger-cli/tests/fixtures/l007/.decisions/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml rename to ledger-cli/tests/fixtures/l007/.decisions/ns/fixture.ledger/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml diff --git a/ledger-cli/tests/fixtures/l007/.decisions/sets/ledger-fixture.yml b/ledger-cli/tests/fixtures/l007/.decisions/ns/fixture.ledger/sets/ledger-fixture.yml similarity index 100% rename from ledger-cli/tests/fixtures/l007/.decisions/sets/ledger-fixture.yml rename to ledger-cli/tests/fixtures/l007/.decisions/ns/fixture.ledger/sets/ledger-fixture.yml diff --git a/ledger-cli/tests/fixtures/l008/.decisions/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml b/ledger-cli/tests/fixtures/l008/.decisions/ns/fixture.ledger/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml similarity index 100% rename from ledger-cli/tests/fixtures/l008/.decisions/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml rename to ledger-cli/tests/fixtures/l008/.decisions/ns/fixture.ledger/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml diff --git a/ledger-cli/tests/fixtures/l008/.decisions/sets/ledger-fixture.yml b/ledger-cli/tests/fixtures/l008/.decisions/ns/fixture.ledger/sets/ledger-fixture.yml similarity index 100% rename from ledger-cli/tests/fixtures/l008/.decisions/sets/ledger-fixture.yml rename to ledger-cli/tests/fixtures/l008/.decisions/ns/fixture.ledger/sets/ledger-fixture.yml diff --git a/ledger-cli/tests/fixtures/l010/.decisions/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml b/ledger-cli/tests/fixtures/l010/.decisions/ns/fixture.ledger/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml similarity index 100% rename from ledger-cli/tests/fixtures/l010/.decisions/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml rename to ledger-cli/tests/fixtures/l010/.decisions/ns/fixture.ledger/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml diff --git a/ledger-cli/tests/fixtures/l010/.decisions/sets/ledger-fixture.yml b/ledger-cli/tests/fixtures/l010/.decisions/ns/fixture.ledger/sets/ledger-fixture.yml similarity index 100% rename from ledger-cli/tests/fixtures/l010/.decisions/sets/ledger-fixture.yml rename to ledger-cli/tests/fixtures/l010/.decisions/ns/fixture.ledger/sets/ledger-fixture.yml diff --git a/ledger-cli/tests/fixtures/l013/.decisions/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml b/ledger-cli/tests/fixtures/l013/.decisions/ns/fixture.ledger/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml similarity index 100% rename from ledger-cli/tests/fixtures/l013/.decisions/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml rename to ledger-cli/tests/fixtures/l013/.decisions/ns/fixture.ledger/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml diff --git a/ledger-cli/tests/fixtures/l013/.decisions/sets/ledger-fixture.yml b/ledger-cli/tests/fixtures/l013/.decisions/ns/fixture.ledger/sets/ledger-fixture.yml similarity index 100% rename from ledger-cli/tests/fixtures/l013/.decisions/sets/ledger-fixture.yml rename to ledger-cli/tests/fixtures/l013/.decisions/ns/fixture.ledger/sets/ledger-fixture.yml diff --git a/ledger-cli/tests/fixtures/l014/.decisions/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml b/ledger-cli/tests/fixtures/l014/.decisions/ns/fixture.ledger/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml similarity index 100% rename from ledger-cli/tests/fixtures/l014/.decisions/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml rename to ledger-cli/tests/fixtures/l014/.decisions/ns/fixture.ledger/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml diff --git a/ledger-cli/tests/fixtures/l014/.decisions/sets/ledger-fixture.yml b/ledger-cli/tests/fixtures/l014/.decisions/ns/fixture.ledger/sets/ledger-fixture.yml similarity index 100% rename from ledger-cli/tests/fixtures/l014/.decisions/sets/ledger-fixture.yml rename to ledger-cli/tests/fixtures/l014/.decisions/ns/fixture.ledger/sets/ledger-fixture.yml diff --git a/ledger-cli/tests/fixtures/pass/.decisions/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml b/ledger-cli/tests/fixtures/pass/.decisions/ns/fixture.ledger/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml similarity index 100% rename from ledger-cli/tests/fixtures/pass/.decisions/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml rename to ledger-cli/tests/fixtures/pass/.decisions/ns/fixture.ledger/log/01K2C4YQJ3F8M0PT5W7NZ9RDXW.yml diff --git a/ledger-cli/tests/fixtures/pass/.decisions/sets/ledger-fixture.yml b/ledger-cli/tests/fixtures/pass/.decisions/ns/fixture.ledger/sets/ledger-fixture.yml similarity index 100% rename from ledger-cli/tests/fixtures/pass/.decisions/sets/ledger-fixture.yml rename to ledger-cli/tests/fixtures/pass/.decisions/ns/fixture.ledger/sets/ledger-fixture.yml diff --git a/ledger-cli/tests/fixtures/two-clocks/.decisions/log/01K2000000000000000000000A.yml b/ledger-cli/tests/fixtures/two-clocks/.decisions/ns/fixture.two-clocks/log/01K2000000000000000000000A.yml similarity index 100% rename from ledger-cli/tests/fixtures/two-clocks/.decisions/log/01K2000000000000000000000A.yml rename to ledger-cli/tests/fixtures/two-clocks/.decisions/ns/fixture.two-clocks/log/01K2000000000000000000000A.yml diff --git a/ledger-cli/tests/fixtures/two-clocks/.decisions/log/01K2ZZZZZZZZZZZZZZZZZZZZZZ.yml b/ledger-cli/tests/fixtures/two-clocks/.decisions/ns/fixture.two-clocks/log/01K2ZZZZZZZZZZZZZZZZZZZZZZ.yml similarity index 100% rename from ledger-cli/tests/fixtures/two-clocks/.decisions/log/01K2ZZZZZZZZZZZZZZZZZZZZZZ.yml rename to ledger-cli/tests/fixtures/two-clocks/.decisions/ns/fixture.two-clocks/log/01K2ZZZZZZZZZZZZZZZZZZZZZZ.yml diff --git a/ledger-cli/tests/fixtures/two-clocks/.decisions/sets/two-clocks.yml b/ledger-cli/tests/fixtures/two-clocks/.decisions/ns/fixture.two-clocks/sets/two-clocks.yml similarity index 100% rename from ledger-cli/tests/fixtures/two-clocks/.decisions/sets/two-clocks.yml rename to ledger-cli/tests/fixtures/two-clocks/.decisions/ns/fixture.two-clocks/sets/two-clocks.yml diff --git a/ledger-cli/tests/format_history.rs b/ledger-cli/tests/format_history.rs index 91cd3a3a..54ed7095 100644 --- a/ledger-cli/tests/format_history.rs +++ b/ledger-cli/tests/format_history.rs @@ -18,7 +18,7 @@ const CS: &str = "01K2C4YQJ3F8M0PT5W7NZ9RDXW"; /// The `pass` fixture's store (its change-set needs format 1), landed /// declaring `format: N`. Returns the log file. fn landed_at(repo: &Repo, n: u32) -> PathBuf { - common::stage_fixture_into("pass", repo.path()); + common::copy_fixture_into("pass", repo.path()); let file = repo.log_dir("fixture.ledger").join(format!("{CS}.yml")); redeclare(&file, 1, n); hand::commit(repo, &format!("landed at format {n}")); diff --git a/ledger-cli/tests/gate.rs b/ledger-cli/tests/gate.rs index 6399509a..f574d158 100644 --- a/ledger-cli/tests/gate.rs +++ b/ledger-cli/tests/gate.rs @@ -32,11 +32,11 @@ fn fixtures() -> PathBuf { Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/fixtures") } -/// Run the gate over a fixture store, staged under `.decisions/ns//` -/// (`common::stage_fixture`). Blame is off: these stores live inside +/// Run the gate over a scratch copy of a fixture store +/// (`common::fixture_copy`). Blame is off: these stores live inside /// this repository, so their history attributes to whoever committed them. fn gate(fixture: &str, extra: &[&str]) -> Output { - let staged = common::stage_fixture(fixture); + let staged = common::fixture_copy(fixture); let mut cmd = Command::cargo_bin("ledger").expect("binary"); cmd.arg("--root") .arg(staged.path()) @@ -201,7 +201,7 @@ mod blame { } fn copy_pass_fixture(&self) { - common::stage_fixture_into("pass", self.path()); + common::copy_fixture_into("pass", self.path()); } fn git(&self, args: &[&str]) { @@ -284,13 +284,14 @@ fn fixture_hashes_are_current() { ); } -/// The log files of one fixture store: `.decisions/ns//log/*` (LP-3.34) -/// or, until issue 9 re-lays the fixtures out, the flat `.decisions/log/*`. +/// The log files of one fixture store: `.decisions/ns//log/*` (LP-3.34). fn fixture_log_files(root: &Path) -> Vec { - let mut dirs: Vec = - ledger_core::layout::namespaces(root).iter().map(|ns| ledger_core::layout::log_dir(root, ns)).collect(); - dirs.push(root.join(".decisions/log")); - dirs.into_iter().filter(|d| d.is_dir()).flat_map(|d| std::fs::read_dir(d).expect("log").flatten()).collect() + ledger_core::layout::namespaces(root) + .iter() + .map(|ns| ledger_core::layout::log_dir(root, ns)) + .filter(|d| d.is_dir()) + .flat_map(|d| std::fs::read_dir(d).expect("log").flatten()) + .collect() } /// Rewrite the stored hashes in one log file. Returns whether it was stale. diff --git a/ledger-cli/tests/graph.rs b/ledger-cli/tests/graph.rs index c519464d..d06a045d 100644 --- a/ledger-cli/tests/graph.rs +++ b/ledger-cli/tests/graph.rs @@ -25,7 +25,7 @@ fn stdout(out: &Output) -> String { /// A scratch copy of the coverage fixture, so tests can write an index. fn scratch_coverage() -> tempfile::TempDir { - common::stage_fixture("coverage") + common::fixture_copy("coverage") } #[test] @@ -46,7 +46,7 @@ fn the_rebuild_is_byte_identical_after_deleting_the_index() { #[test] fn coverage_distinguishes_all_seven_states_on_the_fixture() { - let staged = common::stage_fixture("coverage"); + let staged = common::fixture_copy("coverage"); let root = staged.path().to_path_buf(); let out = ledger(&root, &["coverage", "--today", TODAY]); assert_eq!(out.status.code(), Some(0), "{}", String::from_utf8_lossy(&out.stderr)); @@ -70,7 +70,7 @@ fn coverage_distinguishes_all_seven_states_on_the_fixture() { #[test] fn coverage_json_carries_the_states_and_the_chain_machine_readably() { - let staged = common::stage_fixture("coverage"); + let staged = common::fixture_copy("coverage"); let root = staged.path().to_path_buf(); let out = ledger(&root, &["coverage", "--today", TODAY, "--json"]); let parsed: serde_json::Value = serde_json::from_str(&stdout(&out)).expect("json"); @@ -84,7 +84,7 @@ fn coverage_json_carries_the_states_and_the_chain_machine_readably() { fn a_superseded_versions_acceptances_are_historical_in_blame_and_status() { // d7 (the chain root) is superseded; the fixture's `decided` decision // d3 stays live. Status renders the supersession terminally. - let staged = common::stage_fixture("coverage"); + let staged = common::fixture_copy("coverage"); let root = staged.path().to_path_buf(); let out = ledger(&root, &["status", "--today", TODAY]); let text = stdout(&out); @@ -128,7 +128,7 @@ fn latest_follows_the_parent_dag_when_ulid_order_contradicts_it() { // a writer whose clock runs ahead. ULID order would call the root // latest and the signed revision historical; the parent DAG knows the // revision is the tip, so the store is conformant and decided. - let staged = common::stage_fixture("two-clocks"); + let staged = common::fixture_copy("two-clocks"); let root = staged.path().to_path_buf(); let out = ledger(&root, &["verify", "--today", "2026-08-10", "--no-blame"]); assert_eq!(out.status.code(), Some(0), "{}", String::from_utf8_lossy(&out.stderr)); @@ -150,7 +150,7 @@ fn g004_a_forked_chain_fails_verify_and_names_both_tips() { // produces: one parent, two divergent revisions. No file is malformed; // the graph stage names the fork and the store is non-conformant until // a human arbitrates. - let staged = common::stage_fixture("forked"); + let staged = common::fixture_copy("forked"); let root = staged.path().to_path_buf(); let out = ledger(&root, &["verify", "--today", "2026-08-10", "--no-blame"]); assert_eq!(out.status.code(), Some(1), "{}", String::from_utf8_lossy(&out.stderr)); diff --git a/ledger-cli/tests/landed_header.rs b/ledger-cli/tests/landed_header.rs index 64d36501..47b039c9 100644 --- a/ledger-cli/tests/landed_header.rs +++ b/ledger-cli/tests/landed_header.rs @@ -14,7 +14,7 @@ const CS: &str = "01K2C4YQJ3F8M0PT5W7NZ9RDXW"; /// The `pass` fixture's store, committed. fn landed() -> Repo { let repo = Repo::human(); - common::stage_fixture_into("pass", repo.path()); + common::copy_fixture_into("pass", repo.path()); hand::commit(&repo, "landed"); repo } diff --git a/ledger-cli/tests/legacy_layout.rs b/ledger-cli/tests/legacy_layout.rs index b5a9f877..3f6f8d7e 100644 --- a/ledger-cli/tests/legacy_layout.rs +++ b/ledger-cli/tests/legacy_layout.rs @@ -27,7 +27,9 @@ const RELAYER: &str = "relayout@example"; /// commit's id. fn flat_history() -> (Repo, String) { let repo = Repo::with_identity(ACCEPTOR); - let from = Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/fixtures/pass/.decisions"); + // The fixture is committed in the v1.9 layout; its files are laid flat + // here, byte for byte, as a v1.8 writer filed them. + let from = Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/fixtures/pass/.decisions/ns").join(NS); for sub in ["sets", "log"] { let to = repo.path().join(".decisions").join(sub); std::fs::create_dir_all(&to).expect("mkdir"); diff --git a/ledger-cli/tests/revisit_format.rs b/ledger-cli/tests/revisit_format.rs index 69b242c7..332f7ea3 100644 --- a/ledger-cli/tests/revisit_format.rs +++ b/ledger-cli/tests/revisit_format.rs @@ -149,7 +149,7 @@ fn the_corrected_files_declare_exactly_what_they_need() { /// acceptance of their own hash, and the gate finds nothing about them. #[test] fn the_four_acceptances_still_verify() { - let staged = common::stage_workspace(); + let staged = common::workspace_copy(); let store = ledger_core::store::load(staged.path()); let view = View::build(&store); let report = verify::verify(&store, &Options::offline(chrono::Utc::now().date_naive())); diff --git a/ledger-cli/tests/scalars.rs b/ledger-cli/tests/scalars.rs index 6afaec18..4eebb69e 100644 --- a/ledger-cli/tests/scalars.rs +++ b/ledger-cli/tests/scalars.rs @@ -17,7 +17,7 @@ const CS: &str = "01K2C4YQJ3F8M0PT5W7NZ9RDXW"; /// the loader computes, committed beside the `pass` fixture's set. fn committed(scalar: &str) -> (i32, String) { let repo = Repo::human(); - let sets = Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/fixtures/pass/.decisions/sets"); + let sets = Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/fixtures/pass/.decisions/ns/fixture.ledger/sets"); std::fs::create_dir_all(repo.sets_dir("fixture.ledger")).expect("sets dir"); for entry in std::fs::read_dir(sets).expect("fixture").flatten() { std::fs::copy(entry.path(), repo.sets_dir("fixture.ledger").join(entry.file_name())).expect("copy"); diff --git a/ledger/spec/ledger-protocol.md b/ledger/spec/ledger-protocol.md index e6057290..00858bc4 100644 --- a/ledger/spec/ledger-protocol.md +++ b/ledger/spec/ledger-protocol.md @@ -1476,6 +1476,7 @@ A deployment should tell holders, before they accept a grant, that their address | 7 October 2026 | Ruling 58 applied: a landed `format:` declaration is compared across first-parent history, and any change other than the LP-3.16 correction fails `L007` (LP-3.16, LP-8.30, `L007`'s wording). This enforces the ruling of 5 October on #81; its three corrections stay green. No class added; no digest moves. | | 7 October 2026 | Ruling 59 applied: a `set:` grant scope accepts every valid set id, dots included (LP-3.3). The reference had refused a dot, which section 3.3 allows. No class added; no digest moves: a scope is hashed as written. | | 7 October 2026 | Ruling 60 applied: a change-set's `parents` is part of its header entity and immutable once landed (LP-8.25). The reference had keyed each parent as its own entity, so a parent appended to a landed header passed. No class added; no digest moves. | +| 9 October 2026 | **Rulings 63 and 68 applied: the fixtures re-laid out; the re-founding note** (PRD §3.11; issue 9). The fifteen committed fixture stores of the reference test suite move their `sets/` and `log/` under `ns//`, no file's content or digest changed; the test helpers that staged a flat fixture into the layout go. The Appendix C note "Namespaces become independent; a store with shared authority is re-founded" is added as the PRD drafted it, headed with no format number. No class added; no digest moves. | | 9 October 2026 | **Ruling 69 applied: a close in every namespace held** (PRD §3.3; issue 8). LP-6.34 (new): a writer closes a key in every namespace its principal holds it open in with one change-set per namespace, the same act with the same `at`, to land in one commit; LP-6.32 loses its note. The writer's opening of every namespace on its own genesis (LP-4.38) landed with issues 5 and 6. No class added; no digest moves; no Appendix C note. | | 9 October 2026 | **Ruling 47 applied: `allowed_signers` per namespace** (PRD §3.4; issue 7). LP-4.10 loses its note: each namespace's file holds that namespace's trusted bindings, a line ended by a close in that namespace only (LP-4.32), a namespace that binds nothing has no file, and a writer that regenerates the files removes a stale one; LP-4.33 names the namespace a `[SIGNERS]` finding is about. No class added; no digest moves. The Appendix C note "A stale `allowed_signers` is removed" is added. | | 9 October 2026 | **Rulings 47 and 69 applied: keys per namespace** (PRD §3.3; issue 6). LP-6.32 loses its not-implemented mark: a close ends the key in its own namespace only; LP-4.37's three rules, LP-4.39 (with ruling 101's wording) and LP-4.13's deadline look at the binding's own namespace; the genesis holder's first key in a namespace is that namespace's self-bound binding, once per namespace, and a key trusted elsewhere vouches for nothing here (LP-4.12, LP-4.31, LP-4.38 — the later-namespace paragraph goes, with the reference's `carried_over`); `allowed_signers` ends a line at a close in its own namespace (LP-4.32); LP-8.31 gains the two notices of ruling 69. LP-6.31 drops its keys note. No class added; no digest moves. The Appendix C note "Keys are per namespace" is added. | @@ -1627,6 +1628,45 @@ only adds an unhashed field. --- +#### Namespaces become independent; a store with shared authority is re-founded (spec v1.9, no format change) + +From v1.9 every store holds each namespace under +`.decisions/ns//`. Each namespace has its own genesis grant, +roles, grants, key bindings, policy and `allowed_signers`, and nothing in +one namespace's authority has effect in another (rulings 47, 62, 63; the +notes "Authority is per namespace" and "Keys are per namespace" below). + +**Who must act.** A store whose log holds a policy for more than one +namespace, filed before v1.9, shared one genesis grant, one set of role +files and one set of trusted keys across them. Its namespaces cannot be +split, and no migration path is provided (ruling 68). Under v1.9 rules +such a store fails verification: each namespace after the first has no +genesis grant of its own (`A006` on its policy, D7 on its first key +binding). + +**What to do.** Re-found each namespace: + +1. Open it in a fresh directory, `.decisions/ns//`, with + `ledger init --namespace --external-ref `. That + files its own genesis grant, roles, first policy and self-bound key. +2. Grant its roles again. +3. File each decision's latest version again, with its key carried, and + accept it again under the new authority. + +**What is not carried over.** Acceptances, grants and key windows of the +old store. The old store's history stays in git as the record of what was +accepted under it. Re-founding is a new start, not a migration, and no +digest of the old store is reused by the new one. + +**A store with one namespace, or with none under policy,** is not +re-founded. It moves its files under `ns//` in one commit, and +landing follows each entity across the move (the note "Spec v1.9 — one +directory per namespace" below). + +*The PRD's draft of this note (§3.11) is headed "spec v1.9 and format 8"; +no format number changes here (ruling 66 as amended by 87), and format 8 +arrives with the issues that follow.* + #### A stale `allowed_signers` is removed; a close reaches its own namespace's file only (2026-10-09, no format change) **Ruled 7 October 2026** (ruling 47; `ledger/prd/namespace-independence-prd.md` @@ -1720,7 +1760,8 @@ be split, and no migration path is provided (ruling 68). Under these rules such a store fails verification: each namespace after the first has no genesis grant of its own (`A006` on its policy) and its first key binding leans on no other namespace (D7 on that binding). It is re-founded per -namespace; the re-founding note is added with issue 9 of the PRD's §6. +namespace: the note "Namespaces become independent; a store with shared +authority is re-founded" above. **Keys are not yet per namespace.** A key is still bound, closed and trusted store-wide (LP-4.12, LP-4.31, LP-4.32, LP-4.37, LP-4.38, LP-4.39): @@ -1786,13 +1827,14 @@ No class is added: the refusal is `SCHEMA`. namespace its entities belong to, each set to the namespace whose versions name it, each role file to the namespace whose grants and policies name it. A governed store with more than one namespace is not moved but -re-founded (ruling 68); its note lands with issue 9. This repository's -own store was re-laid out in one commit on 9 October 2026 (issue 10): -`hafeok.ddd`'s 164 change-sets and its set to `ns/hafeok.ddd/`, -`hafeok.ledger`'s 23 and its set to `ns/hafeok.ledger/`, every file byte -for byte, both exports unchanged. The committed fixture stores are -re-laid out by issue 9; until then a verifier of this revision refuses -them, as LP-3.34 says. +re-founded (ruling 68; the note "Namespaces become independent; a store +with shared authority is re-founded"). This repository's own store was +re-laid out in one commit on 9 October 2026 (issue 10): `hafeok.ddd`'s +164 change-sets and its set to `ns/hafeok.ddd/`, `hafeok.ledger`'s 23 +and its set to `ns/hafeok.ledger/`, every file byte for byte, both +exports unchanged. The fifteen committed fixture stores under +`ledger-cli/tests/fixtures/` were re-laid out the same way (issue 9), each +under its one namespace, no file's content or digest changed. **The flat layout in history** (rulings 82 and 97; LP-3.35). The re-layout cannot make the flat paths disappear from history, and From a3f3d54add67fd6c96ccd874d5f61cdddd973579 Mon Sep 17 00:00:00 2001 From: "Claude (Emil)" Date: Sun, 11 Oct 2026 06:22:07 +0000 Subject: [PATCH 2/2] Seam bindings for step 9: the fixtures under ns// Files the signed bindings the contract-surface gate demands for this step's eight exposed Rust surface changes, all test helpers in ledger-cli/tests/common/mod.rs: the four staging-shim helpers removed and the four copy helpers that replace them. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01GgRcHXmnAu43hChNxhnqxU --- ...m-rust-ledger-cli-tests-common-mod-rs.yaml | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/.ddd/seams/seam-rust-ledger-cli-tests-common-mod-rs.yaml b/.ddd/seams/seam-rust-ledger-cli-tests-common-mod-rs.yaml index 4ff3d0d4..41463dff 100644 --- a/.ddd/seams/seam-rust-ledger-cli-tests-common-mod-rs.yaml +++ b/.ddd/seams/seam-rust-ledger-cli-tests-common-mod-rs.yaml @@ -270,3 +270,51 @@ bindings: after: sha256:4950bad589fd7178075bd548a44829ce5427af2c8f9efb20d2cfb88bf1460db8 base_revision: 70395dfe317cb9a00665433813766ca763f3c58a hash: sha256:8debaac1a6019c0a4e89fd05aebdc38472dc853fd33d1e9eef714237ff482817 +- symbol: copy_fixture_into + file: ledger-cli/tests/common/mod.rs + before: sha256:4950bad589fd7178075bd548a44829ce5427af2c8f9efb20d2cfb88bf1460db8 + after: sha256:d38812b1be3063fc0a3b6246abceb1ce7867035b787e9c5dfaca58026242aa7d + base_revision: 0fafebcd753944b5931fffd3d4fe841b703a6b8b + hash: sha256:2e68b054fa86d714cbb63cf75496c44896ca04bcdc7ab0e4e9b6ad00f71a3f5e +- symbol: copy_store_into + file: ledger-cli/tests/common/mod.rs + before: sha256:4950bad589fd7178075bd548a44829ce5427af2c8f9efb20d2cfb88bf1460db8 + after: sha256:d38812b1be3063fc0a3b6246abceb1ce7867035b787e9c5dfaca58026242aa7d + base_revision: 0fafebcd753944b5931fffd3d4fe841b703a6b8b + hash: sha256:6e6f8f489f38de5fe96392bc425ddbfe26da43e61732baadb8b8dcfd44769a86 +- symbol: fixture_copy + file: ledger-cli/tests/common/mod.rs + before: sha256:4950bad589fd7178075bd548a44829ce5427af2c8f9efb20d2cfb88bf1460db8 + after: sha256:d38812b1be3063fc0a3b6246abceb1ce7867035b787e9c5dfaca58026242aa7d + base_revision: 0fafebcd753944b5931fffd3d4fe841b703a6b8b + hash: sha256:500db47caf9fd8712a2281e9408e902f8b2214147d0a54e389e2a4c16df1c5b8 +- symbol: workspace_copy + file: ledger-cli/tests/common/mod.rs + before: sha256:4950bad589fd7178075bd548a44829ce5427af2c8f9efb20d2cfb88bf1460db8 + after: sha256:d38812b1be3063fc0a3b6246abceb1ce7867035b787e9c5dfaca58026242aa7d + base_revision: 0fafebcd753944b5931fffd3d4fe841b703a6b8b + hash: sha256:6e2265df119ec47cc2c0b2262a75b56575b9d0bfa19a41748015ea4e7ee31ca5 +- symbol: stage_fixture + file: ledger-cli/tests/common/mod.rs + before: sha256:4950bad589fd7178075bd548a44829ce5427af2c8f9efb20d2cfb88bf1460db8 + after: sha256:d38812b1be3063fc0a3b6246abceb1ce7867035b787e9c5dfaca58026242aa7d + base_revision: 0fafebcd753944b5931fffd3d4fe841b703a6b8b + hash: sha256:95ee587ed7f5d0e93e31548cbc105c211d55ca70ce8eaef6fd9469c5c98a596c +- symbol: stage_fixture_into + file: ledger-cli/tests/common/mod.rs + before: sha256:4950bad589fd7178075bd548a44829ce5427af2c8f9efb20d2cfb88bf1460db8 + after: sha256:d38812b1be3063fc0a3b6246abceb1ce7867035b787e9c5dfaca58026242aa7d + base_revision: 0fafebcd753944b5931fffd3d4fe841b703a6b8b + hash: sha256:2a7a9bba87a4d4faa005ae07dde38f88074c2497e6c9126effa6e3dd292ae559 +- symbol: stage_store_into + file: ledger-cli/tests/common/mod.rs + before: sha256:4950bad589fd7178075bd548a44829ce5427af2c8f9efb20d2cfb88bf1460db8 + after: sha256:d38812b1be3063fc0a3b6246abceb1ce7867035b787e9c5dfaca58026242aa7d + base_revision: 0fafebcd753944b5931fffd3d4fe841b703a6b8b + hash: sha256:46c21d64d31e336403e2299122c3285bf997a177c6d474522a6dc542cc2e9688 +- symbol: stage_workspace + file: ledger-cli/tests/common/mod.rs + before: sha256:4950bad589fd7178075bd548a44829ce5427af2c8f9efb20d2cfb88bf1460db8 + after: sha256:d38812b1be3063fc0a3b6246abceb1ce7867035b787e9c5dfaca58026242aa7d + base_revision: 0fafebcd753944b5931fffd3d4fe841b703a6b8b + hash: sha256:d2d52238f232a4fdbcb5d5bb897771d777f21866a29653124f560e8d142cf8ed