Repository navigation
feat(bep): carry a store handle sealed as a store member kind (T60) - #2568
norrietaylor merged 1 commit into
Conversation
MemberKind gains Store, wire name "store", so a store handle travels
sealed as {kind: "store", jws}. read_opened maps a store member to a
store handle, which verifies under a registered client key and resolves
to the store reference it names (BEP-063). Tests prove the round trip
and the refusal under an unregistered key.
|
Important Review skippedBot user detected. To trigger a single review, invoke the
|
|
Round 1 of 10 on a failed check suite: the coder changed nothing. Revise round 1 is for a failed macOS |
|
Approved: no findings at Nothing to do. Verdict APPROVE, posted as a comment: the App cannot review its own pull request; the check and the label carry it. Clobber: none seen. |
There was a problem hiding this comment.
arch-review: PASS_WITH_CONDITIONS · 1 condition · the full ruling
The seal layer of BEP-063 conforms to Gatehouse §6.10 line 842. A store handle now travels as a store member, and the existing store-handle checks verify it in the order the design gives. One gap remains. Line 842 makes jti the audit correlation id, but the audit record has no jti, and the PR body says that it does. C1 corrects the body and files that edit as a residual. The PR can merge with C1 open after its issue exists.
Ruled at 7203255 against gominimal/arch@109541a48c31 by claude-opus-5-5.
There was a problem hiding this comment.
Babysitter approval at 7203255: every merge gate passes at this head (arch PASS at 7203255, zero open threads, every lane aggregator green). Squash title feat(bep): carry a store handle sealed as a store member kind (T60) and the squashed message pass commitlint. Queued for squash merge.
Generated by Claude Code
T60 — Carry a store handle sealed as a store member kind
slice: S9
kind: task
covers: BEP-063
size: M
est: 140 code, 160 tests
executor: agent
difficulty: needs care
model: standard
diagnostics:
min box audit <box>shows a redemption of a store member with its store reference, and a store member whose handle fails verification as a refusalobservability: one debug line per store member redeemed naming the store reference, never the value
layers:
- seal:
- crates/bep/src/seal.rs:
MemberKindgainsStore(serdestore), so a store handle travels sealed as{kind: "store", jws}- crates/bep/src/redeem.rs: a store member's handle is verified against the registered client key and resolved to the store reference it names
test: cargo nextest run -p bep a_store_member_round_trips_sealed
test: cargo nextest run -p bep a_store_handle_with_an_unregistered_key_is_refused
produces: none
consumes: none
proof: A store handle sealed as a store member round-trips through the envelope, redeems against the registered client key, and is refused under an unregistered one.
depends on:
- blocked by T27
- assumes OQ3
Proof
A store handle sealed as a
storemember goes through seal and open unchanged. Its handle verifies under the registered client key and resolves tokeychain:anthropic, and decide admits the redemption. The same member under an empty registry or an unregistered key is refused asstore_handle_invalid, and the refusal still names the store reference.Notes from the agent: Out of layers: crates/bep/src/handle.rs. The match in read_opened over MemberKind is exhaustive, so the new Store variant does not compile without the arm
MemberKind::Store => HandleKind::Store. I also updated its doc comment. That arm is also the place where a store member's handle is verified and resolved. The store path in handle::read already existed, so redeem.rs got its module doc and the two tests only. Observability: handle::read already logs one debug linestore handle checkedper member read, with the store and the identifier and never the value or the signature, so I added no new log line. Only the identifier reaches the audit record today; thejtidoes not (residual #2576). The full bep suite passed (158 tests). Clippy and fmt for bep are clean. I did not run just clippy-strict.Tests
cargo nextest run -p bep a_store_member_round_trips_sealedcargo nextest run -p bep a_store_handle_with_an_unregistered_key_is_refusedVerify
min task run agent-verifypassed ([tasks.verify]).Layer exception
The epic owner's rule accepts out-of-layer changes a task needs. The babysitter accepted this one on 2026-10-25:
crates/bep/src/handle.rs:read_openedmatchesMemberKindexhaustively, so the newStorekind needs its arm mapping toHandleKind::Store.Residuals
Recordgains the handle'sjti, filled fromhandle::Read::jtithroughFactsinredeemer.rs(Gatehouse §6.10 line 842).Out of scope
These files are outside the task's
layers:, so this PR is a draft:crates/bep/src/handle.rsCloses #2540
Generated by Claude Code