Repository navigation
T18 — Render an entry's or a box's expanded spec - #3290
Conversation
min box spec <box> reads the spec stored beside the box's record (spec.json). The RPC name joins the dispatch table in rpc.rs.
An argument is an entry of the project that --repo-dir names, else a box address. The entry form expands the entry, applies the override flags as min box start does, and names the layer of each value. The box form reads the stored spec with GetBoxSpec. Both write toml, json or yaml with -o. With no argument, the proxy rows render as before.
|
Important Review skippedBot user detected. To trigger a single review, invoke the
|
|
Undrafted by the BCLI babysitter under the owner's standing rules. The only file outside |
|
Reviewed: 1 finding, none blocking at Address the comments on the diff. Clobber: none found. |
There was a problem hiding this comment.
arch-review: CONDITIONS · 4 conditions · the full ruling
The box form, the GetBoxSpec RPC and the secret redaction conform to the design. The entry form drops --loadout. A task entry renders where min box start refuses with exit 2 (C1). A session entry renders with a loadout that start cannot resolve (C2). Line 1234 says the render is exactly what the host receives. The removed path form also breaks scripts/session-e2e.sh at lines 14374 and 14650 (C3). The CLI reference still documents [PATH], and no issue tracks that (C4).
Outside the diff
scripts/session-e2e.sh:14374: C3 · This call passes a directory as the positional argument. After this PR, the argument reads as a box address and exits 4. Change it tomnl box spec --repo-dir "$GRANT_SEED_DIR".scripts/session-e2e.sh:14650: C3 · This is the same removed path form. Change it tomnl box spec --repo-dir "$GRANT_SEED_DIR".docs/reference/cli-min.md:589: C4 · This line documents the removed grammar. Document the entry, box and no-argument forms, with-oand--repo-dir.
Ruled at 00018a0 against gominimal/arch@15b603e6afb8 by claude-opus-5-5.
|
/revise Head 1. C1: 2. C2: the session branch resolves the loadout selection as start does. 3. C3: 4. C4:
Reply on the arch threads with the commit. Run the whole |
|
That Nothing to type again: the command gets a rocket when its round starts, or a refusal that names the reason. No round was counted for it yet. |
|
Round 1 of 10 on a failed check suite: the coder changed nothing. every commit this round put on the branch above 00018a0 is a merge of the base branch, so it carries no work of its own |
…entry-s-or-a-box-s-expanded-spec # Conflicts: # crates/minimal/src/tests.rs
A task entry refuses --loadout with exit 2, as min box start refuses it. A session entry resolves the loadout selection from the client config that start reads, fails on a missing loadout with start's error, and names the selected loadouts in each output format.
The reference shows the entry, box and project forms. The session e2e names the demo project with --repo-dir, because a bare argument is now an entry or a box, never a directory.
…entry-s-or-a-box-s-expanded-spec
There was a problem hiding this comment.
arch-review: CONDITIONS · 2 conditions · the full ruling
The entry and box forms conform in placement, flags, addressing and redaction. Two gaps remain in the machine-output contract. The -o json document of each form has no schema field, and section Output conventions line 381 requires min/v1/<type> on every object. Add ObjectType::Spec.schema() to both documents (C1). A failure under min box spec -o json prints plain text, because machine_output_mode() in main.rs has no arm for box spec. Line 383 requires one min/v1/error object on stderr. Add the arm (C2).
Outside the diff
crates/minimal/src/main.rs:627: C2 ·machine_output_mode()has no arm forBoxCommand::Spec. Amin box spec -o jsonfailure is then plain text. Line 383 requires onemin/v1/errorobject on stderr. Add the arm for-o jsonand-o yaml, and add a test case.
Ruled at 1eda4a9 against gominimal/arch@15b603e6afb8 by claude-opus-5-5.
|
Round 2 of 10 on a /revise note, pushed as Resolved conflicts in:
Verify Outside the task's
Converted to a draft: something above needs a person before review. Review threads the coder judged:
Notes from the agent: Revise round 2. The merge of origin/main conflicted only in crates/minimal/src/tests.rs. Both sides appended tests, so the resolution keeps both, and the merge commit completes it. C1: the task branch of expand_entry refuses --loadout with exit 2, next to --ingress. box_spec_entry_network_flags_match_start checks that start refuses both flags too. C2: the session branch reads the client config with crate::config::read_client_config and calls loadouts::resolve_active_loadouts(LoadoutSelection::from_flags(&overrides.loadout, false), ...). A missing loadout fails with start's error. The selected names render as a |
Add the min/v1/spec schema to the -o json and yaml documents of both forms. Show only a stored grant's reference keys in the box form. Parse an entry's grants before the render strips them, so a grant that min box start refuses is refused here too. Quote YAML scalars outside a narrow safe set. Read the argument as a box address when minimal.toml does not load, and keep the project file error when no box matches.
There was a problem hiding this comment.
arch-review: CONDITIONS · 2 conditions · the full ruling
The schema stamp, the stored-grant filter, the grant parse and the YAML quoting conform to lines 381 and 384. The new fallback in box_spec_to() does not conform. When minimal.toml does not load, it reads every target as a box address. A bare name is an entry first, and line 476 says the entry form exits 3 on an invalid file. With [tasks.build and a box named build, the command now shows the box and exits 0. Apply C1 to limit the fallback to a qualified address, a full id or self. Apply C2 to make the test prove that rule.
Ruled at 69b7227 against gominimal/arch@15b603e6afb8 by claude-opus-5-5.
|
/revise Head 1. C1: an invalid project file blocks the entry form, not a box address.
For every other target, return 2. C2: the test pins both halves.
Keep the Reply on the arch threads with the commit. Run the whole |
|
That Nothing to type again: the command gets a rocket when its round starts, or a refusal that names the reason. No round was counted for it yet. |
…entry-s-or-a-box-s-expanded-spec # Conflicts: # crates/minimal/src/tests.rs
With a minimal.toml that does not load, min box spec takes the box form only for a qualified address, a full box id or self. Any other target can name an entry, so it fails with the project file error (exit 3).
|
/revise Head |
|
That Nothing to type again: the command gets a rocket when its round starts, or a refusal that names the reason. No round was counted for it yet. |
|
Round 4 of 10 on a /revise note, pushed as Resolved conflicts in:
Verify Outside the task's
Converted to a draft: something above needs a person before review. Review threads the coder judged:
Notes from the agent: The merge with origin/main had a conflict in crates/minimal/src/tests.rs. Both sides only added tests (the box spec tests and concept_and_reference_docs_use_no_removed_session_verb), so the merge commit b1fdde6 keeps both. The other files in the merge diff come from main. The fix for C1 and C2 is commit af61b5a. I ran the six minimal test lines once, as part of the whole minimal suite, so only one of them has its own run. The directive said to change nothing else, so I did not change json_to_toml (see its thread). |
There was a problem hiding this comment.
arch-review: PASS · the full ruling
The last commit makes an invalid minimal.toml block the entry form. A bare name now fails with exit 3, and only a full box id or a qualified address reads as a box. This matches the exit 3 that architecture.md line 476 gives an invalid file, and it fails closed. The earlier conditions stay met, and the merge from main does not touch this path. One residual stays open: the entry render does not fold loadout values yet (#3236).
Ruled at af61b5a against gominimal/arch@15b603e6afb8 by claude-opus-5-5.
|
Round 5 of 10 on a /revise note: the coder changed nothing. every commit this round put on the branch above af61b5a is a merge of the base branch, so it carries no work of its own |
T18 — Render an entry's or a box's expanded spec
slice: S5
kind: task
covers: BCLI-021, BCLI-022, BCLI-023
size: L
est: 340 code, 480 tests
executor: agent
difficulty: routine
model: standard
diagnostics:
min box spec <entry>prints each value with the layer and type it came from, and a secret as its reference only, pinned by box_spec 8000 _renders_formats_secrets_as_refsobservability: the command's existing tracing span records the verb, the box id it resolved and the outcome
layers:
- client:
- crates/minimal/src/cli.rs: the verb's arguments and help in the one command model
- crates/minimal/src/cmd/mod.rs: dispatches the verb
- crates/minimal/src/cmd/box_spec.rs: the entry and box forms,
-o toml|json|yaml, the layer and type beside each value- crates/minimal/src/tests.rs: the in-process minimald test harness gains this layer's tests
test: cargo nextest run -p minimal box_spec_renders_formats_secrets_as_refs
test: cargo nextest run -p minimal box_spec_path_form_renders_bep_rows
test: cargo nextest run -p minimal box_spec_entry_network_flags_match_start
test: cargo nextest run -p minimal box_spec_box_renders_stored_copy
test: cargo nextest run -p minimal box_spec_argument_directory_then_entry_then_box
test: cargo nextest run -p minimal box_spec_renders_unenforced_sections
- daemon:
- crates/minimald-rpc/src/lib.rs: a
GetBoxSpecrequest returns a box's stored spec (spec.json) to the client- crates/minimald/src/box_manager.rs: answers
GetBoxSpecfrom the box's stored spec.jsontest: cargo nextest run -p minimald get_box_spec_returns_stored_spec
produces: none
consumes:
- crates/minimal/src/cmd/boxes/address.rs
proof:
min box specshows an entry's expanded spec before start and a box's stored spec after, with the source of every value.depends on:
- blocked by #2895
- blocked by #2877
- blocked by #2878
Proof
In a project,
min box spec <entry>prints the entry's expanded spec before any start, as TOML (default), JSON or YAML with -o. Each value names its source: the minimal.toml table that set it ([defaults], [sessions.default] and so on),the command linefor an override flag, orthe default. A secret prints as its reference only. With the same --network and egress flags, it prints the network thatmin box startsends.min box spec <box>prints the spec stored with the box's record.min box specwith no argument still prints the proxy rows for the project that --repo-dir names.Notes from the agent: Outside the layers: crates/minimald/src/rpc.rs gains serve_get_box_spec and two dispatch lines for GetBoxSpec. A new RPC cannot be served without them.
Spec over task: the task's test name box_spec_argument_directory_then_entry_then_box says a directory is read first. The spec excerpt (BCLI-022 sub-bullet and the 2026-11-09 ruling) says the argument is never a directory, so the positional PATH is removed. The project form is only --repo-dir/-C now. The test keeps the task's name and checks that a directory path is read as a box address (exit 4). docs/reference/cli-min.md line 589 still documents
min box spec [--network ...] [PATH]. That file is not in the layers, so a follow-up must update it.How the entry form matches start: start does not yet send the expanded spec (BOX-065 bytes). It sends BoxSpec v0, with network computed from the flags. So the entry form renders mfile::expand's spec and report, which is the expansion start uses for the daemon entry. Its [network] mode/egress/ingress are then replaced with the values that project_egress, effective_egress, flag_network_overrides and network_override_policy give, the same calls start makes. For a session entry with no --network, the mode is the start default (host_ip), because start ignores the entry's network.mode (#3238). Task entries follow the min box run rule (flag, then file, then defaul…[truncated]
Tests
cargo nextest run -p minimal box_spec_renders_formats_secrets_as_refscargo nextest run -p minimal box_spec_path_form_renders_bep_rowscargo nextest run -p minimal box_spec_entry_network_flags_match_startcargo nextest run -p minimal box_spec_box_renders_stored_copycargo nextest run -p minimal box_spec_argument_directory_then_entry_then_boxcargo nextest run -p minimal box_spec_renders_unenforced_sectionscargo nextest run -p minimald get_box_spec_returns_stored_specVerify
min task run agent-verifytimed out after 1800s, so this PR is a draft.Out of scope
These files are outside the task's
layers:, so this PR is a draft:crates/minimald/src/rpc.rsCloses #2906