Skip to content

allowed_signers per namespace; remove a stale file (issue 7) - #161

Open
Hafeok wants to merge 3 commits into
claude/great-feynman-zcdsdd-step-06-keysfrom
claude/great-feynman-zcdsdd-step-07-signers
Open

Hafeok wants to merge 3 commits into
claude/great-feynman-zcdsdd-step-06-keysfrom
claude/great-feynman-zcdsdd-step-07-signers

Conversation

@Hafeok

@Hafeok Hafeok commented Oct 9, 2026

Copy link
Copy Markdown
Collaborator

Closes #150 — PRD ledger/prd/namespace-independence-prd.md §6 issue 7 (§3.4; ruling 47).

Stacked on #160 (issue 6). Review the last commit alone, 9df8605e.

What lands

Each namespace's ns/<ns>/allowed_signers is derived from that namespace's trusted bindings alone — a line ended by a close in that namespace only, as issue 6 made the derivation read — and a namespace that binds nothing has no file. signers::write now removes a file committed in a namespace none of whose bindings is trusted (inventory item N10) and reports what it wrote and removed per namespace; ledger identity sync, the identity verbs and init --namespace print those lines, and sync says when no namespace binds a key. [SIGNERS] already compared each namespace's file with its own derivation (issue 1); its protocol line now says so.

Tests

ledger-cli/tests/signers_per_namespace.rs: each namespace has its own file holding its own ledger-accept@<ns> lines; a close in A leaves B's file byte-identical; a file hand-written in a namespace that binds nothing fails [SIGNERS] naming the namespace, and identity sync removes it, prints the removal, and the store verifies again (failing before: the file was left in place); a namespace whose only binding is untrusted has no file after sync.

Protocol

LP-4.10 loses its note and gains the removal; LP-4.33 names the namespace; Appendix B row; Appendix C note "A stale allowed_signers is removed; a close reaches its own namespace's file only". No class added; no digest moves (a derived file is never hashed or signed).

Checks

cargo build, cargo t, cargo clippy --workspace -- -D warnings -D clippy::unwrap_used, the quality scripts, and ledger verify --export on this repository (same output as on main).

🤖 Generated with Claude Code

https://claude.ai/code/session_01GgRcHXmnAu43hChNxhnqxU


Generated by Claude Code

Hafeok commented Oct 9, 2026

Copy link
Copy Markdown
Collaborator Author

CI, standing down on one step. The check job fails at the contract-surface gate (ddd diff-contracts <base>..HEAD): 6 undischarged exposed-surface changes, all this PR's — signers::write re-signed and the new Synced struct with its fields and lines. Every other step of check passed.

The remedy the gate names is ddd bind claude/great-feynman-zcdsdd-step-06-keys..HEAD (with --verdict), which files seam declarations under .ddd/seams/. The session's instructions forbid me to edit .ddd/, and a declaration's verdict is the author's judgment, so I am not filing them. Please run ddd bind on this branch and push, or tell me to. Recorded in the close-out.


Generated by Claude Code

@Hafeok
Hafeok force-pushed the claude/great-feynman-zcdsdd-step-06-keys branch from 406b17d to 792983a Compare October 11, 2026 06:18
@Hafeok
Hafeok force-pushed the claude/great-feynman-zcdsdd-step-07-signers branch from 9df8605 to 111f4f6 Compare October 11, 2026 06:19
Hafeok added a commit that referenced this pull request Oct 11, 2026
…e invocation

Issue #151 (PRD issue 8, §3.2, §3.3; rulings 47 and 69; AC-47 third
bullet). `ledger identity revoke|rotate <binding> --everywhere` closes
the key in every namespace its principal holds it open in: one
change-set per namespace, each the same act closing that namespace's
binding with the same `at`, signed in its own namespace, filed namespace
by namespace and gated as it lands, naming every file written, to land
in one commit (LP-6.34). Without the flag a close ends the key in the
namespace of the binding it names, as before, and the split is a notice.
A key already closed everywhere is refused with nothing to close.

The other half of this issue — the writer opening every namespace on its
own genesis, roles, first policy and self-bound binding, `join_genesis`
gone, `--external-ref` required every time — landed with issues 5 and 6,
for the reason their commits give; the `genesis_key.rs` rewrites §3.11
lists landed with issue 6. `--without-key` stays until issue 13.

Tests (each failing before the change): `key_across_namespaces.rs` —
a revoke everywhere files one change-set in A and one in B, both closes
with one `at`, each naming its namespace's binding, named in the verb's
output, landing in one commit; `verify` is conformant with no split
notice and both `allowed_signers` lines end; closed everywhere, a second
`--everywhere` is refused; a rotate everywhere closes the key and binds
the new one in each namespace, the new key signs in B and the old one
does not; and the carried test now drives `--everywhere` too: no agent
identity and no non-interactive session produces a key close.

Also: `signers_per_namespace.rs` (issue 7) pauses a second after opening
its two namespaces, as its sibling key tests do — a close in the same
second as the policies it closes under sat at their second for
`ssh-keygen`, and the test was flaky.

Protocol: LP-6.34 (new), LP-6.32 loses its note; Appendix B row; no
Appendix C note (the issue row says none). CLAUDE.md updated. No class
added; no digest moves.

Stacked on #161 (issue 7).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GgRcHXmnAu43hChNxhnqxU
Hafeok and others added 2 commits October 11, 2026 06:22
Issue #150 (PRD issue 7, §3.4; ruling 47). Each namespace's
`ns/<ns>/allowed_signers` is derived from that namespace's trusted
bindings alone — a line ended by a close in that namespace only, as
issue 6 made the derivation read — and a namespace that binds nothing
has no file. `signers::write` now removes a file committed in a
namespace none of whose bindings is trusted (inventory item N10) and
reports what it wrote and removed per namespace (`Synced`); `ledger
identity sync`, the identity verbs and `init --namespace` print those
lines, and `sync` says when no namespace binds a key. `[SIGNERS]`
already compared each namespace's file with its own derivation (issue
1); its protocol line now says so.

Tests (each failing before the change where the behaviour is new):
`ledger-cli/tests/signers_per_namespace.rs` — each namespace has its own
file holding its own `ledger-accept@<ns>` lines; a close in A leaves B's
file byte-identical; a file hand-written in a namespace that binds
nothing fails `[SIGNERS]` naming the namespace, and `identity sync`
removes it, prints the removal, and the store verifies again; a
namespace whose only binding is untrusted has no file after `sync`.

Protocol: LP-4.10 loses its note and gains the removal; LP-4.33 names
the namespace; Appendix B row; Appendix C note "A stale `allowed_signers`
is removed". No class added; no digest moves.

Stacked on #160 (issue 6).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GgRcHXmnAu43hChNxhnqxU
Files the signed bindings the contract-surface gate demands for this
step's six exposed Rust surface changes, all in authority/signers.rs:
the declaration is amended with the bindings and its verdict extended
with what write now reports and removes.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GgRcHXmnAu43hChNxhnqxU
@Hafeok
Hafeok force-pushed the claude/great-feynman-zcdsdd-step-06-keys branch from 792983a to 53becab Compare October 11, 2026 06:22
@Hafeok
Hafeok force-pushed the claude/great-feynman-zcdsdd-step-07-signers branch from 111f4f6 to 3cdc118 Compare October 11, 2026 06:22
Hafeok added a commit that referenced this pull request Oct 11, 2026
…e invocation

Issue #151 (PRD issue 8, §3.2, §3.3; rulings 47 and 69; AC-47 third
bullet). `ledger identity revoke|rotate <binding> --everywhere` closes
the key in every namespace its principal holds it open in: one
change-set per namespace, each the same act closing that namespace's
binding with the same `at`, signed in its own namespace, filed namespace
by namespace and gated as it lands, naming every file written, to land
in one commit (LP-6.34). Without the flag a close ends the key in the
namespace of the binding it names, as before, and the split is a notice.
A key already closed everywhere is refused with nothing to close.

The other half of this issue — the writer opening every namespace on its
own genesis, roles, first policy and self-bound binding, `join_genesis`
gone, `--external-ref` required every time — landed with issues 5 and 6,
for the reason their commits give; the `genesis_key.rs` rewrites §3.11
lists landed with issue 6. `--without-key` stays until issue 13.

Tests (each failing before the change): `key_across_namespaces.rs` —
a revoke everywhere files one change-set in A and one in B, both closes
with one `at`, each naming its namespace's binding, named in the verb's
output, landing in one commit; `verify` is conformant with no split
notice and both `allowed_signers` lines end; closed everywhere, a second
`--everywhere` is refused; a rotate everywhere closes the key and binds
the new one in each namespace, the new key signs in B and the old one
does not; and the carried test now drives `--everywhere` too: no agent
identity and no non-interactive session produces a key close.

Also: `signers_per_namespace.rs` (issue 7) pauses a second after opening
its two namespaces, as its sibling key tests do — a close in the same
second as the policies it closes under sat at their second for
`ssh-keygen`, and the test was flaky.

Protocol: LP-6.34 (new), LP-6.32 loses its note; Appendix B row; no
Appendix C note (the issue row says none). CLAUDE.md updated. No class
added; no digest moves.

Stacked on #161 (issue 7).

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

`ssh-keygen` reads validity windows at second granularity, so a close
filed in the same second as the policies it is judged under fails L011
("Could not verify signature"), which `a_close_in_another_namespace_does_
not_reach_the_file` did once in CI. The same pause step 8 added to this
harness, ported here so this step is green on its own; it no-ops when
step 8 lands.

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
…e invocation

Issue #151 (PRD issue 8, §3.2, §3.3; rulings 47 and 69; AC-47 third
bullet). `ledger identity revoke|rotate <binding> --everywhere` closes
the key in every namespace its principal holds it open in: one
change-set per namespace, each the same act closing that namespace's
binding with the same `at`, signed in its own namespace, filed namespace
by namespace and gated as it lands, naming every file written, to land
in one commit (LP-6.34). Without the flag a close ends the key in the
namespace of the binding it names, as before, and the split is a notice.
A key already closed everywhere is refused with nothing to close.

The other half of this issue — the writer opening every namespace on its
own genesis, roles, first policy and self-bound binding, `join_genesis`
gone, `--external-ref` required every time — landed with issues 5 and 6,
for the reason their commits give; the `genesis_key.rs` rewrites §3.11
lists landed with issue 6. `--without-key` stays until issue 13.

Tests (each failing before the change): `key_across_namespaces.rs` —
a revoke everywhere files one change-set in A and one in B, both closes
with one `at`, each naming its namespace's binding, named in the verb's
output, landing in one commit; `verify` is conformant with no split
notice and both `allowed_signers` lines end; closed everywhere, a second
`--everywhere` is refused; a rotate everywhere closes the key and binds
the new one in each namespace, the new key signs in B and the old one
does not; and the carried test now drives `--everywhere` too: no agent
identity and no non-interactive session produces a key close.

Also: `signers_per_namespace.rs` (issue 7) pauses a second after opening
its two namespaces, as its sibling key tests do — a close in the same
second as the policies it closes under sat at their second for
`ssh-keygen`, and the test was flaky.

Protocol: LP-6.34 (new), LP-6.32 loses its note; Appendix B row; no
Appendix C note (the issue row says none). CLAUDE.md updated. No class
added; no digest moves.

Stacked on #161 (issue 7).

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.

1 participant