8000 T20 — Scaffold and append entries with min init by minimal-foundry[bot] · Pull Request #2962 · gominimal/minimal · GitHub
[go: up one dir, main page]

Skip to content

T20 — Scaffold and append entries with min init - #2962

Open
minimal-foundry[bot] wants to merge 12 commits into
mainfrom
agent/2893-scaffold-and-append-entries-with-min-init
Open

minimal-foundry[bot] wants to merge 12 commits into
mainfrom
agent/2893-scaffold-and-append-entries-with-min-init

Conversation

@minimal-foundry
@minimal-foundry minimal-foundry Bot commented Nov 4, 2026 •
Copy link
Copy Markdown
Contributor

T20 — Scaffold and append entries with min init

slice: S5
kind: task
covers: BCLI-017, BCLI-018
size: L
est: 200 code, 300 tests
executor: agent
difficulty: routine
model: standard
diagnostics: when two of --session, --task, --agent, --service and --type are given, min init prints "Pass one of --session, --task, --agent, --service or --type." and changes nothing, pinned by init_noun_flags_exclusive_exit2_appends_nothing
observability: 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/project.rs: min init scaffolds the entry shape and appends one entry by --type or a noun flag
test: cargo nextest run -p minimal init_scaffolds_entry_shape
test: cargo nextest run -p minimal init_entry_type_appends_one
test: cargo nextest run -p minimal init_refused_type_exit3_appends_nothing
test: cargo nextest run -p minimal init_noun_flag_is_type_alias
test: cargo nextest run -p minimal init_noun_flags_exclusive_exit2_appends_nothing
produces: none
consumes: none
proof: min init writes an entry-shaped minimal.toml, and min init <entry> --type <type> appends one entry.

Residuals

  • BCLI-017's entry-shape scaffold is built and tested, but off by default. min init with no flags writes the legacy [session] shape (INIT_ENTRY_SHAPE = false). On main, box creation does not read [defaults.<type>] yet, so an entry-shaped scaffold would lose its packages at session start. BOX T21 (T21 — One minimal.toml for every box, end to end #2418) wires mfile::expand into box creation. When T21 — One minimal.toml for every box, end to end #2418 lands, min init and offer_mfile_scaffold write the entry shape, and the entry_shape parameter is removed. The owner decided this on 2026-11-06.
  • crates/minimal/src/cmd/mod.rs is outside T20's layers:. Arch ruling 808 C1 required the change so that an InitRefusal reaches failure_exit_code.
  • Where the Proof section below says min init writes the entry shape, that is superseded: at this head, bare min init writes the legacy [session] shape (see the first residual), and init_no_flags_writes_legacy_shape pins it.
  • The agent's note 1 below is superseded. Refusals now return through main.rs failure_exit_code (exit 2 for usage, 3 for invalid minimal.toml), and exit_refused is gone.

Proof

min init now writes minimal.toml in the entry shape: [defaults.session] with the packages, [defaults.task] with state_key, and a [boxes.dev] entry with type = "session". min init <entry> --type <type> appends one [boxes.] entry and keeps the rest of the file. min init --session <n> (also --task, --agent, --service) writes the same file as min init <n> --type <noun>. If you give more than one of these flags, min init prints "Pass one of --session, --task, --agent, --service or --type.", exits 2 and changes nothing. A type that is, or extends, agent, service, build or container-build is refused with exit 3 and changes nothing.

Notes from the agent: 1. Exit codes: crates/minimal/src/cmd/mod.rs turns every cmd_init error into a string, so main.rs can only give exit 1. mod.rs and main.rs are outside the layers. For this reason cmd_init prints its refusal and calls std::process::exit with the code (2 or 3) itself. The tests check the code on the InitRefusal value and do not run the binary. A later task can route this through failure_exit_code. 2. Nothing in this tree reads [boxes.*], [defaults.session] or [defaults.task] yet. mfile logs them as unknown fields. So a project scaffolded by min init gets no session packages from minimal.toml at activation until the BOX entry expansion lands. For this reason the scaffold offer in min activate (offer_mfile_scaffold) keeps the legacy [session] shape. run_init_flow takes a new entry_shape flag for this. 3. Choices the spec does not fix: appended entries go under [boxes.] with type. An unknown type, an entry with no type, or --type with no entry exits 2. A duplicate entry name in boxes/sessions/tasks/agents/services exits 1. A missing minimal.toml exits 1 and tells the user to run min init first. Project types resolve through the [box_types.] extends chain to a built-in root. 4. The exit-3 refusal names gominimal/inbox#678 because BOX-063 requires it. That is an issue reference, not a co…[truncated]

Tests

line exit tail
cargo nextest run -p minimal init_scaffolds_entry_shape 0 Applying loadouts: default Running task runtime-implement-test-0 in session task-runtime-implement-test-0-ea7c... Compiling paths v0.0.1 (/workbench/crates/paths) Compiling args v0.0.1 (/workbench/crates/args) Compiling ot v0.0.1 (/workbench/crates/ot) Compiling client-config v0.0.1 (/wo
cargo nextest run -p minimal init_entry_type_appends_one 0 Applying loadouts: default Running task runtime-implement-test-1 in session task-runtime-implement-test-1-b9e1... 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 init_refused_type_exit3_appends_nothing 0 Applying loadouts: default Running task runtime-implement-test-2 in session task-runtime-implement-test-2-f71d... 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 init_noun_flag_is_type_alias 0 Applying loadouts: default Running task runtime-implement-test-3 in session task-runtime-implement-test-3-57cb... 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 init_noun_flags_exclusive_exit2_appends_nothing 0 Applying loadouts: default Running task runtime-implement-test-4 in session task-runtime-implement-test-4-f6b9... 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 100 under rustc 1.99.0, which the repository does not pin (1.99.1 in rust-toolchain.toml); the PR is not a draft on that alone — CI, which honours the pin, is the gate.

dSpan {
            name: "session.message",
            fields: {
                "kind": "GetNetSwitch",
                "parent_span_id": "4d32eab524d7aa5d",
                "span_id": "d87052db788d3fe6",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "session.message",
            fields: {
                "kind": "GetDenyAllOptOut",
                "parent_span_id": "4d32eab524d7aa5d",
                "span_id": "58fa204b5107cd34",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "session.message",
            fields: {
                "kind": "GetPaths",
                "parent_span_id": "4d32eab524d7aa5d",
                "span_id": "621f0838437b9ae3",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "sessions.manager.message",
            fields: {
                "kind": "GetRecord",
                "parent_span_id": "4d32eab524d7aa5d",
                "queued_behind": "0",
                "span_id": "ff4923eaca352e7b",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "sessions.manager.message",
            fields: {
                "kind": "DeleteSession",
                "parent_span_id": "4d32eab524d7aa5d",
                "queued_behind": "0",
                "span_id": "f69f9b446e94d011",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "session.message",
            fields: {
                "kind": "Destroy",
                "parent_span_id": "f69f9b446e94d011",
                "span_id": "aa6279837661646d",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "sessions.manager.message",
            fields: {
                "kind": "HandOverName",
                "parent_span_id": "f69f9b446e94d011",
                "queued_behind": "0",
                "span_id": "2b2269a2cfba576a",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
    ]
    note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

  Cancelling due to test failure: 
────────────
     Summary [  37.064s] 853 tests run: 852 passed, 1 failed, 1 skipped
        FAIL [   3.886s] (853/853) minimal::otel_cli exec_run_attach_and_task_run_share_the_commands_trace
error: test run failed

Closes #2893

min init now writes minimal.toml in the entry shape: [defaults.session],
[defaults.task] and a [boxes.dev] session entry. min init <entry> --type
<type> appends one [boxes.<entry>] entry. --session, --task, --agent and
--service are aliases for --type with that noun. More than one of them, or
one with --type, ends with exit 2 and the file unchanged. A type that is,
or extends, agent, service, build or container-build ends with exit 3.

The activate scaffold offer keeps the legacy shape, because this tree
does not read entries at activation yet.
@coderabbitai
coderabbitai Bot commented Nov 4, 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: a98e5621-2e79-499c-91ce-8665a9f91ff4

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

@minimal-foundry
minimal-foundry Bot commented Nov 4, 2026 •
Copy link
Copy Markdown
Contributor Author

Reading bef69e747528.

This comment updates when the review finishes.

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

Choose a reason for hiding this comment

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

minimal-review — approved

Verdict APPROVE — No findings.

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

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

Choose a reason for hiding this comment

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

arch-review: CONDITIONS · 3 conditions · the full ruling

The scaffold shape and the append conform to architecture.md line 448 and lines 1173–1176. A refusal ends the process with std::process::exit inside the root span. The spool records a span only when it ends, so D9 (line 793) loses the refused outcome. C1 routes the exit code through failure_exit_code and adds cmd/mod.rs and main.rs to the layers. init_request accepts self and names that are not DNS-safe, against line 1176. C2 refuses them with exit 2. C3 links the legacy-shape interim to an issue with a flip condition. The escalation asks whether BCLI-017 can merge before the BOX reader of [defaults.session].

Outside the diff

  • crates/minimal/src/cmd/mod.rs:294: C1 · This arm formats the error to a string, and the InitRefusal type is lost. Map mctx::Error::Other(e) to e, and format only the other variants.
  • crates/minimal/src/main.rs:208: C1 · Add a branch: when e.downcast_ref::<minimal::InitRefusal>() matches, return refusal.code as u8. Add a test for exit 2 and exit 3.

Ruled at 5c90f9d against gominimal/arch@7a86ec7bb3c0 by claude-opus-5-5.

Comment thread crates/minimal/src/cmd/project.rs Resolved
Comment thread crates/minimal/src/cmd/project.rs Resolved
Comment thread crates/minimal/src/cmd/project.rs Resolved
@mitodrummer
Copy link
Copy Markdown
Member

Held by the maintainer: this waits on BOX T15 (#2409), which reads [boxes.*], [defaults.session] and [defaults.task]. Until then a scaffolded project would start boxes without its packages (arch's ruling on this head). Don't merge before #2409 lands. Arch's C1 (the exit-code path through cmd/mod.rs/main.rs) and C2 (entry-name validation) still apply when it resumes.

@agent-137
Copy link
Copy Markdown
Member

/revise

Head 5c90f9dc. This PR was held on #2409, and #2409 is now closed: #3091 (BOX T15, "Read the type tables as box entries") merged at 2026-11-06T16:33Z. Bring the branch up to date with main first. Then answer arch ruling 808's three conditions (threads PRRT_kwDOPdfcxM6zZDKA, PRRT_kwDOPdfcxM6zZDKD, PRRT_kwDOPdfcxM6zZDKG).

1. C1: a refusal must end through main.rs, not exit_refused (D9, architecture line 793).

Delete exit_refused in crates/minimal/src/cmd/project.rs. cmd_init returns each refusal as Err(mctx::Error::Other(anyhow::Error::new(refusal))), after its tracing::info! outcome record. Make InitRefusal pub and re-export it as minimal::InitRefusal. 8000 In crates/minimal/src/cmd/mod.rs, the Some(Command::Init(args)) arm maps mctx::Error::Other(e) to e, so the type survives. In crates/minimal/src/main.rs, failure_exit_code returns refusal.code when e.downcast_ref::<minimal::InitRefusal>() matches, beside the other typed refusals. Add a main.rs test: 2 for the INIT_ONE_TYPE_FLAG refusal and 3 for a refused type. cmd/mod.rs and main.rs are outside this task's layers:, and arch C1 names them, so the change is in scope.

2. C2: entry names (architecture line 1176, Addressing line 390).

In init_request, replace the entry.trim().is_empty() check with an entry-name check. Return InitRefusal::usage (exit 2) for self, and for a name that is not a DNS label: 1 to 63 characters of a-z, 0-9 and -, with no - at the start or end. The message names the rejected value and the rule. Run the check before any file read. Add init_entry_name_invalid_exit2_appends_nothing for self, My_Box, -dev and a 64-character name, and assert that minimal.toml is unchanged after each.

3. C3: the two-shape interim is no longer needed. Remove it.

C3 asked for an issue for the BOX reader of [boxes.*], [defaults.session] and [defaults.task]. That reader is #2409, and it is now on main. So take the flip now, not a residual: offer_mfile_scaffold scaffolds the entry shape, and the entry_shape parameter of run_init_flow is removed with its interim comments. After a plain min init, min session start must get the scaffold's [defaults.session] packages (architecture lines 576–577). Add or extend a test that reads the scaffolded file through mfile and shows the session entry carries those packages. If the reader on main does not cover something the scaffold writes, say what in the PR body as a residual with an issue link. Do not keep the switch.

cmd_init returns an InitRefusal as its error, so the cmd span closes and
its outcome record reaches the spool. failure_exit_code in main.rs gives
the refusal's code (2 or 3). exit_refused is gone.

min init refuses the entry name self, and a name that is not a DNS label,
with exit 2 before it reads any file.

The activate scaffold stays in the legacy shape: session start does not
read [defaults.session] yet. The comment names #2410 as the flip.
@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 — 1 finding, 1 inline.

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

Comment thread crates/minimal/src/cmd/project.rs Resolved
@minimal-foundry minimal-foundry Bot removed the review:approved minimal-review approved the current head label Nov 6, 2026
@minimal-arch minimal-arch Bot left a comment
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

arch-review: CONDITIONS · 3 conditions · the full ruling

The compare fixes the exit path. Refusals now end through failure_exit_code, and the cmd span closes. Three exit codes still do not agree with the design. Line 1176 makes self, a name that is not DNS-safe, and a duplicate name invalid minimal.toml, and line 364 gives exit 3 for that. mfile::entry already uses 3. C1 and C2 change check_entry_name and the duplicate check to code 3, and C2 also replaces ENTRY_TABLES with EntryTable::ALL. C3 makes a [box_types] entry with no extends exit 3, as line 1232 states.

Ruled at af34c8a against gominimal/arch@7a86ec7bb3c0 by claude-opus-5-5.

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

Round 1 of 10 on a /revise note, pushed as af34c8a2f73c.

line exit tail
cargo nextest run -p minimal init_scaffolds_entry_shape 0 Applying loadouts: default Running task runtime-implement-test-0 in session task-runtime-implement-test-0-8bd5... Compiling paths v0.0.1 (/workbench/crates/paths) Compiling args v0.0.1 (/workbench/crates/args) Compiling ot v0.0.1 (/workbench/crates/ot) Compiling client-config v0.0.1 (/wo
cargo nextest run -p minimal init_entry_type_appends_one 0 Applying loadouts: default Running task runtime-implement-test-1 in session task-runtime-implement-test-1-ec42... 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 init_refused_type_exit3_appends_nothing 0 Applying loadouts: default Running task runtime-implement-test-2 in session task-runtime-implement-test-2-a1a7... 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 init_noun_flag_is_type_alias 0 Applying loadouts: default Running task runtime-implement-test-3 in session task-runtime-implement-test-3-0993... 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 init_noun_flags_exclusive_exit2_appends_nothing 0 Applying loadouts: default Running task runtime-implement-test-4 in session task-runtime-implement-test-4-bd1d... 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 100 under rustc 1.99.0, which the repository does not pin (1.99.1 in rust-toolchain.toml); the PR is not a draft on that alone — CI, which honours the pin, is the gate.

lds: {
                "parent_span_id": "2685e1016e2c9cdd",
                "rpc": "minimald-v1-GetSessionRecord",
                "span_id": "8cd08c318f948f40",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "sessions.manager.message",
            fields: {
                "kind": "GetRecord",
                "parent_span_id": "8cd08c318f948f40",
                "queued_behind": "0",
                "span_id": "941ffc216db1259e",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "rpc",
            fields: {
                "parent_span_id": "2685e1016e2c9cdd",
                "rpc": "minimald-v1-DestroySession",
                "span_id": "b6eb3e57ca47d078",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
    
10000
    LoggedSpan {
            name: "sessions.manager.message",
            fields: {
                "kind": "GetRecord",
                "parent_span_id": "b6eb3e57ca47d078",
                "queued_behind": "0",
                "span_id": "81f44c8fd83cfef3",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "sessions.manager.message",
            fields: {
                "kind": "DeleteSession",
                "parent_span_id": "b6eb3e57ca47d078",
                "queued_behind": "0",
                "span_id": "f5392fac98007a17",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "session.message",
            fields: {
                "kind": "Destroy",
                "parent_span_id": "f5392fac98007a17",
                "span_id": "d6c7b3573aaccfc2",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "sessions.manager.message",
            fields: {
                "kind": "HandOverName",
                "parent_span_id": "f5392fac98007a17",
                "queued_behind": "0",
                "span_id": "1003a38bb6943804",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
    ]
    note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

  Cancelling due to test failure: 
────────────
     Summary [  69.372s] 948 tests run: 947 passed, 1 failed, 1 skipped
        FAIL [   3.856s] (948/948) minimal::otel_cli exec_run_attach_and_task_run_share_the_commands_trace
error: test run failed

Outside the task's layers::

  • crates/minimal/src/cmd/mod.rs

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

Review threads the coder judged:

  • 👍 valid — crates/minimal/src/cmd/project.rs: Removed exit_refused. cmd_init returns the InitRefusal as mctx::Error::Other after its outcome record, the Init arm in cmd/mod.rs keeps the type, and failure_exit_code in main.rs returns its code. The test is init_refusals_exit_with_their_codes.
  • 👍 valid — crates/minimal/src/cmd/project.rs: init_request now calls check_entry_name before any file read. It refuses self and any name that mfile::entry::is_dns_safe rejects with exit 2, and the message names the value and the rule. The test is init_entry_name_invalid_exit2_appends_nothing.
  • 👍 valid — crates/minimal/src/cmd/project.rs:532: The switch comments now name T16 — Fold the layers into one expanded spec, the same bytes every run #2410 (T16, BOX-064) as the reader of [defaults.]. They say that offer_mfile_scaffold passes true when T16 — Fold the layers into one expanded spec, the same bytes every run #2410 lands, and that the parameter is then removed. I did not flip it now: T15 — Read the type tables as box entries #3091 does not make session start read [defaults.session], so the flip would drop the

min init writes an entry-shaped minimal.toml, and min init <entry> --type <type> appends one entry. A refused request now ends with exit 2 and a refused type with exit 3 through main.rs, so the refused outcome record reaches the spool. The names self, My_Box, -dev and a 64-character name are refused with exit 2, and minimal.toml does not change.

Notes from the agent: The branch already contained origin/main (merge 1a65936 includes #3091), so no new merge was necessary. C1 and C2 are done as the directive asks. cmd/mod.rs and main.rs are outside layers:, and the directive names them. InitRefusal.code is now u8, because failure_exit_code returns u8. INIT_ONE_TYPE_FLAG is now pub so that the main.rs test can use it. C3 is NOT done as the directive asks, on purpose. The premise is that the reader of [defaults.session] is on main. It is not. #3091 adds mfile::entry::read_entries, which nothing outside mfile calls. It reads only the entry tables. mfile::File still has no [defaults.session]: that key lands in Defaults.extra and logs 'unknown fields in [defaults]'. Session start reads packages only from the legacy [session]. If the activate scaffold flips to the entry shape, a plain min session activate scaffold writes packages that session start ignores. The test the directive asks for (the session entry carries the [defaults.session] packages through mfile) cannot pass without a change to crates/mfile, which is outside this task. I kept the entry_shape switch, and its comments now name #2410 (T16, BOX-064, the expansion over [defaults.]) as the flip condition: pass true in offer_mfile_scaffold, then remove the parameter. This is the original C3 thread's request. The PR body needs this residual: the [defaults.session] reader is #2410, not #2409. The same gap applies to the min init scaffold itself (BCLI-017): its [defaults.session] packages are not read at session start until #2410. The existing tests in cmd/project.rs init_tests carry the task'…[truncated]

@minimal-foundry
minimal-foundry Bot marked this pull request as draft November 6, 2026 17:17
@agent-137
Copy link
Copy Markdown
Member

/revise

Head af34c8a2. Round 1 answered ruling 808. Arch ruling 1014 on this head rules that BCLI-017 conforms. It has three exit-code conditions on BCLI-018. Do these and nothing else.

1. C1: an invalid entry name is a minimal.toml error, exit 3.

In crates/minimal/src/cmd/project.rs check_entry_name(), return InitRefusal { code: 3, .. } for self and for a name mfile::entry::is_dns_safe rejects, in place of InitRefusal::usage (2). Keep the check before any file read. This matches mfile::entry (Error::InvalidEntryName exits 3), architecture lines 1176 and 364, and BOX-007 and BOX-046 (spec 29 lines 96 and 260). Rename init_entry_name_invalid_exit2_appends_nothing to init_entry_name_invalid_exit3_appends_nothing, and assert code 3 at both of its assert_eq!(.., 2, ..) lines.

2. C2: a duplicate entry name exits 3, and the table list has one owner.

In append_entry_text(), refuse a name that is already declared with code: 3, not code: 1. Remove the local ENTRY_TABLES constant, and iterate mfile::entry::EntryTable::ALL with EntryTable::key() in its place. In init_entry_type_appends_one, change assert_eq!(refusal.code, 1) for the duplicate site to assert_eq!(refusal.code, 3).

3. C3: a [box_types] entry with no extends exits 3 (architecture line 1232).

In resolve_builtin_root(), when [box_types.<current>] is present but has no extends, refuse with code: 3, and name the type and the missing extends key. Keep the exit-2 message "is not a built-in type or a [box_types] entry" only for a type with no [box_types] table at all. Add a test that min init x --type web exits 3 and leaves the file unchanged when the file has [box_types.web] and no extends.

Also add one line to the PR body, before the notes: crates/minimal/src/cmd/mod.rs is outside T20's layers:, and arch ruling 808 C1 required the change so that an InitRefusal reaches failure_exit_code.

@agent-137
agent-137 marked this pull request as ready for review November 6, 2026 17:24
@agent-137
Copy link
Copy Markdown
Member

Marked ready by the BCLI babysitter, with the owner's approval. The runtime drafted this PR because crates/minimal/src/cmd/mod.rs is outside T20's layers:. Arch ruling 808 C1 required that change, so that an InitRefusal reaches failure_exit_code. arch-review and minimal-review do not run on a draft. Merging still waits for every gate on the current head.

An entry name that is self or not DNS-safe, a duplicate entry name, and
a [box_types] entry with no extends make minimal.toml invalid, so min
init refuses them with exit 3. The duplicate check reads the entry tables
from mfile::entry::EntryTable::ALL.
@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: 9 unresolved threads — minimal-arch[bot] crates/minimal/src/cmd/project.rs, minimal-arch[bot] crates/minimal/src/cmd/project.rs, minimal-arch[bot] crates/minimal/src/cmd/project.rs:532, minimal-foundry[bot] crates/minimal/src/cmd/project.rs:839, minimal-arch[bot] crates/minimal/src/cmd/project.rs, …. 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 · the full ruling

The compare resolves the open conditions. An invalid entry name, self, a duplicate name and a [box_types] entry with no extends now exit 3. This agrees with design lines 1176 and 1232 and the exit-code table. The flag conflicts stay exit 2, as line 448 states. The duplicate check now uses mfile::entry::EntryTable::ALL, so mfile owns the table list. Two residuals stay open: #2410 for reading [defaults.session], and gominimal/inbox#579 for organization types.

Ruled at 127ec0e against gominimal/arch@7a86ec7bb3c0 by claude-opus-5-5.

@minimal-foundry
Copy link
Copy Markdown
Contributor Author

Round 2 of 10 on a /revise note, pushed as 127ec0ee8d8f.

line exit tail
cargo nextest run -p minimal init_scaffolds_entry_shape 0 Applying loadouts: default Running task runtime-implement-test-0 in session task-runtime-implement-test-0-37a2... Compiling paths v0.0.1 (/workbench/crates/paths) Compiling ot v0.0.1 (/workbench/crates/ot) Compiling args v0.0.1 (/workbench/crates/args) Compiling client-config v0.0.1 (/wo
cargo nextest run -p minimal init_entry_type_appends_one 0 Applying loadouts: default Running task runtime-implement-test-1 in session task-runtime-implement-test-1-2503... 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 init_refused_type_exit3_appends_nothing 0 Applying loadouts: default Running task runtime-implement-test-2 in session task-runtime-implement-test-2-4119... 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 init_noun_flag_is_type_alias 0 Applying loadouts: default Running task runtime-implement-test-3 in session task-runtime-implement-test-3-5bc5... 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 init_noun_flags_exclusive_exit2_appends_nothing 0 Applying loadouts: default Running task runtime-implement-test-4 in session task-runtime-implement-test-4-c4a4... 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 100 under rustc 1.99.0, which the repository does not pin (1.99.1 in rust-toolchain.toml); the PR is not a draft on that alone — CI, which honours the pin, is the gate.

lds: {
                "parent_span_id": "1b25dfa5253dae05",
                "rpc": "minimald-v1-GetSessionRecord",
                "span_id": "b0505717a740dfaa",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "sessions.manager.message",
            fields: {
                "kind": "GetRecord",
                "parent_span_id": "b0505717a740dfaa",
                "queued_behind": "0",
                "span_id": "d134ff226a33fd43",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "rpc",
            fields: {
                "parent_span_id": "1b25dfa5253dae05",
                "rpc": "minimald-v1-DestroySession",
                "span_id": "a59e524b2b4fd43b",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "sessions.manager.message",
            fields: {
                "kind": "GetRecord",
                "parent_span_id": "a59e524b2b4fd43b",
                "queued_behind": "0",
                "span_id": "b8b7ef9348fc3dae",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "sessions.manager.message",
            fields: {
                "kind": "DeleteSession",
                "parent_span_id": "a59e524b2b4fd43b",
                "queued_behind": "0",
                "span_id": "46b04379026c053c",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "session.message",
            fields: {
                "kind": "Destroy",
                "parent_span_id": "46b04379026c053c",
                "span_id": "641c619c016ee34e",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "sessions.manager.message",
            fields: {
                "kind": "HandOverName",
                "parent_span_id": "46b04379026c053c",
                "queued_behind": "0",
                "span_id": "3770ed16cd7ca5f6",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
    ]
    note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

  Cancelling due to test failure: 
────────────
     Summary [  52.628s] 949 tests run: 948 passed, 1 failed, 1 skipped
        FAIL [   2.815s] (949/949) minimal::otel_cli exec_run_attach_and_task_run_share_the_commands_trace
error: test run failed

Outside the task's layers::

  • crates/minimal/src/cmd/mod.rs

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

Review threads the coder judged:

  • 👎 invalid — crates/minimal/src/cmd/project.rs:839: Arch ruling 1014 sets exit 3 for every invalid-minimal.toml cause (architecture line 364), which includes an unparsable file, a dangling or cyclic extends, a duplicate, and a bad name. A refused type is one of those causes. Only a type with no [box_types] entry at all is a usage error (2). The InitR
  • 👍 valid — crates/minimal/src/cmd/project.rs: check_entry_name now returns InitRefusal { code: 3 } for self and for a name that is not DNS-safe. The check still runs before any file read.
  • 👍 valid — crates/minimal/src/cmd/project.rs: Renamed the test to init_entry_name_invalid_exit3_appends_nothing. Both of its asserts now expect code 3.
  • 👍 valid — crates/minimal/src/cmd/project.rs: Removed ENTRY_TABLES. The duplicate check iterates mfile::entry::EntryTable::ALL with EntryTable::key().
  • 👍 valid — crates/minimal/src/cmd/project.rs: A duplicate entry name now refuses with code 3, and init_entry_type_appends_one asserts 3.
  • 👍 valid — crates/minimal/src/cmd/project.rs:804: A declared [box_types.] with no extends now exits 3, and the message names the table and the missing extends key. init_box_type_without_extends_exit3_appends_nothing pins this.

min init writes an entry-shaped minimal.toml, and min init <entry> --type <type> appends one entry. An invalid entry name, a duplicate entry name, or a [box_types] entry with no extends now exits 3 and leaves the file unchanged.

Notes from the agent: Revise round 2 did only the three ruling-1014 items. C1: check_entry_name returns code 3 for self and for a name that is not DNS-safe, and the check still runs before any file read. The test is renamed to init_entry_name_invalid_exit3_appends_nothing and asserts 3. C2: a duplicate entry name exits 3. The local ENTRY_TABLES constant is gone, and the check iterates mfile::entry::EntryTable::ALL with key(). C3: resolve_builtin_root refuses a declared [box_types.] with no extends with code 3. The message names the table and the missing extends key. The exit-2 message stays for a type with no [box_types] entry. The new test init_box_type_without_extends_exit3_appends_nothing pins both cases. No test: line names it, so the runner does not run it. I ran it in the init_ filter run. PR body line requested by the directive, for the runner to add before the notes: crates/minimal/src/cmd/mod.rs is outside T20's layers:, and arch ruling 808 C1 required the change so that an InitRefusal reaches failure_exit_code. This round did not touch mod.rs. cargo clippy -p minimal --all-targets reported no warnings. I did not run just clippy-strict.

@minimal-foundry
minimal-foundry Bot marked this pull request as draft November 6, 2026 17:51
@agent-137
agent-137 marked this pull request as ready for review November 6, 2026 17:52
@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; @agent-137 closed the last one. The review of 127ec0ee8d8f 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 Nov 6, 2026
@agent-137
Copy link
Copy Markdown
Member

Held by the owner until #2410 (BOX T16, PR #3093) lands. Arch passes this head, and minimal-review found nothing. But min init now writes the entry shape (project.rs:947), and mfile on main still treats [defaults.session] as an unknown key of [defaults]. Merged now, min init followed by min session start would skip the scaffold's packages. #2409 (T15) did not add that reader. #2410 does. The hold on #2893 now names #2410.

@agent-137
Copy link
Copy Markdown
Member

/revise

Head 127ec0ee. Arch passes this head, and the threads are closed. The owner decided how this PR merges. Make this one change and nothing else.

min init keeps the legacy [session] scaffold until box creation reads [defaults.<type>].

#2410 (BOX T16, #3093) merged, but it only adds mfile::expand. Its notes say nothing calls it yet, and BoxSpec::for_session is unchanged. So on main, min session start still ignores [defaults.session]. A project that min init scaffolds in the entry shape would lose its packages at session start. BOX T21 (#2418, "One minimal.toml for every box, end to end") wires expansion into box creation.

  1. In crates/minimal/src/cmd/project.rs cmd_init (line 947), pass false for entry_shape, as offer_mfile_scaffold does. Keep the --type / noun-flag append (BCLI-018) and every refusal and exit code as they are.
  2. Change the two interim comments (above offer_mfile_scaffold's call and on run_init_flow's entry_shape doc) to name T21 — One minimal.toml for every box, end to end #2418 in place of T16 — Fold the layers into one expanded spec, the same bytes every run #2410. Flip condition: when T21 — One minimal.toml for every box, end to end #2418 lands, both callers pass true and the parameter is removed.
  3. Keep to_entry_shape and its test init_scaffolds_entry_shape, which call run_init_flow(.., true) directly. Add or adjust one test that pins min init with no flags writing the legacy shape, which mfile::File reads today.
  4. In the PR body, before the notes, add a residual: BCLI-017's entry-shape scaffold is built and tested, but min init writes the legacy [session] shape until T21 — One minimal.toml for every box, end to end #2418 (BOX T21) makes box creation read [defaults.<type>]. Then min init and offer_mfile_scaffold pass true, and the entry_shape parameter is removed. Keep the existing line about crates/minimal/src/cmd/mod.rs.

Box creation does not read [defaults.<type>] until #2418 (BOX T21), so
an entry-shaped scaffold loses its packages at session start. Both init
callers pass INIT_ENTRY_SHAPE, which is false until then.
@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/project.rs Resolved
Comment thread crates/minimal/src/cmd/project.rs Resolved
@minimal-foundry minimal-foundry Bot removed the review:approved minimal-review approved the current head label Nov 6, 2026
@minimal-foundry
minimal-foundry Bot 10BC8 commented Nov 6, 2026
Copy link
Copy Markdown
Contributor Author

Round 3 of 10 on a /revise note, pushed as 4e4194cc412c.

line exit tail
cargo nextest run -p minimal init_scaffolds_entry_shape 0 Applying loadouts: default Running task runtime-implement-test-0 in box runtime-implement-test-0-1... Compiling paths v0.0.1 (/workbench/crates/paths) Compiling ot v0.0.1 (/workbench/crates/ot) Compiling args v0.0.1 (/workbench/crates/args) Compiling client-config v0.0.1 (/workbench/crat
cargo nextest run -p minimal init_entry_type_appends_one 0 Applying loadouts: default Running task runtime-implement-test-1 in box runtime-implement-test-1-1... 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.0.1 (/workbe
cargo nextest run -p minimal init_refused_type_exit3_appends_nothing 0 Applying loadouts: default Running task runtime-implement-test-2 in box runtime-implement-test-2-1... 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.0.1 (/workbe
cargo nextest run -p minimal init_noun_flag_is_type_alias 0 Applying loadouts: default Running task runtime-implement-test-3 in box runtime-implement-test-3-1... 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.0.1 (/workbe
cargo nextest run -p minimal init_noun_flags_exclusive_exit2_appends_nothing 0 Applying loadouts: default Running task runtime-implement-test-4 in box runtime-implement-test-4-1... 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.0.1 (/workbe

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

s::range_step_custody_follows_the_program_the_plist_names
        PASS [   0.007s] (549/950) minimal resolver::tests::range_step_custody_is_root_owned
        PASS [   0.007s] (550/950) minimal resolver::tests::range_step_custody_walks_every_path_component
        PASS [   0.007s] (551/950) minimal resolver::tests::resolver_file_hook_parses_nameserver_and_port
        PASS [   0.006s] (552/950) minimal resolver::tests::resolver_file_hook_states_its_gaps
        PASS [   0.007s] (553/950) minimal resolver::tests::routing_domain_hook_finds_the_carrying_link_and_its_port
        PASS [   0.007s] (554/950) minimal resolver::tests::routing_domain_hook_states_its_gaps
        PASS [   0.009s] (555/950) minimal resolver::tests::session_advisory_agrees_with_the_hook_it_detected
        PASS [   0.008s] (556/950) minimal resolver::tests::session_advisory_without_a_port_stays_quiet
        PASS [   0.008s] (557/950) minimal resolver::tests::session_start_points_at_finalize_install_without_the_advisory
        PASS [   0.744s] (558/950) minimal resolver::tests::finalize_install_undo_succeeds_on_a_clean_host
        PASS [   0.007s] (559/950) minimal resolver::tests::the_app_bundle_layout_matches_packaging
        PASS [   0.007s] (560/950) minimal resolver::tests::the_bundle_record_mirrors_the_probe
        PASS [   0.167s] (561/950) minimal resolver::tests::privileged_copy_refuses_a_user_writable_ancestor
        PASS [   0.007s] (562/950) minimal resolver::tests::the_resolve_module_is_looked_up_under_glibcs_module_name
        FAIL [   0.040s] (563/950) minimal resolver::tests::the_answerer_facts_ride_beside_a_down_proxy_sibling
  stdout ───

    running 1 test
    test resolver::tests::the_answerer_facts_ride_beside_a_down_proxy_sibling ... FAILED

    failures:

    failures:
        resolver::tests::the_answerer_facts_ride_beside_a_down_proxy_sibling

    test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 795 filtered out; finished in 0.03s

  stderr ───

    thread 'resolver::tests::the_answerer_facts_ride_beside_a_down_proxy_sibling' (3683) panicked at crates/minimal/src/resolver.rs:7666:9:
    the liveness proof still ran at the holder's port
    note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

  Cancelling due to test failure: 3 tests still running
        PASS [   0.006s] (564/950) minimal resolver::tests::vm_host_answerer_line_names_the_holder
        PASS [   2.040s] (565/950) minimal mint::tests::a_refused_client_key_is_replaced_and_registered_before_the_mint
        PASS [   0.615s] (566/950) minimal resolver::tests::the_lists_two_queries_run_under_one_deadline
────────────
     Summary [  10.697s] 566/950 tests run: 565 passed, 1 failed, 1 skipped
        FAIL [   0.040s] (563/950) minimal resolver::tests::the_answerer_facts_ride_beside_a_down_proxy_sibling
warning: 384/950 tests were not run due to test failure (run with --no-fail-fast to run all tests, or run with --max-fail)
error: test run failed

Outside the task's layers::

  • crates/minimal/src/cmd/mod.rs

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

min init with no flags writes the legacy [session] minimal.toml that session start reads today. The entry-shape scaffold is built and tested through to_entry_shape. min init <entry> --type <type> appends one entry, with the same refusals and exit codes as before.

Notes from the agent: Residual for the PR body, before the notes: BCLI-017's entry-shape scaffold is built and tested, but min init writes the legacy [session] shape until #2418 (BOX T21) makes box creation read [defaults.<type>]. Then min init and offer_mfile_scaffold pass true, and the entry_shape parameter is removed. Keep the existing line about crates/minimal/src/cmd/mod.rs. I cannot edit the PR body, so the runner must add this residual.

How I did it: cmd_init and offer_mfile_scaffold both pass a new pub(crate) const INIT_ENTRY_SHAPE: bool = false in place of a literal false. With the constant, the new test init_no_flags_writes_legacy_shape can pin the choice with a compile-time assert. The test also checks that mfile::File reads the scaffold's packages from [session]. At the flip, set the constant to true and update that test, or remove the constant together with the parameter. Both interim comments now name #2418 in place of #2410. init_scaffolds_entry_shape calls to_entry_shape directly, not run_init_flow(.., true). It is unchanged. The append path, the refusals and the exit codes are unchanged. I did not run just clippy-strict.

@minimal-foundry
minimal-foundry Bot marked this pull request as draft November 6, 2026 19:51
@agent-137
agent-137 marked this pull request as ready for review November 6, 2026 19:52
@agent-137
Copy link
Copy Markdown
Member

/revise

Head 4e4194cc. Two items from minimal-review. Change no other behaviour.

1. Thread PRRT_kwDOPdfcxM60qlds (LOW): the scaffold span names an entry the file lacks.

cmd_init records tracing::info!(verb = "init", entry = "dev", ..) for the scaffold. With INIT_ENTRY_SHAPE = false, the file has a legacy [session] table and no dev entry. Record what was written: leave entry out of the scaffold record (or record shape = "legacy") while INIT_ENTRY_SHAPE is false. Keep entry = <name> on the append records, where an entry is written. Reply on the thread with the commit.

2. Thread PRRT_kwDOPdfcxM60qldo (MEDIUM): min init writes the legacy shape.

This is the owner's decision, so do not change it. Reply on the thread: on main, box creation does not read [defaults.<type>] yet. BOX T21 (#2418) wires mfile::expand into it. Until then, an entry-shaped scaffold would lose its packages at session start. INIT_ENTRY_SHAPE flips to true and the parameter goes when #2418 lands. BCLI-017's scaffold is built and tested, but not on by default.

The PR body still shows the round-0 notes, which describe the removed exit_refused. The babysitter handles the body, so do not edit it.

The legacy [session] scaffold has no dev entry, so the span records
shape = "legacy" and leaves entry out while INIT_ENTRY_SHAPE is false.
@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 — 1 finding, 1 inline.

Panel: 2 of 3 personas ran (correctness, supply-chain); did not complete: security.

Comment thread crates/minimal/src/cmd/project.rs Outdated
Comment on lines +899 to +925
fn find_init_mfile(dir: &std::path::Path) -> Option<std::path::PathBuf> {
[
dir.join(mfile::MFILE_NAME),
dir.join(".minimal").join(mfile::MFILE_NAME),
]
.into_iter()
.find(|path| path.is_file())
}

/// Append the entry to the project's `minimal.toml` in `dir`, under the
/// file's edit lock, and return the path written. A refusal comes back as
/// an [`InitRefusal`] inside the error, and leaves the file unchanged.
pub(crate) fn append_entry_in(
dir: &std::path::Path,
entry: &str,
box_type: &str,
) -> Result<std::path::PathBuf, anyhow::Error> {
let Some(path) = find_init_mfile(dir) else {
return Err(InitRefusal {
code: 1,
message: format!(
"No minimal.toml in {}. Run min init to create one, then append the entry.",
dir.display()
),
}
.into());
};
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.

MEDIUM · correctness · confidence 0.60 · in find_init_mfile

find_init_mfile looks only in the given directory. min add and the other commands search the ancestor directories (MFileSearchStrategy::CurrentDirRecursive in crates/mctx/src/lib.rs). So min init worker --type task from a project subdirectory fails with "No minimal.toml", and the hint to run min init would create a nested file. The function also picks the root file silently when both layouts exist. mfile::File::from_dir refuses that case with ConflictingLayouts. Use mfile::File::from_dir_recursive to find the path, or the same search as the other commands.

What the reviewer checked

find_init_mfile: [dir.join(MFILE_NAME), dir.join(".minimal").join(MFILE_NAME)].find(is_file); no ancestor walk, no conflict check

Hand this to an agent
Act on a code-review finding.

File:       crates/minimal/src/cmd/project.rs
Lines:      899-925
Category:   correctness
Severity:   medium (reviewer confidence 0.60)

Finding:
`find_init_mfile` looks only in the given directory. `min add` and the other commands search the ancestor directories (`MFileSearchStrategy::CurrentDirRecursive` in `crates/mctx/src/lib.rs`). So `min init worker --type task` from a project subdirectory fails with "No minimal.toml", and the hint to run `min init` would create a nested file. The function also picks the root file silently when both layouts exist. `mfile::File::from_dir` refuses that case with `ConflictingLayouts`. Use `mfile::File::from_dir_recursive` to find the path, or the same search as the other commands.

First verify this against the code yourself. It is model output and
may be wrong. If it is wrong, or the tradeoff was deliberate, say so
and change nothing.

👍 useful · 👎 noise — react to tell the reviewer. Replying works too, and says more.

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.

Addressed in 5cf31bab27bf: Fixed in 5cf31ba: find_init_mfile uses mfile::File::from_dir_recursive (from_dir with --repo-dir), refuses both layouts with exit 3 naming both paths, and two tests pin the subdirectory and conflict cases.

@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

BCLI-018 and the exit codes are unchanged, and the PASS on 127ec0e stands for them. Bare min init now writes the legacy [session] table. The design's minimal.toml layout (lines 1165 and 1173) and its canonical example have no such table. The interim is honest and its reason is true: box creation does not merge [defaults.<type>] yet. C1 is the flip when #2418 lands, and it stays open as that residual. Also update the PR body's Proof section. It still says that min init writes the entry shape.

Ruled at f2efb84 against gominimal/arch@7a86ec7bb3c0 by claude-opus-5-5.

/// Whether `min init` and the `min activate` scaffold write the entry shape.
/// `false` until #2418 (BOX T21): box creation still reads packages from
/// `[session]`, so an entry-shaped scaffold loses them at session start.
pub(crate) const INIT_ENTRY_SHAPE: bool = false;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

C1 · This const keeps bare min init on the legacy [session] table. The design layout (architecture.md lines 1165 and 1173) has no such table. When #2418 lands, set this to true. Then remove the const and the entry_shape parameter of run_init_flow.

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.

Disputed — not addressed: Already so on this branch: the doc comments on INIT_ENTRY_SHAPE and run_init_flow record this exact follow-up for #2418. #2418 has not landed, so the const stays false now, and this round changes nothing for it.

@minimal-foundry
Copy link
Copy Markdown
Contributor Author

Round 4 of 10 on a /revise note, pushed as f2efb842ed4f.

line exit tail
cargo nextest run -p minimal init_scaffolds_entry_shape 0 Applying loadouts: default Running task runtime-implement-test-0 in box runtime-implement-test-0-1... Compiling paths v0.0.1 (/workbench/crates/paths) Compiling ot v0.0.1 (/workbench/crates/ot) Compiling args v0.0.1 (/workbench/crates/args) Compiling client-config v0.0.1 (/workbench/crat
cargo nextest run -p minimal init_entry_type_appends_one 0 Applying loadouts: default Running task runtime-implement-test-1 in box runtime-implement-test-1-1... 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.0.1 (/workbe
cargo nextest run -p minimal init_refused_type_exit3_appends_nothing 0 Applying loadouts: default Running task runtime-implement-test-2 in box runtime-implement-test-2-1... 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.0.1 (/workbe
cargo nextest run -p minimal init_noun_flag_is_type_alias 0 Applying loadouts: default Running task runtime-implement-test-3 in box runtime-implement-test-3-1... 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.0.1 (/workbe
cargo nextest run -p minimal init_noun_flags_exclusive_exit2_appends_nothing 0 Applying loadouts: default Running task runtime-implement-test-4 in box runtime-implement-test-4-1... 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.0.1 (/workbe

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

sts::range_program_applies_exactly_the_reserved_range
        PASS [   0.025s] (547/950) minimal resolver::tests::range_step_custody_failure_resurfaces_the_advisory
        PASS [   0.018s] (548/950) minimal resolver::tests::range_step_custody_follows_the_program_the_plist_names
        PASS [   0.254s] (549/950) minimal resolver::tests::privileged_copy_refuses_a_source_swapped_after_render
        PASS [   0.012s] (550/950) minimal resolver::tests::range_step_custody_is_root_owned
        PASS [   0.019s] (551/950) minimal resolver::tests::range_step_custody_walks_every_path_component
        PASS [   0.017s] (552/950) minimal resolver::tests::resolver_file_hook_parses_nameserver_and_port
        PASS [   0.013s] (553/950) minimal resolver::tests::resolver_file_hook_states_its_gaps
        PASS [   0.016s] (554/950) minimal resolver::tests::routing_domain_hook_finds_the_carrying_link_and_its_port
        PASS [   0.018s] (555/950) minimal resolver::tests::routing_domain_hook_states_its_gaps
        PASS [   0.017s] (556/950) minimal resolver::tests::session_advisory_without_a_port_stays_quiet
        PASS [   0.025s] (557/950) minimal resolver::tests::session_advisory_agrees_with_the_hook_it_detected
        PASS [   0.014s] (558/950) minimal resolver::tests::session_start_points_at_finalize_install_without_the_advisory
        PASS [   0.015s] (559/950) minimal resolver::tests::the_app_bundle_layout_matches_packaging
        PASS [   0.013s] (560/950) minimal resolver::tests::the_bundle_record_mirrors_the_probe
        FAIL [   0.095s] (561/950) minimal resolver::tests::the_answerer_facts_ride_beside_a_down_proxy_sibling
  stdout ───

    running 1 test
    test resolver::tests::the_answerer_facts_ride_beside_a_down_proxy_sibling ... FAILED

    failures:

    failures:
        resolver::tests::the_answerer_facts_ride_beside_a_down_proxy_sibling

    test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 795 filtered out; finished in 0.08s

  stderr ───

    thread 'resolver::tests::the_answerer_facts_ride_beside_a_down_proxy_sibling' (3495) panicked at crates/minimal/src/resolver.rs:7666:9:
    the liveness proof still ran at the holder's port
    note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

  Cancelling due to test failure: 3 tests still running
        PASS [   0.437s] (562/950) minimal resolver::tests::privileged_copy_refuses_a_user_writable_ancestor
        PASS [   1.806s] (563/950) minimal resolver::tests::finalize_install_undo_succeeds_on_a_clean_host
        PASS [   0.649s] (564/950) minimal resolver::tests::the_lists_two_queries_run_under_one_deadline
────────────
     Summary [  15.320s] 564/950 tests run: 563 passed, 1 failed, 1 skipped
        FAIL [   0.095s] (561/950) minimal resolver::tests::the_answerer_facts_ride_beside_a_down_proxy_sibling
warning: 386/950 tests were not run due to test failure (run with --no-fail-fast to run all tests, or run with --max-fail)
error: test run failed

Outside the task's layers::

  • crates/minimal/src/cmd/mod.rs

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

Review threads the coder judged:

  • 👍 valid — crates/minimal/src/cmd/project.rs: Fixed in f2efb84: the scaffold record now has shape = "legacy" and no entry field while INIT_ENTRY_SHAPE is false. The append records keep entry = .
  • 👎 invalid — crates/minimal/src/cmd/project.rs:522: The legacy default is the owner's decision. On main, box creation does not read [defaults.] yet. BOX T21 (T21 — One minimal.toml for every box, end to end #2418) wires mfile::expand into it. Until then, an entry-shaped scaffold loses its packages at session start. INIT_ENTRY_SHAPE flips to true and the parameter goes when T21 — One minimal.toml for every box, end to end #2418 lands. BCLI-0

min init <entry> --type <type> appends one entry to minimal.toml. The entry-shaped scaffold is built and tested, but min init with no flags still writes the legacy [session] shape until INIT_ENTRY_SHAPE flips with #2418. The scaffold's tracing record now says shape = "legacy" and names no entry.

Notes from the agent: Round 4 changes only the scaffold tracing record in cmd_init (commit f2efb84). It records shape = "legacy" and leaves out entry while INIT_ENTRY_SHAPE is false. The append records keep entry = . No other behaviour changed. BCLI-017's default entry-shaped scaffold is not on by default. That is the owner's decision, and it waits on #2418.

@minimal-foundry
minimal-foundry Bot marked this pull request as draft November 6, 2026 20:21
@agent-137
agent-137 marked this pull request as ready for review November 6, 2026 20:22
@agent-137
Copy link
Copy Markdown
Member

/revise

Head f2efb842. One item: minimal-review thread PRRT_kwDOPdfcxM60rDx9 (MEDIUM). Change nothing else.

find_init_mfile must find minimal.toml the way the other commands do.

find_init_mfile (crates/minimal/src/cmd/project.rs lines 899–925) looks only in the given directory. min add and the other commands search the ancestor directories (MFileSearchStrategy::CurrentDirRecursive in crates/mctx/src/lib.rs). Today min init worker --type task from a project subdirectory fails with "No minimal.toml". The hint to run min init would then create a nested file. The function also picks the root file silently when both minimal.toml and .minimal/minimal.toml exist. mfile::File::from_dir refuses that case with ConflictingLayouts.

  1. Find the file that the append writes to with the same search the other commands use: mfile::File::from_dir_recursive, or MFileSearchStrategy::CurrentDirRecursive. Do not hand-roll a second walk.
  2. Refuse when both layouts exist, as mfile does, with exit 3 and a message that names both paths.
  3. Add tests:
    • min init worker --type task run from a subdirectory appends to the project root's minimal.toml, and creates no file in the subdirectory.
    • Both layouts present exits 3, and neither file changes.
  4. The bare scaffold (min init with no flags) keeps creating the file in the current directory, as today.

Reply on the thread with the commit.

min init <entry> --type <type> now locates the project's minimal.toml
with mfile::File::from_dir_recursive, the search the other commands use,
so it works from a project subdirectory. With --repo-dir it looks in that
directory only, as MFileSearchStrategy::Override does. Both layouts in one
directory are refused with exit 3, and the message names both paths.
@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

The new search for minimal.toml conforms to the Discovery line (architecture.md line 1167). But mfile::File::from_dir now parses the file before the append. A minimal.toml that does not parse now exits 1 through the generic error arm in find_init_mfile. The Exit codes table (line 364) gives 3 for invalid configuration, and this head gave 3 for that file before this commit. Make the change in C1. Then the change conforms.

Ruled at 5cf31ba against gominimal/arch@7a86ec7bb3c0 by claude-opus-5-5.

Comment thread crates/minimal/src/cmd/project.rs Outdated
),
}
.into()),
Err(e) => Err(anyhow::Error::new(e).context("reading minimal.toml")),
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

C1 · A minimal.toml that does not parse comes here as mfile::Error::Format and exits 1. The Exit codes table (line 364) gives 3 for invalid configuration. Keep mfile::Error::IO on this arm. Return every other mfile::Error as InitRefusal { code: 3, .. } that names the file. Pin it with init_invalid_mfile_exit3_appends_nothing.

@minimal-foundry
Copy link
Copy Markdown
Contributor Author

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

line exit tail
cargo nextest run -p minimal init_scaffolds_entry_shape 0 Applying loadouts: default Running task runtime-implement-test-0 in box runtime-implement-test-0-1... Compiling paths v0.0.1 (/workbench/crates/paths) Compiling args v0.0.1 (/workbench/crates/args) Compiling ot v0.0.1 (/workbench/crates/ot) Compiling client-config v0.0.1 (/workbench/crat
cargo nextest run -p minimal init_entry_type_appends_one 0 Applying loadouts: default Running task runtime-implement-test-1 in box runtime-implement-test-1-1... 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.0.1 (/workbe
cargo nextest run -p minimal init_refused_type_exit3_appends_nothing 0 Applying loadouts: default Running task runtime-implement-test-2 in box runtime-implement-test-2-1... 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.0.1 (/workbe
cargo nextest run -p minimal init_noun_flag_is_type_alias 0 Applying loadouts: default Running task runtime-implement-test-3 in box runtime-implement-test-3-1... 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.0.1 (/workbe
cargo nextest run -p minimal init_noun_flags_exclusive_exit2_appends_nothing 0 Applying loadouts: default Running task runtime-implement-test-4 in box runtime-implement-test-4-1... 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.0.1 (/workbe

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

ests::range_alias_with_a_wide_mask_resurfaces_the_advisory
        PASS [   0.021s] (553/956) minimal resolver::tests::range_program_applies_exactly_the_reserved_range
        PASS [   0.013s] (554/956) minimal resolver::tests::range_step_custody_failure_resurfaces_the_advisory
        PASS [   0.017s] (555/956) minimal resolver::tests::range_step_custody_follows_the_program_the_plist_names
        PASS [   0.019s] (556/956) minimal resolver::tests::range_step_custody_is_root_owned
        PASS [   0.017s] (557/956) minimal resolver::tests::range_step_custody_walks_every_path_component
        PASS [   0.012s] (558/956) minimal resolver::tests::resolver_file_hook_states_its_gaps
        PASS [   0.020s] (559/956) minimal resolver::tests::resolver_file_hook_parses_nameserver_and_port
        PASS [   0.014s] (560/956) minimal resolver::tests::routing_domain_hook_finds_the_carrying_link_and_its_port
        PASS [   0.014s] (561/956) minimal resolver::tests::routing_domain_hook_states_its_gaps
        PASS [   0.020s] (562/956) minimal resolver::tests::session_advisory_agrees_with_the_hook_it_detected
        PASS [   0.030s] (563/956) minimal resolver::tests::session_advisory_without_a_port_stays_quiet
        PASS [   0.015s] (564/956) minimal resolver::tests::session_start_points_at_finalize_install_without_the_advisory
        PASS [   0.013s] (565/956) minimal resolver::tests::the_app_bundle_layout_matches_packaging
        PASS [   0.013s] (566/956) minimal resolver::tests::the_bundle_record_mirrors_the_probe
        FAIL [   0.071s] (567/956) minimal resolver::tests::the_answerer_facts_ride_beside_a_down_proxy_sibling
  stdout ───

    running 1 test
    test resolver::tests::the_answerer_facts_ride_beside_a_down_proxy_sibling ... FAILED

    failures:

    failures:
        resolver::tests::the_answerer_facts_ride_beside_a_down_proxy_sibling

    test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 801 filtered out; finished in 0.06s

  stderr ───

    thread 'resolver::tests::the_answerer_facts_ride_beside_a_down_proxy_sibling' (3637) panicked at crates/minimal/src/resolver.rs:7689:9:
    the liveness proof still ran at the holder's port
    note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

  Cancelling due to test failure: 3 tests still running
        PASS [   0.434s] (568/956) minimal resolver::tests::privileged_copy_refuses_a_user_writable_ancestor
        PASS [   1.751s] (569/956) minimal resolver::tests::finalize_install_undo_succeeds_on_a_clean_host
        PASS [   0.648s] (570/956) minimal resolver::tests::the_lists_two_queries_run_under_one_deadline
────────────
     Summary [  14.412s] 570/956 tests run: 569 passed, 1 failed, 1 skipped
        FAIL [   0.071s] (567/956) minimal resolver::tests::the_answerer_facts_ride_beside_a_down_proxy_sibling
warning: 386/956 tests were not run due to test failure (run with --no-fail-fast to run all tests, or run with --max-fail)
error: test run failed

Outside the task's layers::

  • crates/minimal/src/cmd/mod.rs

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

Review threads the coder judged:

  • 👍 valid — crates/minimal/src/cmd/project.rs: Fixed in 5cf31ba: find_init_mfile uses mfile::File::from_dir_recursive (from_dir with --repo-dir), refuses both layouts with exit 3 naming both paths, and two tests pin the subdirectory and conflict cases.
  • 👎 invalid — crates/minimal/src/cmd/project.rs:522: Already so on this branch: the doc comments on INIT_ENTRY_SHAPE and run_init_flow record this exact follow-up for T21 — One minimal.toml for every box, end to end #2418. T21 — One minimal.toml for every box, end to end #2418 has not landed, so the const stays false now, and this round changes nothing for it.

min init writes a minimal.toml in the current directory, and min init <entry> --type <type> appends one entry to the project's minimal.toml. The append now also works from a project subdirectory, and it refuses with exit 3 when both minimal.toml and .minimal/minimal.toml exist.

Notes from the agent: Revise round 5, commit 5cf31ba. find_init_mfile now calls mfile::File::from_dir_recursive without --repo-dir (MFileSearchStrategy::CurrentDirRecursive), and mfile::File::from_dir with --repo-dir (MFileSearchStrategy::Override). mfile::Error::ConflictingLayouts becomes an InitRefusal with code 3 that names both paths. NotFound stays code 1, and its message adds 'or its parent directories' when the search walks up. Other mfile errors (for example a parse error) are now reported before the append, with the context 'reading minimal.toml'. The bare scaffold is unchanged and still writes to the current directory. New tests: init_entry_type_appends_from_subdirectory and init_conflicting_layouts_exit3_appends_nothing. cargo clippy -p minimal --all-targets is clean. just clippy-strict was not run.

@minimal-foundry
minimal-foundry Bot marked this pull request as draft November 6, 2026 20:57
@agent-137
agent-137 marked this pull request as ready for review November 6, 2026 21:07
@agent-137
Copy link
Copy Markdown
Member

/revise

Head 5cf31bab. Arch ruling 1031 has one condition. Change nothing else.

C1: a minimal.toml that does not parse is invalid configuration, exit 3.

In crates/minimal/src/cmd/project.rs find_init_mfile(), replace the catch-all Err(e) => Err(anyhow::Error::new(e).context("reading minimal.toml")) arm (line 941):

  • Keep mfile::Error::IO(..) on that generic path (exit 1).
  • Return every other mfile::Error as InitRefusal { code: 3, message }. The message says that min init did not add the entry, names the file it found, and includes the mfile error.

Add the test init_invalid_mfile_exit3_appends_nothing in init_tests. It writes a minimal.toml that does not parse, calls append_from, asserts code == 3, and asserts that the file is unchanged.

@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 — 1 finding, 1 inline.

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

match append_entry_in(&dir, search_ancestors, &entry, &box_type) {
Ok(path) => {
tracing::info!(verb = "init", entry, box_type, outcome = "appended");
println!("Added the {box_type} entry {entry} to {}", path.display());
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.

LOW · correctness · confidence 0.50 · in cmd_init

The command prints "Added the ... entry" as success, but the PR body says nothing reads [boxes.*] yet. Activation ignores the entry, and bare min init still writes the legacy [session] shape. The user sees success for a change that has no effect. Say that the entry takes effect later, or hold the append until box creation reads entries.

What the reviewer checked

println!("Added the {box_type} entry {entry} to {}", path.display()); PR body: 'Nothing in this tree reads [boxes.*] ... mfile logs them as unknown fields'

Hand this to an agent
Act on a code-review finding.

File:       crates/minimal/src/cmd/project.rs
Lines:      1020-1020
Category:   correctness
Severity:   low (reviewer confidence 0.50)

Finding:
The command prints "Added the ... entry" as success, but the PR body says nothing reads [boxes.*] yet. Activation ignores the entry, and bare `min init` still writes the legacy [session] shape. The user sees success for a change that has no effect. Say that the entry takes effect later, or hold the append until box creation reads entries.

First verify this against the code yourself. It is model output and
may be wrong. If it is wrong, or the tradeoff was deliberate, say so
and change nothing.

👍 useful · 👎 noise — react to tell the reviewer. Replying works too, and says more.

A minimal.toml that does not parse or validate is invalid configuration.
min init now refuses it with exit 3, names the file, and leaves it
unchanged. An I/O error still exits 1.
@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 fixes the open point from 5cf31ba. A minimal.toml that does not parse or validate now refuses min init <entry> --type <type> with exit 3, names the file and changes nothing. That agrees with the exit-code table, line 364. An I/O error stays exit 1. BCLI-018 conforms. The BCLI-017 interim from f2efb84 is still open and filed on #2418. C1 is its flip, and it can stay open at merge.

Ruled at bef69e7 against gominimal/arch@7a86ec7bb3c0 by claude-opus-5-5.

/// Whether `min init` and the `min activate` scaffold write the entry shape.
/// `false` until #2418 (BOX T21): box creation still reads packages from
/// `[session]`, so an entry-shaped scaffold loses them at session start.
pub(crate) const INIT_ENTRY_SHAPE: bool = false;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

C1 · This interim is filed on #2418. When #2418 merges, set this to true and then remove it. Remove the entry_shape parameter of run_init_flow, and make bare min init write [defaults.<type>] and [boxes.dev] (minimal.toml layout, lines 1173 and 1176).

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

T20 — Scaffold and append entries with min init

2 participants

0