lab infocheck: false-positives on lib+bin crates (assumes src/main.rs exists for every cargo-metadata-discovered binary crate) #265

Open
opened 2026-05-19 14:28:29 +00:00 by mik-tf · 0 comments
Owner

lab infocheck discovers binary crates via cargo metadata (correctly finds every crate with [[bin]] targets), then calls check_crate(crate_dir) which assumes the crate has src/main.rs:

// crates/lab/src/builder/infocheck.rs:255-257
let main_rs = crate_dir.join("src").join("main.rs");
let src = std::fs::read_to_string(&main_rs).unwrap_or_default();
check_main_rs(&main_rs, &src, &mut report);

For lib+bin crates (with src/lib.rs and bins under src/bin/<name>.rs), there is no src/main.rs. unwrap_or_default() returns an empty string and check_main_rs produces 3 false-positive findings at src/main.rs:0:

  • macro service_base!() is missing
  • validate_service_toml(SERVICE_TOML) is missing
  • handle_info_flag(SERVICE_TOML) is missing

Concrete example

hero_osis/crates/hero_osis_server/ ships:

  • src/lib.rs — the domain code.
  • src/bin/hero_osis.rs — auto-generated orchestrator (by hero_rpc::generator::generate_single_bin).
  • src/bin/seed.rs — DB seed tool.
  • src/bin/hero_bot.rs — ACP agent.

All three bins correctly use the canonical pattern with inline SERVICE_TOML / BUILD_NR consts (Lesson #20 workaround, because service_base!() macro's include_str!("../service.toml") resolves wrong from src/bin/<name>.rs). The runtime <bin> --info --json output deserialises cleanly into ServiceToml. The lab build post-build --info check is green.

But lab infocheck reports 3 findings against a non-existent src/main.rs, so the crate looks "fail" in the source-side audit even though the runtime contract is met.

Proposed fix

When src/main.rs does not exist, check_crate should:

  1. Either silently skip the crate (matches the skill spec: "Library-only crates (no src/main.rs) are silently skipped — they don't need --info wiring."),
  2. Or better, fall back to walking src/bin/*.rs and applying the same check_main_rs checks to each. For src/bin/ bins, the canonical pattern is inline SERVICE_TOML/BUILD_NR consts (Lesson #20), so the source-side check should accept either:
    • service_base!() macro call + validate_service_toml(SERVICE_TOML) + handle_info_flag(SERVICE_TOML), OR
    • inline const SERVICE_TOML: &str = include_str!("../../service.toml"); + same two API calls.

Option 2 keeps the audit coverage while accommodating the src/bin/ shape.

Repro

cd lhumina_code/hero_osis  # after squash-commit 7d8b3a2 lands
lab infocheck
# Reports 1 clean (hero_osis_admin) + 1 fail (hero_osis_server, 3 issues at src/main.rs:0)

lab build --release --install --workspace --policy-mode warn is green: 4/4 built, 4/4 --info check pass.

Context

Filed during s123 hero_proc#102 D-10 closure for hero_osis. The hero_osis_server lib+bin shape is legitimate per Cargo conventions and necessary here (the auto-generated orchestrator must live alongside the library code it imports + the hand-written seed/bot tools). Splitting into 3 separate crates would be invasive and not warranted by the skill spec, which already documents the workaround.

Reference: hero_proc#102#33220 Session 123 update, hero_osis 7d8b3a2.

`lab infocheck` discovers binary crates via `cargo metadata` (correctly finds every crate with `[[bin]]` targets), then calls `check_crate(crate_dir)` which assumes the crate has `src/main.rs`: ```rust // crates/lab/src/builder/infocheck.rs:255-257 let main_rs = crate_dir.join("src").join("main.rs"); let src = std::fs::read_to_string(&main_rs).unwrap_or_default(); check_main_rs(&main_rs, &src, &mut report); ``` For **lib+bin crates** (with `src/lib.rs` and bins under `src/bin/<name>.rs`), there is no `src/main.rs`. `unwrap_or_default()` returns an empty string and `check_main_rs` produces 3 false-positive findings at `src/main.rs:0`: - `macro service_base!() is missing` - `validate_service_toml(SERVICE_TOML) is missing` - `handle_info_flag(SERVICE_TOML) is missing` ## Concrete example `hero_osis/crates/hero_osis_server/` ships: - `src/lib.rs` — the domain code. - `src/bin/hero_osis.rs` — auto-generated orchestrator (by `hero_rpc::generator::generate_single_bin`). - `src/bin/seed.rs` — DB seed tool. - `src/bin/hero_bot.rs` — ACP agent. All three bins correctly use the canonical pattern with **inline SERVICE_TOML / BUILD_NR consts** (Lesson #20 workaround, because `service_base!()` macro's `include_str!("../service.toml")` resolves wrong from `src/bin/<name>.rs`). The runtime `<bin> --info --json` output deserialises cleanly into `ServiceToml`. The lab build post-build `--info check` is green. But `lab infocheck` reports 3 findings against a non-existent `src/main.rs`, so the crate looks "fail" in the source-side audit even though the runtime contract is met. ## Proposed fix When `src/main.rs` does not exist, `check_crate` should: 1. **Either** silently skip the crate (matches the skill spec: *"Library-only crates (no `src/main.rs`) are silently skipped — they don't need `--info` wiring."*), 2. **Or better**, fall back to walking `src/bin/*.rs` and applying the same `check_main_rs` checks to each. For `src/bin/` bins, the canonical pattern is **inline SERVICE_TOML/BUILD_NR consts** (Lesson #20), so the source-side check should accept either: - `service_base!()` macro call + `validate_service_toml(SERVICE_TOML)` + `handle_info_flag(SERVICE_TOML)`, OR - inline `const SERVICE_TOML: &str = include_str!("../../service.toml");` + same two API calls. Option 2 keeps the audit coverage while accommodating the `src/bin/` shape. ## Repro ```bash cd lhumina_code/hero_osis # after squash-commit 7d8b3a2 lands lab infocheck # Reports 1 clean (hero_osis_admin) + 1 fail (hero_osis_server, 3 issues at src/main.rs:0) ``` `lab build --release --install --workspace --policy-mode warn` is green: 4/4 built, 4/4 `--info` check pass. ## Context Filed during s123 hero_proc#102 D-10 closure for hero_osis. The hero_osis_server lib+bin shape is legitimate per Cargo conventions and necessary here (the auto-generated orchestrator must live alongside the library code it imports + the hand-written seed/bot tools). Splitting into 3 separate crates would be invasive and not warranted by the skill spec, which already documents the workaround. Reference: [hero_proc#102#33220](https://forge.ourworld.tf/lhumina_code/hero_proc/issues/102#issuecomment-33220) Session 123 update, [hero_osis 7d8b3a2](https://forge.ourworld.tf/lhumina_code/hero_osis/commit/7d8b3a2).
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
lhumina_code/hero_skills#265
No description provided.