Skip to content

Load every store from ns/<ns>/; refuse flat paths at the verified commit (issue 1) - #154

Open
Hafeok wants to merge 3 commits into
mainfrom
claude/great-feynman-zcdsdd-step-01-layout
Open

Hafeok wants to merge 3 commits into
mainfrom
claude/great-feynman-zcdsdd-step-01-layout

Conversation

@Hafeok

@Hafeok Hafeok commented Oct 9, 2026

Copy link
Copy Markdown
Collaborator

Closes #144 (PRD §6 issue 1; rulings 62, 63, 66 as amended by 87; AC-63). Step 1 of the namespace layout and authority session.

What lands. Every store holds each namespace under .decisions/ns/<namespace>/, with its own sets/, roles/, log/, sig/ and allowed_signers; a file's namespace is its directory. The loader reads only those directories. A file at a flat path of revision v1.8, or anywhere under .decisions/ outside ns/ and index/, is a SCHEMA fault naming the path, and so is a store with no ns/ and any of those paths (AC-63).

  • ledger_core::layout is the one module that knows the layout: directory helpers, the git pathspecs landing tracks, and the classifier every reader of a repo-relative path uses (landing, L007's history walk, the at-revision loader, the base overlay).
  • Sets and roles carry the namespace of their directory; a set id is unique within a namespace, and a version names a set of its own namespace (LP-3.36, LP-5.22). Sidecars carry their namespace.
  • Writers file every change-set under the one namespace its entities belong to (author::home::namespace_of), sidecars and role and set files under theirs. declare and role declare take --namespace, inferred when the store holds one. allowed_signers is written per namespace and [SIGNERS] compares each; its derivation still reads a close from any namespace until issues 6 and 7. init scaffolds ns/. The merge driver's .gitattributes patterns follow the layout.
  • ddd migrate-ledger names the namespace of the set it declares.

Tests. Fails-before, passes-after for AC-63: store_tests::a_file_at_a_flat_path_is_a_schema_fault_and_names_the_path, a_flat_only_store_is_refused_and_nothing_of_it_is_read, a_set_id_is_unique_within_its_namespace_not_across_the_store, a_stray_file_under_ns_and_a_misnamed_namespace_directory_are_faults; unit tests in layout and author::home. The integration suites that wrote or read flat paths go through per-namespace harness helpers (PRD §3.11 item 1, done here because the loader change forces it). The committed fixtures and this repository's own store are still flat until issues 9 and 10; the tests that read them stage a byte-identical copy under ns/<namespace>/ first (common::stage_store_into), to be removed by those issues.

Protocol. §3.1 states the layout; LP-3.34, LP-3.35 (marked not implemented until issue 2), LP-3.36 and LP-5.22 are new; LP-4.10 and §§5.2, 5.3, 5.6 name the new paths; Appendix B row; Appendix C note "Spec v1.9 — one directory per namespace". No class added, no digest moves, no format number, CANONICAL_FORM stays v1.

One check is red by construction. This repository's own store is flat, so ledger verify --export on this branch refuses it (191 SCHEMA), exactly as LP-3.34 says. Any pull request that lands the refusal before the store moves is red on that step, and the store cannot move before issue 2's legacy capability exists (a move without it is 408 L007 and L009 on every acceptance). The chain is therefore issue 1 → issue 2 → issue 10, each stacked on the one before; this PR and #2's are red on that one step only, and #10's is green. cargo build, cargo t, clippy and the ddd gates pass here.

🤖 Generated with Claude Code

https://claude.ai/code/session_01GgRcHXmnAu43hChNxhnqxU


Generated by Claude Code

…commit

Issue #144 (PRD issue 1, rulings 62, 63 and 66 as amended by 87). Every
store holds each namespace under `.decisions/ns/<namespace>/`, with its
own `sets/`, `roles/`, `log/`, `sig/` and `allowed_signers`, and a file's
namespace is its directory. The loader reads only those directories; a
file at a flat path of revision v1.8, or anywhere under `.decisions/`
outside `ns/` and `index/`, is a schema fault naming the path (AC-63),
and so is a store with no `ns/` and any of those paths.

The layout is one module, `ledger_core::layout`: the directory helpers,
the git pathspecs landing tracks, and the one classifier every reader of
a repo-relative path uses (landing, the write-once history check, the
at-revision loader and the base overlay). A set and a role carry the
namespace of the directory that holds them; a set id is unique within a
namespace and a version names a set of its own namespace (LP-3.36,
LP-5.22). Sidecars carry their namespace too. The writers file every
change-set under the one namespace its entities belong to
(`author::home::namespace_of`), sidecars beside it, role files and set
files under theirs; `declare` and `role declare` take `--namespace`,
inferred when the store holds one namespace. `allowed_signers` is written
per namespace and `[SIGNERS]` compares each namespace's file; its
derivation still reads a close in any namespace, which issues 6 and 7
narrow. `init` scaffolds `ns/`. The merge driver's `.gitattributes`
patterns follow the layout.

Tests: `store_tests` gains the AC-63 cases (each flat path named, a
flat-only store refused and unread, a set id unique per namespace, a
stray file under `ns/`); `layout` and `author::home` carry their unit
tests. The integration suites that wrote or read flat paths now go
through the harness's per-namespace helpers, and the fixtures and this
repository's own store, both still flat until issues 9 and 10, are
staged under `ns/<namespace>/` by `common::stage_store_into` before a
test reads them, byte for byte. The `ddd migrate-ledger` adapter names
the namespace it declares the set in.

Protocol: section 3.1 states the layout; LP-3.34, LP-3.35 (marked not
implemented until issue 2), LP-3.36 and LP-5.22 are new; LP-4.10 and
sections 5.2, 5.3 and 5.6 name the new paths; Appendix B row; Appendix C
note "Spec v1.9 — one directory per namespace". No class added, no
digest moves, no format number, `CANONICAL_FORM` stays `v1`.

This repository's own store is still flat, so `ledger verify --export`
on this branch refuses it (191 `SCHEMA`), as LP-3.34 says; issue 10
re-lays it out, after issue 2's history capability. That is the one red
check on this pull request.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GgRcHXmnAu43hChNxhnqxU

Hafeok commented Oct 9, 2026

Copy link
Copy Markdown
Collaborator Author

CI, standing down, as the description says. The check job fails at ledger verify --export: at this commit the loader refuses the repository's own flat store (187 [SCHEMA] findings naming the flat paths, LP-3.34) and the two exports then speak namespaces the log does not. This PR is red on that step by design: the store moves in #156 (issue 10), which is green, and the series merges in order (#154 → #155 → #156). Nothing else is wrong on this step; the full suite, clippy and the quality scripts pass.

Once the store moves, the contract-surface gate (ddd diff-contracts) will also hold this PR for its exposed-surface changes (the layout module, Store::set_in, the per-namespace signers API, …), as it holds #157–#162. The remedy is ddd bind <base>..HEAD under .ddd/seams/, which the session's instructions forbid me to run; see the close-out, ledger/sessions/2026-10-namespace-layout-authority.md.


Generated by Claude Code

Files the signed bindings the contract-surface gate demands for every
exposed Rust surface this step changes — 62 events over 14 files, five of
them new declarations (layout.rs, author/home.rs, author/declare.rs, the
CLI declare args, set.rs) with their verdict_knowledge written, and three
existing declarations (store.rs, signing/mod.rs, authority/signers.rs)
whose verdict the per-namespace layout had made false, rewritten.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GgRcHXmnAu43hChNxhnqxU
Hafeok added a commit that referenced this pull request Oct 11, 2026
…ility

Issue #145 (PRD issue 2; rulings 82 and 97; AC-82). Before reading
history a verifier looks for the flat paths of revision v1.8
(`.decisions/log`, `.decisions/roles`, `.decisions/sig`) on the
first-parent line of the verified commit and, when given, the base
(`layout::flat_history`). Run without the legacy capability
(`ledger verify --no-legacy-layout`) it refuses such a repository with
exit 2, naming the first flat commit, and never reports it conformant.

With the capability, which the reference implementation has, the three
readers ruling 97 leaves to git follow a tracked file along its lineage,
its namespaced path and the flat path of the same kind and name, told
apart by path and never a commit by its layout:

- `L007`: a flat file the re-layout deleted is judged through the file
  it became, by entity, with ruling 58's `format:` comparison along the
  same lineage (`verify::history`); a flat file that went nowhere is a
  removal as before. Rename detection is off in every landing query, so
  a move reads as a delete and an add and each path classifies by itself.
- `L009`: the pickaxe names both paths, so the introducing commit is the
  original and never the move (`blame::introducing_author`).
- The base overlay: a flat base is read for the re-layout's own pull
  request; a flat change-set is homed by the namespace its entities name
  and a flat sidecar by the entity it signs (`revision`).

Landing positions read the namespaced paths only, as the session's
instruction says; that is sound because no committed store with flat
history holds an authority record, confirmed by scanning every
first-parent revision of this repository (none, and no deletion in the
flat log).

Tests (`ledger-cli/tests/legacy_layout.rs`, each failing before the
change): a flat store re-laid out in one commit by a non-acceptor
verifies conformant with blame on; an entity dropped by the move is
`L007` by entity; a flat file removed rather than moved stays `L007`; a
`format:` raised past the need across the move is `L007`; without the
capability a flat history is refused with exit 2 naming the first flat
commit, on the base too; a v1.9 history needs no capability; the overlay
reads a flat base. `layout` gains unit tests for the flat classifier,
the counterpart and the detection.

Protocol: LP-3.35 loses its not-implemented mark; LP-8.30 gains the
re-layout exception; LP-8.32 the lineage; Appendix B row; the v1.9
Appendix C note gains its history paragraph. No class added, no digest
moves.

Stacked on #154 (issue 1). This repository's own store is still flat, so
`ledger verify --export` is still refused here; #10's re-layout commit,
stacked on this, makes it green.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GgRcHXmnAu43hChNxhnqxU
The declaration over ledger-cli/tests/common/mod.rs now says what the
bound helpers are — the suites' shared harness, with no consumer outside
ledger-cli/tests/ — before what a test author learns from it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GgRcHXmnAu43hChNxhnqxU
Hafeok added a commit that referenced this pull request Oct 11, 2026
…ility

Issue #145 (PRD issue 2; rulings 82 and 97; AC-82). Before reading
history a verifier looks for the flat paths of revision v1.8
(`.decisions/log`, `.decisions/roles`, `.decisions/sig`) on the
first-parent line of the verified commit and, when given, the base
(`layout::flat_history`). Run without the legacy capability
(`ledger verify --no-legacy-layout`) it refuses such a repository with
exit 2, naming the first flat commit, and never reports it conformant.

With the capability, which the reference implementation has, the three
readers ruling 97 leaves to git follow a tracked file along its lineage,
its namespaced path and the flat path of the same kind and name, told
apart by path and never a commit by its layout:

- `L007`: a flat file the re-layout deleted is judged through the file
  it became, by entity, with ruling 58's `format:` comparison along the
  same lineage (`verify::history`); a flat file that went nowhere is a
  removal as before. Rename detection is off in every landing query, so
  a move reads as a delete and an add and each path classifies by itself.
- `L009`: the pickaxe names both paths, so the introducing commit is the
  original and never the move (`blame::introducing_author`).
- The base overlay: a flat base is read for the re-layout's own pull
  request; a flat change-set is homed by the namespace its entities name
  and a flat sidecar by the entity it signs (`revision`).

Landing positions read the namespaced paths only, as the session's
instruction says; that is sound because no committed store with flat
history holds an authority record, confirmed by scanning every
first-parent revision of this repository (none, and no deletion in the
flat log).

Tests (`ledger-cli/tests/legacy_layout.rs`, each failing before the
change): a flat store re-laid out in one commit by a non-acceptor
verifies conformant with blame on; an entity dropped by the move is
`L007` by entity; a flat file removed rather than moved stays `L007`; a
`format:` raised past the need across the move is `L007`; without the
capability a flat history is refused with exit 2 naming the first flat
commit, on the base too; a v1.9 history needs no capability; the overlay
reads a flat base. `layout` gains unit tests for the flat classifier,
the counterpart and the detection.

Protocol: LP-3.35 loses its not-implemented mark; LP-8.30 gains the
re-layout exception; LP-8.32 the lineage; Appendix B row; the v1.9
Appendix C note gains its history paragraph. No class added, no digest
moves.

Stacked on #154 (issue 1). This repository's own store is still flat, so
`ledger verify --export` is still refused here; #10's re-layout commit,
stacked on this, makes it green.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GgRcHXmnAu43hChNxhnqxU
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Load every store from ns/<ns>/; refuse flat paths at the verified commit

1 participant