8000 feat(bep): inject store values in bep serve (T67) by minimal-foundry[bot] · Pull Request #2597 · gominimal/minimal · GitHub
[go: up one dir, main page]

Skip to content

feat(bep): inject store values in bep serve (T67) - #2597

Merged
norrietaylor merged 4 commits into
mainfrom
agent/2586-inject-store-values-in-bep-serve
Oct 26, 2026
Merged

norrietaylor merged 4 commits into
mainfrom
agent/2586-inject-store-values-in-bep-serve

Conversation

@minimal-foundry
@minimal-foundry minimal-foundry Bot commented Oct 26, 2026 •
Copy link
Copy Markdown
Contributor

T67 — Inject store values in bep serve

slice: S10
kind: task
covers: BEP-032
size: M
est: 120 code, 160 tests
executor: agent
difficulty: needs care
model: strongest
diagnostics: an admitted store reference that the serve path cannot read is refused as store_item_unreadable in min box audit, never forwarded without the key
observability: one debug line per store injection naming the store and identifier, never the value
layers:
- redeem:
- crates/bep/src/redeemer.rs: BoxRedeemer overrides Redeemer::redeem_reference and returns Redeemed::Store for an admitted store member (Gatehouse §6.10 line 849, redemption step 4), with the header check still before redeem runs
- crates/bep/src/proxy.rs: the bep serve path calls Flow::with_store(Arc::new(HostStore)) where it builds each Flow
- crates/bep/src/forward.rs: the two interim notes on redeem_reference and with_store (#2586) are removed
test: cargo nextest run -p bep serve_injects_a_stored_key_for_an_admitted_store_member
produces: none
consumes: none
proof: A box's request to a store rule's registered upstream leaves bep serve with the stored key in the registered form, and the box never holds the key.
depends on:
- blocked by #2257
- blocked by #2292

Proof

A test shows a box's request to a store rule's registered upstream (api.openai.com) going through BoxRedeemer and the forwarder. The request leaves with authorization: Bearer <stored key>, and the sealed value is gone. The box holds only the sealed value. The audit record names keychain:openai and never the key. Each Flow that bep serve builds now reads values from the host store. On a host that cannot read the store, the request is refused as store_item_unreadable, and nothing is forwarded.

Notes from the agent: 1) The production path is not live end to end yet. bep serve (main.rs) still gives BoxRed 8000 eemer no store rules, and it does not admit store authorities at CONNECT. Both wait for T25 (#2280). So I added BoxRedeemer::with_rules (default: no rules), and the test uses it. main.rs is outside the layers, and I did not change it. Its interim warning about #2280 is still correct.
2) The test drives BoxRedeemer plus Flow::forward_requests with a MemoryReader store. It does not go through the TLS Proxy::serve harness, because that harness's upstream certificate and CA union cover GitHub hosts only. The proxy.rs change is one line: .with_store(Arc::new(HostStore)) where serve builds each Flow.
3) In facts(), a store member now gets the handle's upstream as the bound set and the current rule's authorities as the current set, which is what redeem.rs documents. A sign-in member keeps the module host sets.
4) redeem_reference opens the value once to learn its member kind. A non-store value outside Authorization is then refused as sealed_header_misplaced before decide, and before any sign-in read or renewal. The store member's placement check stays in the forwarder (inject_store).
5) I added a second test, serve_refuses_an_unreadable_store_member (not macOS). It covers the diagnostics line: HostStore off macOS gives store_item_unreadable in the audit. The full bep suite passed (201) after the last change, and clippy -p bep --all-targets is clean. I …[truncated]

Tests

line exit tail
cargo nextest run -p bep serve_injects_a_stored_key_for_an_admitted_store_member 0 Applying loadouts: default Running task runtime-implement-test-0 in session task-runtime-implement-test-0-f529... Compiling bep v0.0.1 (/workbench/crates/bep) Finished 'test' profile [unoptimized] target(s) in 25.56s ──────────── Nextest run ID 1f9f798f-0cf2-422b-a2b1-b43b3c83927f with nexte

Verify

min task run agent-verify passed ([tasks.verify]).

Layer exception

None needed. The merge round at bed6883 listed crates/bep/src/forward.rs, proxy.rs and redeemer.rs as outside the task's layers because it read T25's task file (its notes say so). Those three files are T67's layers in #2586, so the change stays in layer.

Residuals

Closes #2586


Generated by Claude Code

BoxRedeemer now overrides redeem_reference. An admitted store member is
given to the forwarder as Redeemed::Store, with the store, identifier and
injection form, so the forwarder reads the value per request. A store
member is judged against the handle's upstream and the current rule's
authorities. Any other value outside Authorization is still refused as
sealed_header_misplaced before it is decided.

Each flow bep serve builds now reads from the host store. The redeemer
takes its [secret-store-rules] through with_rules. bep serve passes none
until T25 reads them.
@coderabbitai
coderabbitai Bot commented Oct 26, 2026 •
Copy link
Copy Markdown
Contributor

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

Run configuration
  • Source mode: Auto
  • Repository: Unavailab 10000 le
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: d38d90d5-c1a5-42c0-aa87-4f0f79260d9b

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@minimal-foundry
minimal-foundry Bot commented Oct 26, 2026 •
Copy link
Copy Markdown
Contributor Author

Approved: no findings at a7ff760316f2.

Nothing to do.

Clobber: none seen.

@minimal-foundry minimal-foundry Bot left a comment
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minimal-review — approved

Verdict APPROVE — No findings.

Panel: 3 of 3 personas ran (correctness, security, supply-chain).

@minimal-foundry minimal-foundry Bot added the review:approved minimal-review approved the current head label Oct 26, 2026
@minimal-arch minimal-arch Bot left a comment
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

arch-review: PASS · the full ruling

The change conforms to Gatehouse §6.10 line 849 step 4. The redeemer decides a store member against the handle's upstream and the current rule. The forwarder checks placement before it reads the store, and the audit names store:id and never the value. The read happens in the BEP process for each request, as lines 831 and 844 require. No store member is admitted in production until T25 (#2280) wires with_rules in main.rs. That issue is the filed residual, and it also owns the proof through Proxy::serve.

Ruled at 90e36f4 against gominimal/arch@109541a48c31 by claude-opus-5-5.

@norrietaylor norrietaylor left a comment
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

8000

Own review at 90e36f4: the override keeps the header check ahead of the sign-in decision and decides a store member before it, the bound and current sets for a store member come from the handle and its rule, and the forwarder reads the value per request. The serve path still never gives the redeemer any [secret-store-rules], so BEP-032 is not reached end to end. That gap and the interim notes that still name closed #2280 are filed as residual #2599. Merging with the residual filed.


Generated by Claude Code

Copy link
Copy Markdown
Member

/revise

Round on #2597 after a merge conflict at 90e36f4. No round is in flight. #2583 (T33) landed on main and changed the facts doc in crates/bep/src/redeemer.rs, so it now conflicts with this PR's edit of the same paragraph.

  1. Merge main into this branch.
  2. Resolve the facts doc as main's revocation sentence followed by this PR's store paragraph:
  3. Change no other behaviour. Run cargo nextest run -p bep serve_injects_a_stored_key_for_an_admitted_store_member and clippy on bep with --all-targets.

Generated by Claude Code

@minimal-foundry
Copy link
Copy Markdown
Contributor Author

That /revise is held, not dropped. The container platform had no instance to give the coder: its pool of prepared containers was full, which happens most just after a deploy. Your note is kept and asked again every 10 minutes for up to 30; a wait that outlives that is refused here with the reason.

What the platform said

could not start the coder: Error: there is no container instance that can be provided to this durable object

Nothing to type again: the command gets a rocket when its round starts, or a refusal that names the reason. No round was counted for it yet.

Resolve the facts doc in crates/bep/src/redeemer.rs: keep the restored
revocations sentence from main (T33) and this branch's store paragraph,
which now points at #2599.
@minimal-foundry
Copy link
Copy Markdown
Contributor Author

A merge of main before round 1, not counted against the cap (1 of 3), pushed as bed6883d7578.

Resolved conflicts in: crates/bep/src/redeemer.rs

line exit tail
cargo nextest run -p boxes store_rule_in_deny_set_is_refused 0 Applying loadouts: default Running task runtime-implement-test-0 in session task-runtime-implement-test-0-89ba... Compiling args v0.0.1 (/workbench/crates/args) Compiling ot v0.0.1 (/workbench/crates/ot) Compiling paths v0.0.1 (/workbench/crates/paths) Compiling common v0.0.1 (/workbench
cargo nextest run -p boxes store_rule_naming_sign_in_item_is_refused 0 Applying loadouts: default Running task runtime-implement-test-1 in session task-runtime-implement-test-1-b687... Finished 'test' profile [unoptimized] target(s) in 0.33s ──────────── Nextest run ID 51daf21d-d95c-4576-879a-9a147f58282d with nextest profile: default Starting 1 test across 3
cargo nextest run -p boxes ask_rule_without_tty_denies 0 Applying loadouts: default Running task runtime-implement-test-2 in session task-runtime-implement-test-2-8ffd... Finished 'test' profile [unoptimized] target(s) in 0.34s ──────────── Nextest run ID fa226767-55cc-41fb-8156-fafd624bfe18 with nextest profile: default Starting 1 test across 3
cargo nextest run -p boxes prop_store_upstream_outside_egress_is_exit_3 0 Applying loadouts: default Running task runtime-implement-test-3 in session task-runtime-implement-test-3-7e33... Finished 'test' profile [unoptimized] target(s) in 0.35s ──────────── Nextest run ID be3c7205-6f29-4763-b1cd-65d1c6478c73 with nextest profile: default Starting 1 test across 3
cargo nextest run -p boxes project_store_rules_are_ignored_with_warning 0 Applying loadouts: default Running task runtime-implement-test-4 in session task-runtime-implement-test-4-febe... Finished 'test' profile [unoptimized] target(s) in 0.37s ──────────── Nextest run ID 4e35a4bf-002a-49bb-b952-fa4d076b9f5e with nextest profile: default Starting 1 test across 3

Verify min task run agent-verify passed.

Outside the task's layers::

  • crates/bep/src/forward.rs
  • crates/bep/src/proxy.rs
  • crates/bep/src/redeemer.rs

Converted to a draft: something above needs a person before review.

The branch now merges main cleanly. The facts doc in crates/bep/src/redeemer.rs keeps main's sentence about restored revocations (BEP-068) and this branch's store paragraph, which now points at #2599. A store rule aimed at a GitHub host or the Host header is still refused by name when the configuration is read, and the boxes tests pin that.

Notes from the agent: This was a conflict round only. I merged origin/main and resolved the one marker in crates/bep/src/redeemer.rs as the directive asked. I dropped the 'empty at start until T33 (#2290)' sentence, kept main's with_revocations sentence, and pointed the store paragraph at #2599 in place of #2280. I changed no behaviour. The other merged paths (Cargo.lock, audit.rs, main.rs, revoke.rs, store.rs, box_audit.rs, secret.rs, minvmd) came from main and merged without conflict. The PR branch is T67, and task.md holds T25. I ran the T25 boxes test lines too, and all of them pass.

@minimal-foundry
minimal-foundry Bot marked this pull request as draft October 26, 2026 05:30
@minimal-arch minimal-arch Bot left a comment
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

arch-review: PASS · the full ruling

The compare is a merge of main. It changes only doc comments in this PR's files. The PR's code is the same as on 90e36f4, so the PASS on that head stands. BEP-032 conforms to Gatehouse §6.10 line 849. The store rules in bep serve stay open as residual #2599.

Ruled at bed6883 against gominimal/arch@109541a48c31 by claude-opus-5-5.

@minimal-foundry minimal-foundry Bot removed the review:approved minimal-review approved the current head label Oct 26, 2026
@norrietaylor
norrietaylor marked this pull request as ready for review October 26, 2026 07:27
@minimal-foundry minimal-foundry Bot added the review:approved minimal-review approved the current head label Oct 26, 2026
…re-values-in-bep-serve

# Conflicts:
#	crates/bep/src/forward.rs
#	crates/bep/src/redeemer.rs
@minimal-foundry
Copy link
Copy Markdown
Contributor Author

A merge of main before round 1, not counted against the cap (2 of 3), pushed as a7ff760316f2.

Resolved conflicts in: crates/bep/src/forward.rs, crates/bep/src/redeemer.rs

line exit tail
cargo nextest run -p boxes store_rule_in_deny_set_is_refused 0 Applying loadouts: default Running task runtime-implement-test-0 in session task-runtime-implement-test-0-f221... Compiling args v0.0.1 (/workbench/crates/args) Compiling ot v0.0.1 (/workbench/crates/ot) Compiling paths v0.0.1 (/workbench/crates/paths) Compiling common v0.0.1 (/workbench
cargo nextest run -p boxes store_rule_naming_sign_in_item_is_refused 0 Applying loadouts: default Running task runtime-implement-test-1 in session task-runtime-implement-test-1-c62d... Finished 'test' profile [unoptimized] target(s) in 0.31s ──────────── Nextest run ID 85d3275a-a2d9-4286-bb4e-c309fddcd9b8 with nextest profile: default Starting 1 test across 3
cargo nextest run -p boxes ask_rule_without_tty_denies 0 Applying loadouts: default Running task runtime-implement-test-2 in session task-runtime-implement-test-2-7ffe... Finished 'test' profile [unoptimized] target(s) in 0.32s ──────────── Nextest run ID cb4ca686-73c4-4ec2-8b03-4fdc3a9af292 with nextest profile: default Starting 1 test across 3
cargo nextest run -p boxes prop_store_upstream_outside_egress_is_exit_3 0 Applying loadouts: default Running task runtime-implement-test-3 in session task-runtime-implement-test-3-15a7... Finished 'test' profile [unoptimized] target(s) in 0.32s ──────────── Nextest run ID 2bacdb5b-b526-4187-b4c9-0cfccd384aab with nextest profile: default Starting 1 test across 3
cargo nextest run -p boxes project_store_rules_are_ignored_with_warning 0 Applying loadouts: default Running task runtime-implement-test-4 in session task-runtime-implement-test-4-8447... Finished 'test' profile [unoptimized] target(s) in 0.33s ──────────── Nextest run ID 7ccbe878-4c39-416f-a7e7-e80244ee78fd with nextest profile: default Starting 1 test across 3

Verify min task run agent-verify passed.

Outside the task's layers::

  • crates/bep/src/forward.rs
  • crates/bep/src/proxy.rs
  • crates/bep/src/redeemer.rs

Converted to a draft: something above needs a person before review.

A store rule aimed at a GitHub host or the Host header is refused by name when the configuration is read. The tests that pin this pass at the branch head after the merge with main.

Notes from the agent: This round resolved the merge conflict with main only. The conflicts were in crates/bep/src/forward.rs and crates/bep/src/redeemer.rs. The branch adds store references (Facts.kind, the BoxRedeemer::redeem_reference override, store_decision). Main adds the handle jti for the audit record (Facts.jti, redeem_with_jti, a redeem_reference return type of (Redeemed, String)). The resolution keeps both. BoxRedeemer::redeem_reference now returns (Redeemed, String) and gives the jti for store and sign-in decisions. A misplaced sealed header gives an empty jti, as the trait default on main does. Main had an 'Interim' doc note on Redeemer::redeem_reference about #2586. I removed it, because this branch is the change that the note waits for. cargo clippy -p bep --all-targets is clean, and cargo nextest run -p bep passes 213 tests. The task.md for this round describes T25, but this branch is the T67 branch (inject store values in bep serve). The T25 tests already exist on main, and they pass here. The merge commit touches no file outside crates/bep. The merged-in files from main are not edits of this round.

@minimal-foundry
minimal-foundry Bot marked this pull request as draft October 26, 2026 08:36
@minimal-arch minimal-arch Bot left a comment
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

arch-review: PASS · the full ruling

The compare to this head is two merges of main. The store path in redeemer.rs now carries the handle jti, and it keeps the same placement as before. Gatehouse §6.10 lines 844 and 849 still decide the change, and BEP-032 conforms. The end-to-end wiring of [secret-store-rules] in bep serve stays open as #2599.

Ruled at a7ff760 against gominimal/arch@109541a48c31 by claude-opus-5-5.

@norrietaylor
norrietaylor marked this pull request as ready for review October 26, 2026 08:37
@norrietaylor norrietaylor left a comment
8000
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Own review at a7ff760. The merge with #2596 keeps both changes. BoxRedeemer::redeem_reference returns (Redeemed, String) and gives the handle jti for store and sign-in decisions. A misplaced sealed header gives an empty jti, as the trait default on main does. The header check still comes before a sign-in decision. Residual #2599 holds the bep serve store-rule wiring.


Generated by Claude Code

@norrietaylor norrietaylor changed the title T67 — Inject store values in bep serve feat(bep): inject store values in bep serve (T67) Oct 26, 2026
@norrietaylor norrietaylor left a comment
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Babysitter approval at a7ff760: every merge gate passes at this head (arch PASS at a7ff760, zero open threads, every lane aggregator green). Squash title feat(bep): inject store values in bep serve (T67) and the squashed message pass commitlint. Queued for squash merge.


Generated by Claude Code

@norrietaylor
norrietaylor added this pull request to the merge queue Oct 26, 2026
Merged via the queue into main with commit 5a93a07 A016 Oct 26, 2026
37 checks passed
@norrietaylor
norrietaylor deleted the agent/2586-inject-store-values-in-bep-serve branch October 26, 2026 09:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

review:approved minimal-review approved the current head

Projects

None yet

Development

Successfully merging this pull request may close these issues.

T67 — Inject store values in bep serve T25 — Read client-owned store rules and refuse rules in the deny set

1 participant

0