8000 feat(minimal): store, list and remove secrets with min secret (T26) by minimal-foundry[bot] · Pull Request #2522 · gominimal/minimal · GitHub
[go: up one dir, main page]

Skip to content

feat(minimal): store, list and remove secrets with min secret (T26) - #2522

Merged
norrietaylor merged 18 commits into
mainfrom
agent/2287-store-list-and-remove-secrets-with-min-secret-un
Oct 25, 2026
Merged

norrietaylor merged 18 commits into
mainfrom
agent/2287-store-list-and-remove-secrets-with-min-secret-un

Conversation

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

T26 — Store, list and remove secrets with min secret under proxy-only access

slice: S3
kind: task
covers: BEP-050, BEP-051, BEP-052, BEP-053
size: L
est: 380 code, 480 tests
executor: agent
difficulty: needs care
model: strongest
diagnostics: min secret set <id> <value> is refused with "min secret set reads the value from the terminal or standard input, never from an argument or an environment flag." on stderr, pinned by secret_set_refuses_value_argument_and_env_flag; min secret list shows store, authorities, injection form, consent rule and whether the proxy's access entry is present, never a value
observability: one info log line per set and remove naming the store and the identifier, never the value
layers:
- cli:
- crates/minimal/src/cli.rs: min secret set | list | rm [--store <s>]
- crates/minimal/src/cmd/mod.rs: dispatch and module line
- crates/minimal/src/cmd/secret.rs (new): set, list, rm per BEP-050, BEP-052 and BEP-053
test: cargo nextest run -p minimal secret_set_stores_in_keychain_and_prints_id_only
test: cargo nextest run -p minimal secret_set_refuses_value_argument_and_env_flag
test: cargo nextest run -p minimal secret_set_without_tty_or_stdin_fails_immediately
test: cargo nextest run -p minimal secret_set_refuses_gatehouse_store
test: cargo nextest run -p minimal secret_list_shows_metadata_without_values
test: cargo nextest run -p minimal secret_rm_removes_item
- store:
- crates/bep/src/store.rs (new): Keychain store items with the BEP-051 access control
- crates/bep/src/lib.rs: module line
test: cargo nextest run -p minimal secret_item_acl_admits_proxy_only
test: cargo nextest run -p minimal secret_set_refuses_when_proxy_binary_absent
produces:
- crates/bep/src/store.rs
consumes: none
proof: min secret set claude prints only the identifier, and min secret list shows its metadata and no value.
depends on:
- blocked by #2280

Proof

min secret set claude reads the value from the terminal (no echo) or from piped standard input, stores it in the macOS Keychain under service dev.minimal.secret with the bep proxy as the only trusted application, and prints only claude. min secret list prints, for each secret, its store, the upstream and injection form of its [secret-store-rules] rule, the consent action or none, and whether the proxy reads it without a prompt. It prints no value. On this Linux box the proof comes from unit tests against an in-memory store. Nobody ran the real Keychain path.

Notes from the agent: The macOS Keychain backend in bep::store (security -i with add-generic-password -T -X , delete-generic-password, and a parser for security dump-keychain -a that reads each item's access-control entries) is not run on a Mac. Only its command line and the dump parser are tested, from the minimal tests on Linux. Before the proof is final, run min secret set and min secret list on a Mac. Check that dump-keychain -a asks for no access, and that its output format matches parse_dump. On hosts other than macOS, HostStore refuses every operation: the spec says the Linux native store waits on the store roster. The proxy path is MINVMD_BEP_BIN or bep beside min. That mirrors resolve_bep_binary in crates/minvmd/src/cmd/run.rs, which is outside this task's layers, so the two copies can drift. A value given as an argument, or through the hidden --env/--from-env flags, is refused with the exact text the task pins. That text states the accepted sources but names no command to run. I kept it as written. Identifiers are limited to letters, digits, '.', '_' and '-' (at most 128 characters, not starting with '-'), so they need no quoting on the security command line. min secret rm of an absent name exits non-zero. A follow-on task needs this: the proxy's per-request read (BEP-033) must read service dev.minimal.secret with account . BEP-079 rule flags (--upstrea…[truncated]

Tests

line exit tail
cargo nextest run -p minimal secret_set_stores_in_keychain_and_prints_id_only 0 Applying loadouts: default Running task runtime-implement-test-0 in session task-runtime-implement-test-0-5a11... Compiling ot v0.0.1 (/workbench/crates/ot) Compiling args v0.0.1 (/workbench/crates/args) Compiling paths v0.0.1 (/workbench/crates/paths) Compiling stdlib v0.0.22 (/workbenc
cargo nextest run -p minimal secret_set_refuses_value_argument_and_env_flag 0 Applying loadouts: default Running task runtime-implement-test-1 in session task-runtime-implement-test-1-4302... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.
cargo nextest run -p minimal secret_set_without_tty_or_stdin_fails_immediately 0 Applying loadouts: default Running task runtime-implement-test-2 in session task-runtime-implement-test-2-8818... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.
cargo nextest run -p minimal secret_set_refuses_gatehouse_store 0 Applying loadouts: default Running task runtime-implement-test-3 in session task-runtime-implement-test-3-9c54... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.
cargo nextest run -p minimal secret_list_shows_metadata_without_values 0 Applying loadouts: default Running task runtime-implement-test-4 in session task-runtime-implement-test-4-418b... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.
cargo nextest run -p minimal secret_rm_removes_item 0 Applying loadouts: default Running task runtime-implement-test-5 in session task-runtime-implement-test-5-6f40... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.
cargo nextest run -p minimal secret_item_acl_admits_proxy_only 0 Applying loadouts: default Running task runtime-implement-test-6 in session task-runtime-implement-test-6-c1e9... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.
cargo nextest run -p minimal secret_set_refuses_when_proxy_binary_absent 0 Applying loadouts: default Running task runtime-implement-test-7 in session task-runtime-implement-test-7-cb2a... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.

Verify

min task run agent-verify exited 101 under rustc 1.98.1, which the repository does not pin (1.97.0 in rust-toolchain.toml); the PR is not a draft on that alone — CI, which honours the pin, is the gate.

the sandbox ran rustc (1.98.1), the repository pins 1.97.0 in rust-toolchain.toml; a failure here may be the newer toolchain's, not this change's
Applying loadouts: default
Running task runtime-implement-verify in session task-runtime-implement-verify-5d86...
    Checking rustls-webpki v0.103.16
    Checking ot v0.0.1 (/workbench/crates/ot)
    Checking args v0.0.1 (/workbench/crates/args)
    Checking paths v0.0.1 (/workbench/crates/paths)
   Compiling stdlib v0.0.22 (/workbench/crates/stdlib)
   Compiling version v0.8.0 (/workbench/crates/version)
    Checking rustls v0.23.46
    Checking switch v0.0.1 (/workbench/crates/switch)
   Compiling minvmd v0.8.0 (/workbench/crates/minvmd)
    Checking diagnostics v0.0.1 (/workbench/crates/diagnostics)
    Checking async-dialog v0.0.1 (/workbench/crates/async-dialog)
    Checking tokio-rustls v0.26.5
    Checking rustls-platform-verifier v0.7.0
    Checking wait-timeout v0.2.1
    Checking hyper-rustls v0.27.9
    Checking tonic v0.14.6
    Checking bep v0.0.1 (/workbench/crates/bep)
    Checking rusty-fork v0.3.1
    Checking reqwest v0.13.5
    Checking proptest v1.12.0
    Checking tonic-prost v0.14.6
    Checking google-cloud-auth v1.17.0
    Checking opentelemetry-http v0.33.1
    Checking opentelemetry-otlp v0.33.0
    Checking mlog v0.0.1 (/workbench/crates/mlog)
    Checking google-cloud-gax-internal v0.7.20
    Checking google-cloud-longrunning v1.14.0
    Checking google-cloud-lro v1.11.0
    Checking google-cloud-iam-v1 v1.13.0
    Checking google-cloud-storage v1.20.0
    Checking common v0.0.1 (/workbench/crates/common)
    Checking boxes v0.0.1 (/workbench/crates/boxes)
    Checking sandbox v0.0.1 (/workbench/crates/sandbox)
    Checking mfile v0.0.1 (/workbench/crates/mfile)
    Checking minimald-rpc v0.0.1 (/workbench/crates/minimald-rpc)
    Checking decode v0.0.1 (/workbench/crates/decode)
    Checking checkouts v0.0.1 (/workbench/crates/checkouts)
    Checking graph v0.0.1 (/workbench/crates/graph)
error: using `chunks_exact` with a constant chunk size
   --> crates/minimald-rpc/src/trace.rs:199:46
    |
199 |     for (byte, pair) in out.iter_mut().zip(s.chunks_exact(2)) {
    |                                              ^^^^^^^^^^^^^^^
    |
help: consider using `as_chunks::<2>()` instead
   --> crates/minimald-rpc/src/trace.rs:199:46
    |
199 |     for (byte, pair) in out.iter_mut().zip(s.chunks_exact(2)) {
    |                                              ^^^^^^^^^^^^^^^
    = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.98.0/index.html#chunks_exact_to_as_chunks
    = note: `-D clippy::chunks-exact-to-as-chunks` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::chunks_exact_to_as_chunks)]`

error: could not compile `minimald-rpc` (lib) due to 1 previous error
warning: build failed, waiting for other jobs to finish...

Residuals

Closes #2287


Generated by Claude Code

Each item is a generic password under dev.minimal.secret whose access
control
8000
 trusts only the proxy binary (BEP-051). Hosts other than macOS
refuse until a native store lands.
set reads the value from the terminal or standard input and prints only
the identifier. list prints store, rule, consent and proxy access, and
no value (BEP-050, BEP-052, BEP-053).
@coderabbitai
coderabbitai Bot commented Oct 25, 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: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 851e0b02-8754-4f86-92c9-9247b6bc8d0b

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 25, 2026 •
Copy link
Copy Markdown
Contributor Author

Approved: every review thread resolved at eb953d7e6be8.

@norrietaylor resolved the last thread, which releases the approval this review had withheld.

Nothing to do.

@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 — advisory review

Verdict COMMENT — 3 findings, 3 inline.

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

Comment thread crates/minimal/src/cmd/secret.rs Resolved
Comment thread crates/bep/src/store.rs Resolved
Comment thread crates/bep/src/store.rs Resolved
@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: CONDITIONS · 2 conditions · the full ruling

The command grammar, the value sources, the list row and rm conform to the min secret reference in architecture.md line 513. The store provider is in bep, as Gatehouse §6.10 line 844 says. The real Keychain path never ran. So nobody showed that bep reads the item with no prompt, and BEP-051 depends on that (line 513). Do the macOS run in C1 and record it, or fix bep::store::host::set if bep prompts. File the resolver-drift issue in C2 and add it to the PR body as a residual.

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

Comment thread crates/bep/src/store.rs Resolved
Comment thread crates/bep/src/store.rs Resolved
An update in place with add-generic-password -U keeps the old item's
access control. So set now removes the old item, adds the new one
without -U, and reads the item back. The read-back decides the result,
so a warning on stderr after a good write no longer fails the command.
@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 — advisory review

Verdict COMMENT — 2 findings, 2 inline.

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

Comment thread crates/bep/src/store.rs Resolved
Comment thread crates/minimal/src/cmd/secret.rs Resolved
@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: CONDITIONS · 3 conditions · the full ruling

The access control can name the wrong proxy. min looks for bep beside min, but minvmd starts the bep beside itself, and min starts minvmd from PATH. Line 513 of architecture.md says the ACL grants the BEP process identity a prompt-free read. C1 makes min use the same anchor as minvmd. The Keychain path never ran on a Mac, so the BEP-051 proof is open. C2 adds that test and the recorded run. C3 makes the duplicate resolver an owned issue.

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

Comment thread crates/minimal/src/cmd/secret.rs Resolved
Comment thread crates/bep/src/store.rs Resolved
Comment thread crates/bep/src/store.rs Resolved
@minimal-foundry
Copy link
Copy Markdown
Contributor Author

Round 1 of 10 on the runtime's review findings, pushed as 8ae45ff5e0a5.

line exit tail
cargo nextest run -p minimal secret_set_stores_in_keychain_and_prints_id_only 0 Applying loadouts: default Running task runtime-implement-test-0 in session task-runtime-implement-test-0-1e2a... 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 stdlib v0.0.22 (/workbenc
cargo nextest run -p minimal secret_set_refuses_value_argument_and_env_flag 0 Applying loadouts: default Running task runtime-implement-test-1 in session task-runtime-implement-test-1-0423... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling graph v0
cargo nextest run -p minimal secret_set_without_tty_or_stdin_fails_immediately 0 Applying loadouts: default Running task runtime-implement-test-2 in session task-runtime-implement-test-2-4271... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.
cargo nextest run -p minimal secret_set_refuses_gatehouse_store 0 Applying loadouts: default Running task runtime-implement-test-3 in session task-runtime-implement-test-3-c19b... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.
cargo nextest run -p minimal secret_list_shows_metadata_without_values 0 Applying loadouts: default Running task runtime-implement-test-4 in session task-runtime-implement-test-4-b362... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.
cargo nextest run -p minimal secret_rm_removes_item 0 Applying loadouts: default Running task runtime-implement-test-5 in session task-runtime-implement-test-5-f7e1... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.
cargo nextest run -p minimal secret_item_acl_admits_proxy_only 0 Applying loadouts: default Running task runtime-implement-test-6 in session task-runtime-implement-test-6-0a9a... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.
cargo nextest run -p minimal secret_set_refuses_when_proxy_binary_absent 0 Applying loadouts: default Running task runtime-implement-test-7 in session task-runtime-implement-test-7-3927... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.

Verify min task run agent-verify exited 101 under rustc 1.98.1, which the repository does not pin (1.97.0 in rust-toolchain.toml); the PR is not a draft on that alone — CI, which honours the pin, is the gate.

.0.1 (/workbench/crates/ot)
    Checking paths v0.0.1 (/workbench/crates/paths)
   Compiling stdlib v0.0.22 (/workbench/crates/stdlib)
   Compiling version v0.8.0 (/workbench/crates/version)
    Checking rustls v0.23.46
    Checking switch v0.0.1 (/workbench/crates/switch)
   Compiling minvmd v0.8.0 (/workbench/crates/minvmd)
    Checking diagnostics v0.0.1 (/workbench/crates/diagnostics)
    Checking async-dialog v0.0.1 (/workbench/crates/async-dialog)
    Checking wait-timeout v0.2.1
    Checking bit-vec v0.10.1
    Checking tokio-rustls v0.26.5
    Checking rustls-platform-verifier v0.7.0
    Checking quick-error v1.2.3
    Checking bit-set v0.11.1
    Checking hyper-rustls v0.27.9
    Checking tonic v0.14.6
    Checking bep v0.0.1 (/workbench/crates/bep)
    Checking rusty-fork v0.3.1
    Checking reqwest v0.13.5
    Checking rand_xorshift v0.5.0
    Checking tonic-prost v0.14.6
    Checking google-cloud-auth v1.17.0
    Checking opentelemetry-http v0.33.1
    Checking core_detect v1.0.0
    Checking opentelemetry-otlp v0.33.0
    Checking unarray v0.1.4
    Checking google-cloud-gax-internal v0.7.20
    Checking proptest v1.12.0
    Checking mlog v0.0.1 (/workbench/crates/mlog)
    Checking google-cloud-longrunning v1.14.0
    Checking google-cloud-lro v1.11.0
    Checking google-cloud-iam-v1 v1.13.0
    Checking google-cloud-storage v1.20.0
    Checking common v0.0.1 (/workbench/crates/common)
    Checking boxes v0.0.1 (/workbench/crates/boxes)
    Checking sandbox v0.0.1 (/workbench/crates/sandbox)
    Checking mfile v0.0.1 (/workbench/crates/mfile)
    Checking minimald-rpc v0.0.1 (/workbench/crates/minimald-rpc)
    Checking decode v0.0.1 (/workbench/crates/decode)
    Checking checkouts v0.0.1 (/workbench/crates/checkouts)
    Checking graph v0.0.1 (/workbench/crates/graph)
    Checking lcache v0.0.1 (/workbench/crates/lcache)
    Checking rcache v0.0.1 (/workbench/crates/rcache)
    Checking op v0.0.1 (/workbench/crates/op)
    Checking check v0.0.1 (/workbench/crates/check)
    Checking orchestrator v0.0.1 (/workbench/crates/orchestrator)
error: using `chunks_exact` with a constant chunk size
   --> crates/minimald-rpc/src/trace.rs:199:46
    |
199 |     for (byte, pair) in out.iter_mut().zip(s.chunks_exact(2)) {
    |                                              ^^^^^^^^^^^^^^^
    |
help: consider using `as_chunks::<2>()` instead
   --> crates/minimald-rpc/src/trace.rs:199:46
    |
199 |     for (byte, pair) in out.iter_mut().zip(s.chunks_exact(2)) {
    |                                              ^^^^^^^^^^^^^^^
    = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.98.0/index.html#chunks_exact_to_as_chunks
    = note: `-D clippy::chunks-exact-to-as-chunks` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::chunks_exact_to_as_chunks)]`

error: could not compile `minimald-rpc` (lib) due to 1 previous error
warning: build failed, waiting for other jobs to finish...

Review threads the coder judged:

  • 👎 invalid — crates/minimal/src/cmd/secret.rs:148: MINVMD_BEP_BIN is not a new trust boundary. A tool that can set the environment of min can also set PATH and replace min itself, or replace the bep that minvmd starts. minvmd (crates/minvmd/src/cmd/run.rs:1403) finds the proxy through the same variable. If set ignores it, the access control na
  • 👍 valid — crates/bep/src/store.rs:250: set now removes the old item first and adds the new one without -U, so the item gets a fresh -T access control. Then it reads the item back and fails if the proxy entry is missing. The ACL test asserts that the keychain line has no -U.
  • 👍 valid — crates/bep/src/store.rs:406: stderr alone no longer fails set. A non-zero exit fails it, and otherwise a read-back of the item and its proxy entry decides the result. stderr is the error detail only when that check fails.

min secret set claude prints only the identifier claude, and min secret list shows the store, authorities, injection form, consent rule and proxy access entry of claude, and no value. A second min secret set claude now gives the item a fresh access control that names the proxy.

Notes from the agent: Revise round 1. The changed host::set code is in the #[cfg(target_os = "macos")] module. This Linux box does not compile it, and it has no darwin target. So no compiler or test checked that code here. The macOS lane or just e2e must check it. A new test assertion pins the removal of -U from the keychain line. One trade-off: set now removes the old item before it adds the new one. If the add then fails, the old value is gone. The person was replacing that value, and the command reports the failure.

Copy link
Copy Markdown
Member

/revise

Round 2 of #2522, on the arch ruling at 8ae45ff and the review findings that stay open. No round is in flight.

  1. Arch C1 (threads 4369066528, 4369041895): crates/minimal/src/cmd/secret.rs proxy_path() resolves the proxy the way the running minvmd does: MINVMD_BEP_BIN when set and not empty, else bep beside the minvmd that crates/minimal/src/autospawn.rs starts (resolve minvmd on PATH as Command::new("minvmd") does), not beside current_exe(). Change the doc of bep::store::proxy_binary_path to name that anchor and extend secret_set_refuses_when_proxy_binary_absent to pin it. That also answers the review finding 4369062274 on the trust anchor; say so there, and on the disputed thread 4369038812.
  2. Arch C3 (threads 4369066536, 4369041898): file one issue to make crates/minvmd/src/cmd/run.rs resolve_bep_binary and bep::store::proxy_binary_path one function in one owner, and add it to the PR body under ## Residuals.
  3. Arch C2 (thread 4369066531): add the #[cfg(target_os = "macos")] #[ignore] test host_store_set_list_rm_round_trip in crates/bep/src/store.rs as the ruling describes (set, list shows proxy_access: true, set again leaves one item, remove). The run on a real Mac and its output in the Proof section are the owner's; say in the PR body that the BEP-051 leg is not_run until then, and name the BEP-033 task issue that proves the prompt-free read.
  4. Review finding 4369062269 (set deletes the old item before the new add succeeds): add the new item first under a temporary account, or restore the old item when the add or the read-back fails, so a failed min secret set never destroys a working secret; pin it with a test.
  5. Reply on each thread naming the commit and resolve the ones the commit fixes.

One or two commits, Conventional Commits subjects, body lines at most 100 characters.


Generated by Claude Code

min secret set named `bep` beside the `min` program in the item's access control.
The running minvmd starts `bep` beside its own executable, and autospawn starts
the first `minvmd` on PATH. So the access control now names `bep` beside that
`minvmd`, or the MINVMD_BEP_BIN path when it is set and not empty. With no
`minvmd` on PATH, set refuses and names both remedies.
set on a held id deleted the old keychain item before it added the new one, so a
refused add destroyed a working secret. The new value now goes first into an item
under dev.minimal.secret.staging and is read back. Only then is the old item
deleted. If the last add still fails, the error says that the old value is
removed. The proxy path doc now names the minvmd anchor.

Adds the macOS ignored test host_store_set_list_rm_round_trip for a real keychain.
@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 — advisory review

Verdict COMMENT — 2 findings, 2 inline.

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

Comment thread crates/minimal/src/cmd/secret.rs Resolved
Comment thread crates/minimal/src/cmd/secret.rs Resolved
@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: CONDITIONS · 2 conditions · the full ruling

The verb, the refusals and the list row conform to architecture.md line 513. The compare fixes the proxy anchor and the replace order. Two items stay open. C1: the macOS Keychain path never ran, and line 513 makes the keychain ACL the only proof that the proxy reads without a prompt. Run the ignored round-trip test with a copy of bep as the proxy, and paste the output under ## Proof. C2: the proxy-path rule has a second copy in minvmd and no issue owns it. File that issue, and name it in both doc comments and in the PR body.

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

Comment thread crates/bep/src/store.rs Resolved
Comment thread crates/bep/src/store.rs Resolved
Comment thread crates/minimal/src/cmd/secret.rs Resolved
@minimal-foundry
Copy link
Copy Markdown
Contributor Author

Round 2 of 10 on a /revise note, pushed as 7d0e4b26f6ac.

line exit tail
cargo nextest run -p minimal secret_set_stores_in_keychain_and_prints_id_only 0 Applying loadouts: default Running task runtime-implement-test-0 in session task-runtime-implement-test-0-2576... 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 stdlib v0.0.22 (/workbenc
cargo nextest run -p minimal secret_set_refuses_value_argument_and_env_flag 0 Applying loadouts: default Running task runtime-implement-test-1 in session task-runtime-implement-test-1-f66b... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.
cargo nextest run -p minimal secret_set_without_tty_or_stdin_fails_immediately 0 Applying loadouts: default Running task runtime-implement-test-2 in session task-runtime-implement-test-2-7d87... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.
cargo nextest run -p minimal secret_set_refuses_gatehouse_store 0 Applying loadouts: default Running task runtime-implement-test-3 in session task-runtime-implement-test-3-4c98... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.
cargo nextest run -p minimal secret_list_shows_metadata_without_values 0 Applying loadouts: default Running task runtime-implement-test-4 in session task-runtime-implement-test-4-850c... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.
cargo nextest run -p minimal secret_rm_removes_item 0 Applying loadouts: default Running task runtime-implement-test-5 in session task-runtime-implement-test-5-d9ce... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.
cargo nextest run -p minimal secret_item_acl_admits_proxy_only 0 Applying loadouts: default Running task runtime-implement-test-6 in session task-runtime-implement-test-6-278e... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.
cargo nextest run -p minimal secret_set_refuses_when_proxy_binary_absent 0 Applying loadouts: default Running task runtime-implement-test-7 in session task-runtime-implement-test-7-824b... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.

Verify min task run agent-verify exited 101 under rustc 1.98.1, which the repository does not pin (1.97.0 in rust-toolchain.toml); the PR is not a draft on that alone — CI, which honours the pin, is the gate.

the sandbox ran rustc (1.98.1), the repository pins 1.97.0 in rust-toolchain.toml; a failure here may be the newer toolchain's, not this change's
Applying loadouts: default
Running task runtime-implement-verify in session task-runtime-implement-verify-f6ea...
    Checking ot v0.0.1 (/workbench/crates/ot)
    Checking args v0.0.1 (/workbench/crates/args)
    Checking paths v0.0.1 (/workbench/crates/paths)
   Compiling stdlib v0.0.22 (/workbench/crates/stdlib)
   Compiling version v0.8.0 (/workbench/crates/version)
    Checking switch v0.0.1 (/workbench/crates/switch)
    Checking bep v0.0.1 (/workbench/crates/bep)
   Compiling minvmd v0.8.0 (/workbench/crates/minvmd)
    Checking common v0.0.1 (/workbench/crates/common)
    Checking diagnostics v0.0.1 (/workbench/crates/diagnostics)
    Checking async-dialog v0.0.1 (/workbench/crates/async-dialog)
    Checking boxes v0.0.1 (/workbench/crates/boxes)
    Checking sandbox v0.0.1 (/workbench/crates/sandbox)
    Checking mlog v0.0.1 (/workbench/crates/mlog)
    Checking mfile v0.0.1 (/workbench/crates/mfile)
    Checking checkouts v0.0.1 (/workbench/crates/checkouts)
    Checking decode v0.0.1 (/workbench/crates/decode)
    Checking minimald-rpc v0.0.1 (/workbench/crates/minimald-rpc)
    Checking graph v0.0.1 (/workbench/crates/graph)
    Checking lcache v0.0.1 (/workbench/crates/lcache)
    Checking rcache v0.0.1 (/workbench/crates/rcache)
    Checking op v0.0.1 (/workbench/crates/op)
    Checking orchestrator v0.0.1 (/workbench/crates/orchestrator)
    Checking check v0.0.1 (/workbench/crates/check)
error: using `chunks_exact` with a constant chunk size
   --> crates/minimald-rpc/src/trace.rs:199:46
    |
199 |     for (byte, pair) in out.iter_mut().zip(s.chunks_exact(2)) {
    |                                              ^^^^^^^^^^^^^^^
    |
help: consider using `as_chunks::<2>()` instead
   --> crates/minimald-rpc/src/trace.rs:199:46
    |
199 |     for (byte, pair) in out.iter_mut().zip(s.chunks_exact(2)) {
    |                                              ^^^^^^^^^^^^^^^
    = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.98.0/index.html#chunks_exact_to_as_chunks
    = note: `-D clippy::chunks-exact-to-as-chunks` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::chunks_exact_to_as_chunks)]`

error: could not compile `minimald-rpc` (lib) due to 1 previous error
warning: build failed, waiting for other jobs to finish...

Review threads the coder judged:

  • 👍 valid — crates/bep/src/store.rs: 7d0e4b2 adds the macOS #[ignore] test host_store_set_list_rm_round_trip (set, list, set again, remove on HostStore). This Linux box cannot run it, so the real-keychain result for the Proof section is still owed from a Mac.
  • 👍 valid — crates/bep/src/store.rs: 7d0e4b2 names resolve_bep_binary in crates/minvmd/src/cmd/run.rs as the twin in the proxy_binary_path doc. The coder has no credential to file the merge issue, so the owner must file it and list it under Residuals.
  • 👍 valid — PRRT_kwDOPdfcxM6v895Q: 7d0e4b2: set_item adds and reads back the new value under dev.minimal.secret.staging before it deletes the old item. Pinned by secret_set_failure_keeps_the_old_secret. If the final add still fails, the error says the old value is removed. (not posted on the thread: not an open thread on the pull request)
  • 👍 valid — crates/minimal/src/cmd/secret.rs:116: f03dc98: the trusted path is no longer a file beside min. It is MINVMD_BEP_BIN, the same input minvmd reads to start the proxy, or bep beside the minvmd on PATH. No ownership or signature check was added. Such a check must match what minvmd checks, so it belongs in the shared-function issue.
  • 👍 valid — crates/minimal/src/cmd/secret.rs:62: f03dc98: resolve_proxy anchors bep on the first executable minvmd on PATH, as autospawn's Command::new("minvmd") finds it, not on current_exe(). Pinned in secret_set_refuses_when_proxy_binary_absent.
  • 👍 valid — crates/bep/src/store.rs: 7d0e4b2 adds host_store_set_list_rm_round_trip (macOS, #[ignore]). It prints the listing after each step for the Proof section. A Mac run is still owed.
  • 👍 valid — crates/bep/src/store.rs: Same as C2: 7d0e4b2 names the twin function in the doc. The merge issue still has to be filed, and the coder has no credential for that, so the owner must file it and add it as a residual.

min secret set claude prints only the identifier, and min secret list shows its metadata and no value. The item's access control now names the bep program beside the minvmd on PATH, the one the running daemon starts. A failed min secret set on a held identifier keeps the old secret.

Notes from the agent: Commits f03dc98 (min side: proxy anchor) and 7d0e4b2 (bep side: staged replace, proxy_binary_path doc, macOS round-trip test). Directive item 1: resolve_proxy in crates/minimal/src/cmd/secret.rs uses MINVMD_BEP_BIN when set and not empty, else bep beside the first executable minvmd on PATH. When no minvmd is on PATH, set refuses with a new message that names both remedies. secret_set_refuses_when_proxy_binary_absent pins the anchor. Open question for the owner: on macOS, Rust current_exe in minvmd can return a symlink path or a resolved path. resolve_proxy does not canonicalize the PATH entry. If minvmd is a symlink to another directory, the two sides can disagree. Directive item 2: I cannot file the issue or edit the PR body. I have no credential for gh. The owner must file the issue to merge resolve_bep_binary (crates/minvmd/src/cmd/run.rs) and bep::store::proxy_binary_path, and add it under ## Residuals. The doc of proxy_binary_path now names the twin. Directive item 3: host_store_set_list_rm_round_trip is in crates/bep/src/store.rs, #[cfg(target_os = "macos")] #[ignore]. This box is Linux, so it does not compile or run here, and the macOS host module is not compiled here either. The BEP-051 leg is not_run until the owner runs cargo nextest run -p bep host_store_set_list_rm_round_trip --run-ignored only on a Mac. The PR body text for this and the BEP-033 task issue name are the owner's to write, because I cannot edit the body and the issue number is not in my inputs. Directive item 4: set_item stores the new value under service dev.minimal.secret.staging first and reads it back, then deletes the old item, then adds the final item.…[truncated]

Copy link
Copy Markdown
Member

/revise

Round 3 of #2522, on the arch ruling at 7d0e4b2 and the review findings that stay open. No round is in flight. The epic owner filed #2527 for the proxy-binary resolver's single owner (arch C2), and will run the macOS Keychain leg (arch C1) on the head this round produces.

  1. Review findings 4369136719 (HIGH) and 4369136724 (MEDIUM), resolve_proxy and find_on_path in crates/minimal/src/cmd/secret.rs: the program the Keychain item trusts must be an absolute, canonical path to an existing regular file. Skip an empty or relative PATH entry when resolving minvmd, refuse a relative MINVMD_BEP_BIN, canonicalize the result, and refuse with the existing proxy-absent message when nothing qualifies. Pin it with tests for an empty PATH entry, a relative entry and a relative MINVMD_BEP_BIN.
  2. Arch C2 (threads 4369139810, 4369139811, 4369041898, 4369066536): put Give the proxy-binary resolver one owner shared by min secret and minvmd (BEP-051) #2527 in the doc comment of bep::store::proxy_binary_path and of resolve_proxy, and add a ## Residuals section to the PR body with that URL.
  3. Arch C1 (threads 4369139806, 4369041895, 4369066531): in host_store_set_list_rm_round_trip, replace /usr/bin/true with a copy of the built bep (for example env!("CARGO_BIN_EXE_bep") copied into the test's temp dir), so the run shows the access control the proxy gets. State in the PR body that the BEP-051 leg is not_run until the owner pastes the Mac output under ## Proof, and name the BEP-033 task issue that proves the prompt-free read.
  4. Thread 4369038812 (disputed, MINVMD_BEP_BIN as a trust boundary): the hardening in step 1 is the answer; reply with it and resolve.
  5. Reply on each thread naming the commit, and resolve the ones the commit fixes.

One or two commits, Conventional Commits subjects, body lines at most 100 characters.


Generated by Claude Code

resolve_proxy picks the program that the keychain item trusts. An empty or
relative PATH entry let a `minvmd` in the current directory anchor it, and a
relative MINVMD_BEP_BIN went into the access control as is. Now find_on_path
skips every entry that is not absolute, a relative MINVMD_BEP_BIN is refused,
and a proxy that exists comes back canonical. run_set refuses a relative path.
The doc comment names issue 2527, the one owner for the rule.
/usr/bin/true is Apple-signed, so it cannot show the access control that the
proxy gets. The macOS round trip now copies the built `bep` into a temporary
directory and names that copy. proxy_binary_path names issue 2527.
@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 — advisory review

Verdict COMMENT — 3 findings, 3 inline.

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

Comment thread crates/minimal/src/cmd/secret.rs Resolved
Comment thread crates/bep/src/store.rs Resolved
Comment thread crates/bep/src/store.rs Resolved
@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_WITH_CONDITIONS · 1 condition · the full ruling

The compare closes the conditions on 7d0e4b26. The trusted proxy path is now absolute and canonical. The Mac round trip trusts a copy of bep, and issue 2527 owns the duplicated path rule. The code meets architecture.md line 513 for set, list and rm. Nobody ran the BEP-051 access control on a real Keychain. C1 runs the ignored round trip on a Mac and records the output in the PR body. No code change is necessary.

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

Comment thread crates/bep/src/store.rs Resolved
@minimal-foundry
Copy link
Copy Markdown
Contributor Author

Round 3 of 10 on a /revise note, pushed as 5d0e7d053b60.

line exit tail
cargo nextest run -p minimal secret_set_stores_in_keychain_and_prints_id_only 0 Applying loadouts: default Running task runtime-implement-test-0 in session task-runtime-implement-test-0-9328... 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 stdlib v0.0.22 (/workbenc
cargo nextest run -p minimal secret_set_refuses_value_argument_and_env_flag 0 Applying loadouts: default Running task runtime-implement-test-1 in session task-runtime-implement-test-1-fe0d... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.
cargo nextest run -p minimal secret_set_without_tty_or_stdin_fails_immediately 0 Applying loadouts: default Running task runtime-implement-test-2 in session task-runtime-implement-test-2-387c... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.
cargo nextest run -p minimal secret_set_refuses_gatehouse_store 0 Applying loadouts: default Running task runtime-implement-test-3 in session task-runtime-implement-test-3-415e... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.
cargo nextest run -p minimal secret_list_shows_metadata_without_values 0 Applying loadouts: default Running task runtime-implement-test-4 in session task-runtime-implement-test-4-5800... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.
cargo nextest run -p minimal secret_rm_removes_item 0 Applying loadouts: default Running task runtime-implement-test-5 in session task-runtime-implement-test-5-7097... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.
cargo nextest run -p minimal secret_item_acl_admits_proxy_only 0 Applying loadouts: default Running task runtime-implement-test-6 in session task-runtime-implement-test-6-31fa... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.
cargo nextest run -p minimal secret_set_refuses_when_proxy_binary_absent 0 Applying loadouts: default Running task runtime-implement-test-7 in session task-runtime-implement-test-7-e438... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.

Verify min task run agent-verify exited 101 under rustc 1.98.1, which the repository does not pin (1.97.0 in rust-toolchain.toml); the PR is not a draft on that alone — CI, which honours the pin, is the gate.

task runtime-implement-verify in session task-runtime-implement-verify-3c90...
    Checking rustls-webpki v0.103.16
    Checking ot v0.0.1 (/workbench/crates/ot)
    Checking args v0.0.1 (/workbench/crates/args)
    Checking paths v0.0.1 (/workbench/crates/paths)
   Compiling stdlib v0.0.22 (/workbench/crates/stdlib)
   Compiling version v0.8.0 (/workbench/crates/version)
    Checking rustls v0.23.46
    Checking switch v0.0.1 (/workbench/crates/switch)
   Compiling minvmd v0.8.0 (/workbench/crates/minvmd)
    Checking diagnostics v0.0.1 (/workbench/crates/diagnostics)
    Checking async-dialog v0.0.1 (/workbench/crates/async-dialog)
    Checking wait-timeout v0.2.1
    Checking tokio-rustls v0.26.5
    Checking rustls-platform-verifier v0.7.0
    Checking rusty-fork v0.3.1
    Checking hyper-rustls v0.27.9
    Checking tonic v0.14.6
    Checking bep v0.0.1 (/workbench/crates/bep)
    Checking proptest v1.12.0
    Checking reqwest v0.13.5
    Checking tonic-prost v0.14.6
    Checking google-cloud-auth v1.17.0
    Checking opentelemetry-http v0.33.1
    Checking opentelemetry-otlp v0.33.0
    Checking google-cloud-gax-internal v0.7.20
    Checking mlog v0.0.1 (/workbench/crates/mlog)
    Checking google-cloud-longrunning v1.14.0
    Checking google-cloud-lro v1.11.0
    Checking google-cloud-iam-v1 v1.13.0
    Checking google-cloud-storage v1.20.0
    Checking common v0.0.1 (/workbench/crates/common)
    Checking boxes v0.0.1 (/workbench/crates/boxes)
    Checking sandbox v0.0.1 (/workbench/crates/sandbox)
    Checking mfile v0.0.1 (/workbench/crates/mfile)
    Checking minimald-rpc v0.0.1 (/workbench/crates/minimald-rpc)
    Checking decode v0.0.1 (/workbench/crates/decode)
    Checking checkouts v0.0.1 (/workbench/crates/checkouts)
    Checking graph v0.0.1 (/workbench/crates/graph)
    Checking lcache v0.0.1 (/workbench/crates/lcache)
    Checking rcache v0.0.1 (/workbench/crates/rcache)
    Checking op v0.0.1 (/workbench/crates/op)
    Checking check v0.0.1 (/workbench/crates/check)
    Checking orchestrator v0.0.1 (/workbench/crates/orchestrator)
error: using `chunks_exact` with a constant chunk size
   --> crates/minimald-rpc/src/trace.rs:199:46
    |
199 |     for (byte, pair) in out.iter_mut().zip(s.chunks_exact(2)) {
    |                                              ^^^^^^^^^^^^^^^
    |
help: consider using `as_chunks::<2>()` instead
   --> crates/minimald-rpc/src/trace.rs:199:46
    |
199 |     for (byte, pair) in out.iter_mut().zip(s.chunks_exact(2)) {
    |                                              ^^^^^^^^^^^^^^^
    = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.98.0/index.html#chunks_exact_to_as_chunks
    = note: `-D clippy::chunks-exact-to-as-chunks` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::chunks_exact_to_as_chunks)]`

error: could not compile `minimald-rpc` (lib) due to 1 previous error
warning: build failed, waiting for other jobs to finish...

Review threads the coder judged:

  • 👍 valid — PRRT_kwDOPdfcxM6v9JQ7: 1971099: resolve_proxy skips empty and relative PATH entries, refuses a relative MINVMD_BEP_BIN, and canonicalizes the proxy. Ownership checks are not added: minvmd starts the program at this same path. (not posted on the thread: not an open thread on the pull request)
  • 👍 valid — PRRT_kwDOPdfcxM6v9JQ9: 1971099: find_on_path keeps only absolute PATH entries, a relative MINVMD_BEP_BIN is refused, run_set refuses a relative proxy path. Tests pin all three. (not posted on the thread: not an open thread on the pull request)
  • 👍 valid — crates/bep/src/store.rs:717: 5d0e7d0: host_store_set_list_rm_round_trip now names a copy of the built bep in a temp dir, not /usr/bin/true. The Mac run is still owed under ## Proof.
  • 👍 valid — crates/bep/src/store.rs:48: 5d0e7d0: the proxy_binary_path doc comment names Give the proxy-binary resolver one owner shared by min secret and minvmd (BEP-051) #2527 as the one owner for the rule.
  • 👍 valid — crates/minimal/src/cmd/secret.rs:84: 1971099: the resolve_proxy doc comment names Give the proxy-binary resolver one owner shared by min secret and minvmd (BEP-051) #2527 beside resolve_bep_binary in minvmd.

min secret set claude prints only the identifier, and min secret list shows its metadata and no value. The program that the keychain item trusts is now always an absolute, canonical path: a relative MINVMD_BEP_BIN is refused, and an empty or relative PATH entry never anchors it. The BEP-051 leg on a real Mac is not_run until the epic owner runs host_store_set_list_rm_round_trip and pastes its output under ## Proof.

Notes from the agent: Round 3. Commit 1971099 (fix(minimal)) hardens resolve_proxy and find_on_path and names issue 2527 in the resolve_proxy doc comment. Commit 5d0e7d0 (test(bep)) makes host_store_set_list_rm_round_trip name a copy of the built bep in a temp dir, and names issue 2527 in the proxy_binary_path doc comment. The test takes option_env!("CARGO_BIN_EXE_bep") and falls back to the bep beside target//deps. On a Mac, build bep first (cargo build -p bep), then run: cargo nextest run -p bep host_store_set_list_rm_round_trip --run-ignored only. I type-checked that test on Linux by removing its macOS cfg for one clippy run, then put the cfg back. It did not run here, because the box is Linux. For the PR body, which the runner writes: add a ## Residuals section with #2527 (one owner for the proxy-binary rule, arch C2), and state that the BEP-051 leg is not_run until the owner pastes the Mac output under ## Proof. I do not know the number of the BEP-033 task issue that proves the prompt-free read, so the person who edits the body must add it. A relative MINVMD_BEP_BIN has a new refusal: "min secret set did not read the value: MINVMD_BEP_BIN is the relative path

. Set MINVMD_BEP_BIN to the absolute path of the bep program, and run the command again." A proxy path that does not exist still gets the existing proxy-absent message from run_set. The bep path is still computed beside the minvmd path as PATH finds it, then canonicalized. If minvmd on PATH is a symbolic link, minvmd its…[truncated]

Copy link
Copy Markdown
Member

/revise

Round 4 of #2522, on the three review findings left open at 5d0e7d0. No round is in flight. Arch C1 (the real-Keychain run) is the epic owner's and runs on the head this round produces; do not change host_store_set_list_rm_round_trip beyond what step 2 needs.

  1. Finding 4369348721 (add_line, security): add_line writes id unquoted into the line that security -i parses while its comment says valid_id checks it, and keychain_add_line is pub. Call valid_id in add_line (or in keychain_add_line and every path to it) and refuse an invalid id with the existing refusal, so the check is not only the CLI's; pin it with a test for an id that carries a quote and a space.
  2. Finding 4369348719 (set_item): the cleanup of the staging item ignores a delete error, so a failed cleanup leaves the value under dev.minimal.secret.staging with proxy access. Report the failed cleanup as the error of set (the new item is already in place, so say that the staging copy remains and name the security delete-generic-password command that removes it), and pin it with a test whose keychain refuses the staging delete.
  3. Finding 4369348711 (run_set): run_set reads the secret from the terminal before store.set can refuse Unsupported, so on a host with no native store the person types a secret that is then refused. Check the store's availability (and resolve the proxy path) before reading the value, and keep the read-after-check order under a test.
  4. Add a ## Residuals section to the PR body with Give the proxy-binary resolver one owner shared by min secret and minvmd (BEP-051) #2527 (one owner for the proxy-binary resolver rule), and state under ## Proof that the real-Keychain leg (BEP-051) is not_run until the owner pastes the Mac output.
  5. Reply on each thread naming the commit and resolve the ones the commit fixes. Leave thread 4369349013 (arch C1, the Mac run) open.

One or two commits, Conventional Commits subjects, body lines at most 100 characters.


Generated by Claude Code

add_line checks the id with valid_id, so no caller of keychain_add_line can
put an option such as -A on the line that security -i parses.

set_item reports a staging cleanup that the keychain refuses. A replace
that succeeded returns StagingLeft, which says the new value is stored and
names the security delete-generic-password command that removes the copy.

SecretStore gains check_available, so set can learn before it reads a value
that the host has no store.
run_set asks the store whether this host can use it before it prompts or
reads standard input, so nobody types a secret that is then refused. The
new test secret_set_checks_the_store_before_it_reads keeps that order.

check_id uses the store's InvalidId refusal, so the text has one owner. A
StagingLeft error prints without "did not store", because the value is
stored.
check_proxy_binary now walks every directory from the proxy's parent up
to the root. Each one must be owned by the current user or root, and must
not be writable by group or others. A sticky directory above the parent,
such as /tmp, can be writable.

add_checked now deletes the new item when the read-back after a
successful add fails, so a refused set leaves no unchecked item behind.
@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_WITH_CONDITIONS · 1 condition · the full ruling

The new commit makes the proxy-only access in architecture.md line 513 stronger. The proxy check now covers every directory up to the root. A failed read-back now deletes the new item, so the set fails closed. One condition from the last ruling stays open. C1: run the macOS Keychain proof, or file it as an issue and link it. Residual #2527 stays open for the duplicated proxy resolver.

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

Comment thread crates/bep/src/store.rs Resolved
@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 — advisory review

Verdict COMMENT — 2 findings, 2 inline.

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

Comment thread crates/minimal/src/cmd/secret.rs Resolved
Comment thread crates/minimal/src/cmd/secret.rs Resolved
@minimal-foundry
Copy link
Copy Markdown
Contributor Author

Round 6 of 10 on a /revise note, pushed as c8bcc05bd8ba.

line exit tail
cargo nextest run -p minimal secret_set_stores_in_keychain_and_prints_id_only 0 Applying loadouts: default Running task runtime-implement-test-0 in session task-runtime-implement-test-0-a88a... 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 stdlib v0.0.22 (/workbenc
cargo nextest run -p minimal secret_set_refuses_value_argument_and_env_flag 0 Applying loadouts: default Running task runtime-implement-test-1 in session task-runtime-implement-test-1-e5f2... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.
cargo nextest run -p minimal secret_set_without_tty_or_stdin_fails_immediately 0 Applying loadouts: default Running task runtime-implement-test-2 in session task-runtime-implement-test-2-209e... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.
cargo nextest run -p minimal secret_set_refuses_gatehouse_store 0 Applying loadouts: default Running task runtime-implement-test-3 in session task-runtime-implement-test-3-79d7... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.
cargo nextest run -p minimal secret_list_shows_metadata_without_values 0 Applying loadouts: default Running task runtime-implement-test-4 in session task-runtime-implement-test-4-c390... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.
cargo nextest run -p minimal secret_rm_removes_item 0 Applying loadouts: default Running task runtime-implement-test-5 in session task-runtime-implement-test-5-33bd... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.
cargo nextest run -p minimal secret_item_acl_admits_proxy_only 0 Applying loadouts: default Running task runtime-implement-test-6 in session task-runtime-implement-test-6-1bf0... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.
cargo nextest run -p minimal secret_set_refuses_when_proxy_binary_absent 0 Applying loadouts: default Running task runtime-implement-test-7 in session task-runtime-implement-test-7-b786... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.

Verify min task run agent-verify exited 101 under rustc 1.98.1, which the repository does not pin (1.97.0 in rust-toolchain.toml); the PR is not a draft on that alone — CI, which honours the pin, is the gate.

.1
    Checking kasuari v0.4.12
    Checking hash32 v0.3.1
    Checking yasna v0.6.0
    Checking module-lattice v0.2.3
    Checking lru v0.18.2
    Checking kem v0.3.0
    Checking compression-core v0.4.33
    Checking size v0.5.0
    Checking data-encoding v2.11.1
    Checking sponge-cursor v0.1.0
    Checking compression-codecs v0.4.45
    Checking op v0.0.1 (/workbench/crates/op)
    Checking ml-kem v0.3.2
    Checking sha3 v0.12.0
    Checking ratatui-core v0.1.2
    Checking rcgen v0.14.10
    Checking heapless v0.9.3
    Checking ssh-key v0.7.0-rc.11
    Checking mlog v0.0.1 (/workbench/crates/mlog)
    Checking signal-hook-mio v0.2.5
    Checking generic-array v1.4.4
    Checking derive_more v2.1.1
    Checking russh-cryptovec v0.62.0
    Checking num-bigint v0.5.1
    Checking russh-util v0.52.0
    Checking tagptr v0.2.0
    Checking hex-literal v1.1.0
    Checking constcat v0.6.1
    Checking tinyvec_macros v0.1.1
    Checking managed v0.8.0
    Checking bitflags v1.3.2
    Checking tinyvec v1.12.0
    Checking minimald-rpc v0.0.1 (/workbench/crates/minimald-rpc)
    Checking smoltcp v0.14.0
    Checking russh v0.64.1
    Checking moka v0.12.16
    Checking crossterm v0.29.0
    Checking async-compression v0.4.50
    Checking async-tar v0.6.1
    Checking line-clipping v0.3.8
    Checking object v0.40.0
    Checking is_executable v1.0.6
    Checking ratatui-widgets v0.3.2
    Checking clap_complete v4.6.11
    Checking switch v0.0.1 (/workbench/crates/switch)
    Checking hickory-proto v0.26.3
    Checking check v0.0.1 (/workbench/crates/check)
    Checking bep v0.0.1 (/workbench/crates/bep)
    Checking orchestrator v0.0.1 (/workbench/crates/orchestrator)
    Checking sysinfo v0.39.6
   Compiling minvmd v0.8.0 (/workbench/crates/minvmd)
    Checking ratatui-macros v0.7.2
    Checking diagnostics v0.0.1 (/workbench/crates/diagnostics)
    Checking ratatui-crossterm v0.1.2
    Checking mctx v0.0.1 (/workbench/crates/mctx)
    Checking fuzzy-matcher v0.3.7
    Checking hashbrown v0.14.5
    Checking dashmap v6.2.1
    Checking inquire v0.9.4
error: using `chunks_exact` with a constant chunk size
   --> crates/minimald-rpc/src/trace.rs:199:46
    |
199 |     for (byte, pair) in out.iter_mut().zip(s.chunks_exact(2)) {
    |                                              ^^^^^^^^^^^^^^^
    |
help: consider using `as_chunks::<2>()` instead
   --> crates/minimald-rpc/src/trace.rs:199:46
    |
199 |     for (byte, pair) in out.iter_mut().zip(s.chunks_exact(2)) {
    |                                              ^^^^^^^^^^^^^^^
    = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.98.0/index.html#chunks_exact_to_as_chunks
    = note: `-D clippy::chunks-exact-to-as-chunks` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::chunks_exact_to_as_chunks)]`

error: could not compile `minimald-rpc` (lib) due to 1 previous error
warning: build failed, waiting for other jobs to finish...

Review threads the coder judged:

  • 👍 valid — PRRT_kwDOPdfcxM6v-AX9: c8bcc05: check_proxy_binary_as walks every ancestor of the proxy up to the root. Each must be owned by you or root and not group/other-writable. A sticky ancestor above the parent (/tmp) is admitted. Pinned by secret_proxy_check_refuses_a_parent_owned_by_another_user and secret_proxy_check_refuses_ (not posted on the thread: not an open thread on the pull request)
  • 👍 valid — PRRT_kwDOPdfcxM6v-AX-: c8bcc05: add_checked no longer returns early when the read-back fails after the add. It deletes the item and reports the failure. If the delete also fails, the error gives the command that removes the item. Pinned by secret_set_read_back_failure_removes_the_new_item. (not posted on the thread: not an open thread on the pull request)

min secret set claude prints only the identifier, and min secret list shows its metadata and no value. This round adds two checks. min secret set now refuses a proxy program when another user owns, or group or others can write to, any directory between the program and the root. A set whose read-back fails after the add now leaves no item in the keychain.

Notes from the agent: Round 6 is one commit, c8bcc05. The ancestor walk keeps the parent directory strict. A directory above the parent can be writable when its sticky bit is set, as /tmp is. In a sticky directory, only the owner of an entry can rename or remove it, and the entry below that directory also must pass the owner rule. Without this exemption, every proxy under a temporary directory fails the check. This box does not run as root, so the test for a parent owned by another user pins the rule function directly. That test also runs the full directory walk with chown, but only when it runs as root. Also ran cargo nextest run -p bep store:: (12 passed) and cargo clippy -p bep --all-targets (clean). host_store_set_list_rm_round_trip is not changed and was not run, because it needs a real Mac keychain. Thread 4369434893 stays open. I cannot resolve threads, so the runtime or the reviewer must resolve the fixed ones.

Copy link
Copy Markdown
Member

/revise

Round 7 of #2522, on the two review findings opened at c8bcc05. No round is in flight. Arch C1 (the real-Keychain run, threads 4369434893 and 4369550479) is the epic owner's; leave those threads open and do not change host_store_set_list_rm_round_trip.

  1. Finding 4369551998 (cmd_secret_list): min secret list calls proxy_path() before it reads the store, so with no minvmd on PATH it fails with a message that names min secret set and a value list never reads. Let list show the entries without the proxy comparison when the proxy cannot be resolved (print the access column as unknown with one line that says why), and make every refusal text name the command that printed it.
  2. Finding 4369552000 (cmd_secret_set): honour the global --no-input: with it set and a terminal on stdin, refuse at once with a message that says the value comes from piped standard input, per AGENTS.md (a new prompt with --no-input is an immediate error that names what answers it); pin it with a test.
  3. Reply on each thread naming the commit and resolve the ones the commit fixes.

One commit, Conventional Commits subject, body lines at most 100 characters.


Generated by Claude Code

min secret list no longer fails when no minvmd is on PATH. It shows the
items, prints proxy access as unknown, and adds one line that says why.

min secret set with --no-input and a terminal on standard input refuses
at once, and names piped standard input as the way to give the value.

Each refusal of a name or a store now names the command that printed it.
@minimal-arch minimal-arch Bot left a comment
< 10BC8 span class="Button-label"> 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_WITH_CONDITIONS · 1 condition · the full ruling

The compare conforms. With --no-input, min secret set now refuses at once on a terminal, as principle 3 (line 329) requires. min secret list now shows proxy access as unknown when it cannot resolve the proxy path, and it never shows a false yes. That agrees with line 513. One item stays open from the baseline: nobody ran the real Keychain leg on a Mac. C1 tells you how to close it. The resolver duplication stays filed as #2527.

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

Comment thread crates/bep/src/store.rs Resolved
@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 — advisory review

Verdict COMMENT — 3 findings, 3 inline.

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

Comment thread crates/minimal/src/cmd/secret.rs Resolved
Comment thread crates/bep/src/store.rs Resolved
Comment thread crates/bep/src/store.rs Resolved
@minimal-foundry
Copy link
Copy Markdown
Contributor Author

Round 7 of 10 on a /revise note, pushed as 48471a3fb3ca.

line exit tail
cargo nextest run -p minimal secret_set_stores_in_keychain_and_prints_id_only 0 Applying loadouts: default Running task runtime-implement-test-0 in session task-runtime-implement-test-0-f393... 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 stdlib v0.0.22 (/workbenc
cargo nextest run -p minimal secret_set_refuses_value_argument_and_env_flag 0 Applying loadouts: default Running task runtime-implement-test-1 in session task-runtime-implement-test-1-c50b... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.
cargo nextest run -p minimal secret_set_without_tty_or_stdin_fails_immediately 0 Applying loadouts: default Running task runtime-implement-test-2 in session task-runtime-implement-test-2-f43e... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.
cargo nextest run -p minimal secret_set_refuses_gatehouse_store 0 Applying loadouts: default Running task runtime-implement-test-3 in session task-runtime-implement-test-3-5cc2... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.
cargo nextest run -p minimal secret_list_shows_metadata_without_values 0 Applying loadouts: default Running task runtime-implement-test-4 in session task-runtime-implement-test-4-c627... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.
cargo nextest run -p minimal secret_rm_removes_item 0 Applying loadouts: default Running task runtime-implement-test-5 in session task-runtime-implement-test-5-2a8e... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.
cargo nextest run -p minimal secret_item_acl_admits_proxy_only 0 Applying loadouts: default Running task runtime-implement-test-6 in session task-runtime-implement-test-6-a39c... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.
cargo nextest run -p minimal secret_set_refuses_when_proxy_binary_absent 0 Applying loadouts: default Running task runtime-implement-test-7 in session task-runtime-implement-test-7-3eaa... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.

Verify min task run agent-verify exited 101 under rustc 1.98.1, which the repository does not pin (1.97.0 in rust-toolchain.toml); the PR is not a draft on that alone — CI, which honours the pin, is the gate.

0.1 (/workbench/crates/paths)
   Compiling stdlib v0.0.22 (/workbench/crates/stdlib)
   Compiling version v0.8.0 (/workbench/crates/version)
    Checking rustls v0.23.46
    Checking switch v0.0.1 (/workbench/crates/switch)
   Compiling minvmd v0.8.0 (/workbench/crates/minvmd)
    Checking diagnostics v0.0.1 (/workbench/crates/diagnostics)
    Checking async-dialog v0.0.1 (/workbench/crates/async-dialog)
    Checking wait-timeout v0.2.1
    Checking tokio-rustls v0.26.5
    Checking rustls-platform-verifier v0.7.0
    Checking bit-vec v0.10.1
    Checking quick-error v1.2.3
    Checking hyper-rustls v0.27.9
    Checking tonic v0.14.6
    Checking bep v0.0.1 (/workbench/crates/bep)
    Checking bit-set v0.11.1
    Checking reqwest v0.13.5
    Checking rusty-fork v0.3.1
    Checking tonic-prost v0.14.6
    Checking rand_xorshift v0.5.0
    Checking google-cloud-auth v1.17.0
    Checking opentelemetry-http v0.33.1
    Checking core_detect v1.0.0
    Checking opentelemetry-otlp v0.33.0
    Checking unarray v0.1.4
    Checking proptest v1.12.0
    Checking google-cloud-gax-internal v0.7.20
    Checking mlog v0.0.1 (/workbench/crates/mlog)
    Checking google-cloud-longrunning v1.14.0
    Checking google-cloud-iam-v1 v1.13.0
    Checking google-cloud-lro v1.11.0
    Checking google-cloud-storage v1.20.0
    Checking common v0.0.1 (/workbench/crates/common)
    Checking boxes v0.0.1 (/workbench/crates/boxes)
    Checking sandbox v0.0.1 (/workbench/crates/sandbox)
    Checking mfile v0.0.1 (/workbench/crates/mfile)
    Checking minimald-rpc v0.0.1 (/workbench/crates/minimald-rpc)
    Checking checkouts v0.0.1 (/workbench/crates/checkouts)
    Checking decode v0.0.1 (/workbench/crates/decode)
    Checking graph v0.0.1 (/workbench/crates/graph)
    Checking lcache v0.0.1 (/workbench/crates/lcache)
    Checking rcache v0.0.1 (/workbench/crates/rcache)
    Checking op v0.0.1 (/workbench/crates/op)
    Checking orchestrator v0.0.1 (/workbench/crates/orchestrator)
    Checking check v0.0.1 (/workbench/crates/check)
    Checking mctx v0.0.1 (/workbench/crates/mctx)
error: using `chunks_exact` with a constant chunk size
   --> crates/minimald-rpc/src/trace.rs:199:46
    |
199 |     for (byte, pair) in out.iter_mut().zip(s.chunks_exact(2)) {
    |                                              ^^^^^^^^^^^^^^^
    |
help: consider using `as_chunks::<2>()` instead
   --> crates/minimald-rpc/src/trace.rs:199:46
    |
199 |     for (byte, pair) in out.iter_mut().zip(s.chunks_exact(2)) {
    |                                              ^^^^^^^^^^^^^^^
    = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.98.0/index.html#chunks_exact_to_as_chunks
    = note: `-D clippy::chunks-exact-to-as-chunks` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::chunks_exact_to_as_chunks)]`

error: could not compile `minimald-rpc` (lib) due to 1 previous error
warning: build failed, waiting for other jobs to finish...

Review threads the coder judged:

  • 👍 valid — crates/bep/src/store.rs:430: Holds: parse_dump is tested only on fixture text. This Linux box has no Keychain, so the real security dump-keychain -a run is owed on a Mac. The note on round 7 gives that run to the epic owner. Nothing changed for it in 48471a3.
  • 👍 valid — crates/minimal/src/cmd/secret.rs:298: 48471a3: min secret list no longer stops when no proxy resolves. It lists the items with access 'unknown' and a final 'min secret list shows proxy access as unknown: ' line. resolve_proxy errors name no command, and every name or store refusal names set, list or rm.
  • 👍 valid — crates/minimal/src/cmd/secret.rs:170: 48471a3: with --no-input and a terminal on stdin, min secret set refuses before any prompt and says to pipe the value on standard input. Pinned in secret_set_without_tty_or_stdin_fails_immediately.

min secret set claude prints only the identifier, and min secret list shows its metadata and no value. With no minvmd on PATH, min secret list still shows every item, with proxy access as unknown and one line that says why. min secret set --no-input with a terminal on standard input refuses at once and names piped standard input.

Notes from the agent: One commit, 48471a3. resolve_proxy errors no longer name a command. set adds 'min secret set did not read the value' as context. list prints 'min secret list shows proxy access as unknown: ' after the items. check_id and check_store take the command name, so each refusal of a name or a store names set, list or rm. For --no-input, a new ValueSource::NoInput refuses with 'min secret set did not prompt for the value: --no-input is set. Pipe the value in on standard input, as in printf %s "$VALUE" | min secret set <id>.' Tests are in the existing test-line tests (secret_set_without_tty_or_stdin_fails_immediately, secret_list_shows_metadata_without_values, secret_set_refuses_gatehouse_store). I did not resolve any thread: my instructions forbid it, so that is for the reviewer. Thread 4369550479 (real Keychain run) is left to the epic owner, as the note asks. host_store_set_list_rm_round_trip is not changed. The real-Keychain checks cannot run on this 8 Linux bo 10BC8 x. just clippy-strict was not run.

Copy link
Copy Markdown
Member

/revise

Round 8 of #2522, on the three review findings opened at 48471a3. No round is in flight. Arch C1 (the real-Keychain run, threads 4369434893, 4369550479 and 4369645885) is the epic owner's; leave those threads open and do not change host_store_set_list_rm_round_trip.

  1. Finding 4369647104 (cmd_secret_set): call check_available before proxy_path, so a host with no native store refuses with the store message first instead of sending the person to install minvmd and then refusing again; keep the order under a test.
  2. Finding 4369647106 (proxy_binary_path): resolve symbolic links in the minvmd path found on PATH (canonicalize it) before taking bep beside it, so the rule matches the daemon's current_exe() when minvmd on PATH is a link; pin it with a test where PATH holds a link to the real minvmd.
  3. Finding 4369647108 (parse_dump_service): when one id appears in more than one keychain in dump-keychain -a, merge the duplicates with an OR of proxy_access instead of keeping the first after a sort by id, so list never shows no for an item a copy grants; pin it with a fixture that holds the same id twice.
  4. Reply on each thread naming the commit and resolve the ones the commit fixes.

One commit, Conventional Commits subject, body lines at most 100 characters.


Generated by Claude Code

min secret set checks the native store before it resolves the proxy path.
A host with no store now gets the store refusal first.

The minvmd found on PATH resolves as the daemon's current_exe() does:
links resolved on Linux, the path as is on macOS.

parse_dump merges the copies of one identifier from several keychains.
The merged item has proxy access when any copy grants it.
@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: CONDITIONS · 1 condition · the full ruling

Two of the three fixes conform: the store check now runs first, and the symlinked minvmd resolves to the bep that the daemon starts. The duplicate merge in parse_dump_service fails open. An identifier is readable when any keychain copy grants the proxy access. Line 513 says readable means the item's ACL carries the entry for the proxy. The proxy reads one copy, and a copy without the entry prompts. add_checked also uses this merge, so an older copy in the system Keychain can confirm a set that failed. Make the change in C1: merge the copies with AND.

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

Comment thread crates/bep/src/store.rs Resolved
Comment thread crates/bep/src/store.rs Resolved
Comment thread crates/minimal/src/cmd/secret.rs Resolved
@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 — advisory review

Verdict COMMENT — 2 findings, 2 inline.

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

Comment thread crates/minimal/src/cmd/secret.rs Resolved
Comment thread crates/minimal/src/cmd/secret.rs Resolved
@minimal-foundry
Copy link
Copy Markdown
Contributor Author

Round 8 of 10 on a /revise note, pushed as e670990cfe2d.

line exit tail
cargo nextest run -p minimal secret_set_stores_in_keychain_and_prints_id_only 0 Applying loadouts: default Running task runtime-implement-test-0 in session task-runtime-implement-test-0-b31d... 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 stdlib v0.0.22 (/workbenc
cargo nextest run -p minimal secret_set_refuses_value_argument_and_env_flag 0 Applying loadouts: default Running task runtime-implement-test-1 in session task-runtime-implement-test-1-c28c... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.
cargo nextest run -p minimal secret_set_without_tty_or_stdin_fails_immediately 0 Applying loadouts: default Running task runtime-implement-test-2 in session task-runtime-implement-test-2-fe9f... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.
cargo nextest run -p minimal secret_set_refuses_gatehouse_store 0 Applying loadouts: default Running task runtime-implement-test-3 in session task-runtime-implement-test-3-c379... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.
cargo nextest run -p minimal secret_list_shows_metadata_without_values 0 Applying loadouts: default Running task runtime-implement-test-4 in session task-runtime-implement-test-4-8873... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.
cargo nextest run -p minimal secret_rm_removes_item 0 Applying loadouts: default Running task runtime-implement-test-5 in session task-runtime-implement-test-5-01e4... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.
cargo nextest run -p minimal secret_item_acl_admits_proxy_only 0 Applying loadouts: default Running task runtime-implement-test-6 in session task-runtime-implement-test-6-fcfc... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.
cargo nextest run -p minimal secret_set_refuses_when_proxy_binary_absent 0 Applying loadouts: default Running task runtime-implement-test-7 in session task-runtime-implement-test-7-1532... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.

Verify min task run agent-verify exited 101 under rustc 1.98.1, which the repository does not pin (1.97.0 in rust-toolchain.toml); the PR is not a draft on that alone — CI, which honours the pin, is the gate.

0.1 (/workbench/crates/paths)
   Compiling stdlib v0.0.22 (/workbench/crates/stdlib)
   Compiling version v0.8.0 (/workbench/crates/version)
    Checking switch v0.0.1 (/workbench/crates/switch)
    Checking rustls v0.23.46
   Compiling minvmd v0.8.0 (/workbench/crates/minvmd)
    Checking diagnostics v0.0.1 (/workbench/crates/diagnostics)
    Checking async-dialog v0.0.1 (/workbench/crates/async-dialog)
    Checking tokio-rustls v0.26.5
    Checking rustls-platform-verifier v0.7.0
    Checking wait-timeout v0.2.1
    Checking bit-vec v0.10.1
    Checking hyper-rustls v0.27.9
    Checking tonic v0.14.6
    Checking bep v0.0.1 (/workbench/crates/bep)
    Checking quick-error v1.2.3
    Checking reqwest v0.13.5
    Checking rusty-fork v0.3.1
    Checking tonic-prost v0.14.6
    Checking google-cloud-auth v1.17.0
    Checking opentelemetry-http v0.33.1
    Checking bit-set v0.11.1
    Checking opentelemetry-otlp v0.33.0
    Checking rand_xorshift v0.5.0
    Checking unarray v0.1.4
    Checking mlog v0.0.1 (/workbench/crates/mlog)
    Checking google-cloud-gax-internal v0.7.20
    Checking core_detect v1.0.0
    Checking proptest v1.12.0
    Checking google-cloud-longrunning v1.14.0
    Checking google-cloud-lro v1.11.0
    Checking google-cloud-iam-v1 v1.13.0
    Checking google-cloud-storage v1.20.0
    Checking common v0.0.1 (/workbench/crates/common)
    Checking boxes v0.0.1 (/workbench/crates/boxes)
    Checking sandbox v0.0.1 (/workbench/crates/sandbox)
    Checking mfile v0.0.1 (/workbench/crates/mfile)
    Checking minimald-rpc v0.0.1 (/workbench/crates/minimald-rpc)
    Checking checkouts v0.0.1 (/workbench/crates/checkouts)
    Checking decode v0.0.1 (/workbench/crates/decode)
    Checking graph v0.0.1 (/workbench/crates/graph)
    Checking lcache v0.0.1 (/workbench/crates/lcache)
    Checking rcache v0.0.1 (/workbench/crates/rcache)
    Checking op v0.0.1 (/workbench/crates/op)
    Checking check v0.0.1 (/workbench/crates/check)
    Checking orchestrator v0.0.1 (/workbench/crates/orchestrator)
    Checking mctx v0.0.1 (/workbench/crates/mctx)
error: using `chunks_exact` with a constant chunk size
   --> crates/minimald-rpc/src/trace.rs:199:46
    |
199 |     for (byte, pair) in out.iter_mut().zip(s.chunks_exact(2)) {
    |                                              ^^^^^^^^^^^^^^^
    |
help: consider using `as_chunks::<2>()` instead
   --> crates/minimald-rpc/src/trace.rs:199:46
    |
199 |     for (byte, pair) in out.iter_mut().zip(s.chunks_exact(2)) {
    |                                              ^^^^^^^^^^^^^^^
    = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.98.0/index.html#chunks_exact_to_as_chunks
    = note: `-D clippy::chunks-exact-to-as-chunks` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::chunks_exact_to_as_chunks)]`

error: could not compile `minimald-rpc` (lib) due to 1 previous error
warning: build failed, waiting for other jobs to finish...

Review threads the coder judged:

  • 👍 valid — crates/bep/src/store.rs:1180: Still open and not changed in this round. The real-Keychain run of host_store_set_list_rm_round_trip needs a Mac, and the epic owner owns it. This box is Linux and cannot run it.
  • 👍 valid — crates/minimal/src/cmd/secret.rs: e670990: cmd_secret_set calls set_proxy, which runs check_available before resolve_proxy. secret_set_checks_the_store_before_it_reads pins the order.
  • 👍 valid — PRRT_kwDOPdfcxM6v-XYG: e670990: exe_path resolves links in the minvmd found on PATH where current_exe() resolves them (Linux). On macOS, current_exe() can return the link, so the path stays as is. A test with a link on PATH pins it. (not posted on the thread: not an open thread on the pull request)
  • 👍 valid — PRRT_kwDOPdfcxM6v-XYI: e670990: parse_dump_service merges the copies of one id with an OR of proxy_access. The fixture has claude in two keychains and is checked in both orders. (not posted on the thread: not an open thread on the pull request)

min secret set claude prints only the identifier, and min secret list shows its metadata and no value. On a host with no native store, min secret set now gives the store refusal first. A secret that is in two keychains is now listed with proxy access when either copy grants it.

Notes from the agent: Round 8. One commit, e670990. (1) cmd_secret_set calls the new set_proxy, which runs check_available before resolve_proxy. secret_set_checks_the_store_before_it_reads pins the order. (2) Finding 4369647106: I did not canonicalize on every platform. On Linux, current_exe() resolves links, so exe_path canonicalizes the minvmd found on PATH. On macOS, Rust's current_exe() is _NSGetExecutablePath, and that function gives the path that started the program. That path can be the link itself. If min canonicalized there, the access control would name a bep that the daemon does not start, and macOS is the one host with a store. So exe_path keeps the macOS path as is. The macOS behaviour comes from the documented contract of current_exe(). Nobody ran it on a Mac. The link test in secret_set_refuses_when_proxy_binary_absent expects each platform's result. (3) parse_dump_service merges the copies of an identifier with an OR of proxy_access. secret_item_acl_admits_proxy_only now has claude in two keychains, in both orders. Item 4 of the note asks me to reply on and resolve threads. My instructions do not let me resolve threads, so the verdicts below are the replies. Arch C1 is left open, as the note says. host_store_set_list_rm_round_trip is unchanged and was not run (it needs a real Keychain). I did not run just clippy-strict.

Copy link
Copy Markdown
Member

/revise

Round 9 of #2522, on the arch ruling at e670990 and the two review findings opened there. No round is in flight. Arch C1's real-Keychain run (threads 4369434893, 4369550479 and 4369645885) is the epic owner's; leave those threads open and do not change host_store_set_list_rm_round_trip.

  1. Arch C1 (threads 4369745203, 4369745212 and 4369745218): in parse_dump_service (crates/bep/src/store.rs line 460) merge duplicate ids with AND, and_modify(|a| *a &= proxy_access).or_insert(proxy_access), so an id is readable only when every copy's ACL carries the proxy's entry (BEP line 513); the read-back at line 579 then follows. In the test at crates/minimal/src/cmd/secret.rs line 888 expect proxy_access: false for claude, because one copy has no proxy entry, and keep the check for both orders of the copies.
  2. Finding 4369746890 (resolve_proxy, security): nothing checks that the path from the environment variable or the first minvmd on PATH is the real bep. Answer it from the code: say what bounds the trust today (the canonicalised path, the owner of the file, the ACL semantics), and where a check against the daemon's own location or a recorded digest is possible, add it with a test. If the tradeoff is deliberate, say why on the thread and leave the thread open; do not resolve it.
  3. Finding 4369746902 (run_set): read standard input as bytes into a Zeroizing<Vec<u8>> with a size limit, refuse a value over the limit with a message that names the limit, and strip the trailing line break from the bytes, so a binary token is not rejected as a UTF-8 error and a large pipe does not fill memory; pin both with tests.
  4. Reply on each thread naming the commit and resolve the ones the commit fixes.

One commit, Conventional Commits subject, body lines at most 100 characters.


Generated by Claude Code

parse_dump now merges duplicate identifiers with AND. An identifier is readable
only when every copy's access control carries the proxy's entry, so the
read-back in add_checked no longer accepts a new copy because an older one grants access.

min secret set reads standard input as bytes into a Zeroizing buffer of 64 KiB
and a line break. A value that is not UTF-8 is stored as is. A longer value is
refused with a message that names the limit.
@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 — approval withheld

Verdict COMMENT — APPROVE withheld: 8 unresolved threads — minimal-arch[bot] crates/bep/src/store.rs:1184, minimal-arch[bot] crates/bep/src/store.rs:432, minimal-arch[bot] crates/bep/src/store.rs:1184, minimal-arch[bot] crates/bep/src/store.rs, minimal-arch[bot] crates/bep/src/store.rs:583, …. No findings.

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

@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_WITH_CONDITIONS · 1 condition · the full ruling

The fix commit meets both conditions from the last ruling. min secret list now reports a prompt-free read only when every copy of the item carries the proxy's entry, as architecture.md line 513 says. min secret set now reads stdin as bytes, up to a limit. One condition is still open from the earlier rulings. Nobody ran the macOS Keychain path on a Mac, and line 513 makes the Keychain the native store there. Do C1: run that path on a Mac and record the result, or open an issue for the run and list it under Residuals.

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

Comment thread crates/bep/src/store.rs Resolved
@minimal-foundry
Copy link
Copy Markdown
Contributor Author

Round 9 of 10 on a /revise note, pushed as eb953d7e6be8.

line exit tail
cargo nextest run -p minimal secret_set_stores_in_keychain_and_prints_id_only 0 Applying loadouts: default Running task runtime-implement-test-0 in session task-runtime-implement-test-0-6928... 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 stdlib v0.0.22 (/workbenc
cargo nextest run -p minimal secret_set_refuses_value_argument_and_env_flag 0 Applying loadouts: default Running task runtime-implement-test-1 in session task-runtime-implement-test-1-4657... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.
cargo nextest run -p minimal secret_set_without_tty_or_stdin_fails_immediately 0 Applying loadouts: default Running task runtime-implement-test-2 in session task-runtime-implement-test-2-2898... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.
cargo nextest run -p minimal secret_set_refuses_gatehouse_store 0 Applying loadouts: default Running task runtime-implement-test-3 in session task-runtime-implement-test-3-09ea... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.
cargo nextest run -p minimal secret_list_shows_metadata_without_values 0 Applying loadouts: default Running task runtime-implement-test-4 in session task-runtime-implement-test-4-647b... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.
cargo nextest run -p minimal secret_rm_removes_item 0 Applying loadouts: default Running task runtime-implement-test-5 in session task-runtime-implement-test-5-6b1c... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.
cargo nextest run -p minimal secret_item_acl_admits_proxy_only 0 Applying loadouts: default Running task runtime-implement-test-6 in session task-runtime-implement-test-6-1165... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.
cargo nextest run -p minimal secret_set_refuses_when_proxy_binary_absent 0 Applying loadouts: default Running task runtime-implement-test-7 in session task-runtime-implement-test-7-04eb... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.

Verify min task run agent-verify exited 101 under rustc 1.98.1, which the repository does not pin (1.97.0 in rust-toolchain.toml); the PR is not a draft on that alone — CI, which honours the pin, is the gate.

.0.1 (/workbench/crates/ot)
    Checking paths v0.0.1 (/workbench/crates/paths)
   Compiling stdlib v0.0.22 (/workbench/crates/stdlib)
   Compiling version v0.8.0 (/workbench/crates/version)
    Checking rustls v0.23.46
    Checking switch v0.0.1 (/workbench/crates/switch)
   Compiling minvmd v0.8.0 (/workbench/crates/minvmd)
    Checking diagnostics v0.0.1 (/workbench/crates/diagnostics)
    Checking async-dialog v0.0.1 (/workbench/crates/async-dialog)
    Checking tokio-rustls v0.26.5
    Checking rustls-platform-verifier v0.7.0
    Checking wait-timeout v0.2.1
    Checking quick-error v1.2.3
    Checking hyper-rustls v0.27.9
    Checking tonic v0.14.6
    Checking bep v0.0.1 (/workbench/crates/bep)
    Checking bit-vec v0.10.1
    Checking reqwest v0.13.5
    Checking bit-set v0.11.1
    Checking tonic-prost v0.14.6
    Checking rusty-fork v0.3.1
    Checking google-cloud-auth v1.17.0
    Checking opentelemetry-http v0.33.1
    Checking rand_xorshift v0.5.0
    Checking opentelemetry-otlp v0.33.0
    Checking core_detect v1.0.0
    Checking google-cloud-gax-internal v0.7.20
    Checking mlog v0.0.1 (/workbench/crates/mlog)
    Checking unarray v0.1.4
    Checking proptest v1.12.0
    Checking google-cloud-longrunning v1.14.0
    Checking google-cloud-iam-v1 v1.13.0
    Checking google-cloud-lro v1.11.0
    Checking google-cloud-storage v1.20.0
    Checking common v0.0.1 (/workbench/crates/common)
    Checking boxes v0.0.1 (/workbench/crates/boxes)
    Checking sandbox v0.0.1 (/workbench/crates/sandbox)
    Checking mfile v0.0.1 (/workbench/crates/mfile)
    Checking minimald-rpc v0.0.1 (/workbench/crates/minimald-rpc)
    Checking decode v0.0.1 (/workbench/crates/decode)
    Checking checkouts v0.0.1 (/workbench/crates/checkouts)
    Checking graph v0.0.1 (/workbench/crates/graph)
    Checking lcache v0.0.1 (/workbench/crates/lcache)
    Checking rcache v0.0.1 (/workbench/crates/rcache)
    Checking op v0.0.1 (/workbench/crates/op)
    Checking orchestrator v0.0.1 (/workbench/crates/orchestrator)
    Checking check v0.0.1 (/workbench/crates/check)
error: using `chunks_exact` with a constant chunk size
   --> crates/minimald-rpc/src/trace.rs:199:46
    |
199 |     for (byte, pair) in out.iter_mut().zip(s.chunks_exact(2)) {
    |                                              ^^^^^^^^^^^^^^^
    |
help: consider using `as_chunks::<2>()` instead
   --> crates/minimald-rpc/src/trace.rs:199:46
    |
199 |     for (byte, pair) in out.iter_mut().zip(s.chunks_exact(2)) {
    |                                              ^^^^^^^^^^^^^^^
    = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.98.0/index.html#chunks_exact_to_as_chunks
    = note: `-D clippy::chunks-exact-to-as-chunks` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::chunks_exact_to_as_chunks)]`

error: could not compile `minimald-rpc` (lib) due to 1 previous error
warning: build failed, waiting for other jobs to finish...

Review threads the coder judged:

  • 👍 valid — PRRT_kwDOPdfcxM6v-mnC: eb953d7: parse_dump_service merges duplicate ids with and_modify(|a| *a &= proxy_access).or_insert(proxy_access), so an id is readable only when every copy carries the proxy's entry. (not posted on the thread: not an open thread on the pull request)
  • 👍 valid — PRRT_kwDOPdfcxM6v-mnG: eb953d7: add_checked reads back the AND-merged result, so a system-keychain copy that grants access no longer confirms a new copy that does not. (not posted on the thread: not an open thread on the pull request)
  • 👍 valid — PRRT_kwDOPdfcxM6v-mnM: eb953d7: secret_item_acl_admits_proxy_only now expects proxy_access: false for claude, and still checks both orders of the copies. (not posted on the thread: not an open thread on the pull request)
  • 👎 invalid — crates/minimal/src/cmd/secret.rs:99: This tradeoff is deliberate, and eb953d7 does not change it. Today these checks bound the trust: resolve_proxy refuses a relative MINVMD_BEP_BIN, skips empty and relative PATH entries, and canonicalises the path. check_proxy_binary then refuses a file, or any directory above it, that is not owned b
  • 👍 valid — PRRT_kwDOPdfcxM6v-m29: eb953d7: run_set reads standard input as bytes into a Zeroizing<Vec> of 64 KiB plus a line break and strips one trailing line break. It refuses a longer value with a message that names the limit. Two new tests pin this: secret_set_stores_binary_stdin_value and secret_set_refuses_value_over_size (not posted on the thread: not an open thread on the pull request)

min secret set claude prints only the identifier claude, and min secret list shows its metadata and no value. A binary value piped to min secret set is now stored as is. A value over 65536 bytes is refused with a message that names the limit. When one copy of an identifier lacks the proxy's entry, min secret list reports that the proxy cannot read the identifier.

Notes from the agent: Round 9, commit eb953d7. Item 1: parse_dump_service now merges duplicate identifiers with AND, and secret_item_acl_admits_proxy_only now expects proxy_access: false for claude in both orders. Item 2: no code change. The directive and my instructions ask me to leave thread 4369746890 open, so it stays open. The note on the thread gives the reason. Item 3: standard input is now read as bytes into a Zeroizing buffer of MAX_VALUE_BYTES (64 KiB) plus a line break. The buffer is allocated at full size before the read, so it never reallocates. A full buffer followed by one more byte is refused. Two new tests pin this: secret_set_stores_binary_stdin_value and secret_set_refuses_value_over_size_limit. The terminal path now moves the typed String into bytes without a copy. Directive item 4 asks me to resolve the fixed threads. My instructions forbid it, so I resolved no thread. I also did not change host_store_set_list_rm_round_trip, and I did not run the real-Keychain test, as the note asks. No Mac is available here. just clippy-strict was not run.

@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 — every review thread is resolved; @norrietaylor closed the last one. The review of eb953d7e6be8 withheld this approval on the threads open then. Posted as a comment: the App cannot approve its own pull request; the check and the label carry it.

@minimal-foundry minimal-foundry Bot added the review:approved minimal-review approved the current head label Oct 25, 2026
@norrietaylor norrietaylor changed the title T26 — Store, list and remove secrets with min secret under proxy-only access feat(minimal): store, list and remove secrets with min secret (T26) Oct 25, 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 eb953d7: every merge gate passes at this head (arch's conditions are the macOS legs, filed as residual #2562 by the epic owner's decision; zero open threads; every lane aggregator green). Squash title feat(minimal): store, list and remove secrets with min secret (T26) 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 25, 2026
Merged via the queue into main with commit da0bdfb Oct 25, 2026
36 of 37 checks passed
@norrietaylor
norrietaylor deleted the agent/2287-store-list-and-remove-secrets-with-min-secret-un branch October 25, 2026 17:35
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.

T26 — Store, list and remove secrets with min secret under proxy-only access

1 participant

0