Skip to content

fix(tools): validate placement inputs and preserve named CLI errors - #659

Merged
juliankang4 merged 2 commits into
midagedev:mainfrom
Burntgogi:fix/issue637-placement-cli
Oct 22, 2026
Merged

juliankang4 merged 2 commits into
midagedev:mainfrom
Burntgogi:fix/issue637-placement-cli

Conversation

@Burntgogi

@Burntgogi Burntgogi commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Change

Refs #637; resolves its malformed/repeated placement-input item and its bursts traceback item. MTP draft-store correctness and remote narrow-scan cancellation are not part of this PR.

  • parse_n_l is the single placement-admission owner: counts in 0..n_expert, no repeated/overlapping explicit layer ranges, and a nonnegative spread total no larger than eligible capacity. All callers pass the trace's expert count; card_sets only materializes the admitted id prefixes.
  • Both affected command lines reject repeated single-value options. window-union --k also rejects duplicate window sizes rather than duplicating report rows.
  • bursts translates the path-loaded module's SetError at the reader boundary to its own SetError, preserving the named CLI refusal without global module-cache mutation or catching unrelated errors.
  • Existing self-tests retain the numerical replay checks and add placement boundaries/refusals plus real CLI regressions. Help and contributor documentation are updated.

Verification

Base 69b66367; head 7cfab04.

  • Before: six malformed/repeated CLI cases exited 0; excessive-count and unknown-layer bursts cases exited 1 with Python tracebacks. After: all 8 scenarios exit 1 with the named option and no traceback.
  • Full window-union.py --self-test and router-coverage.py --self-test pass, including the existing static/strata numerical checks and seven retained real-CLI refusal cases.
  • Separate smoke: valid empty-card and partial-spread placements retain the expected numerical host-slot results; the burst report gives 16 host slots per four-row window. All 11 single-value option forms across these two CLIs reject repetition by name.
  • The parser's zero/full-capacity boundary assertions pass. This is not a claim that every all-card report succeeds: the unchanged report's zero-host denominator crash was reproduced on main and separately filed as window-union: a valid placement with no host selections divides by zero #656. This PR does not change report arithmetic.
  • Owning static checks: fmt, check-arch, check-comments, and check-levers passed. As in fix(recipes): retain includes and literals inside multiline attributes #658, the initial concurrent worktree runs interfered with the process-global CPU-guard fixture. After serializing those checks, full check-recipes passed at 2498a35a in 137 s. No skipped units, threshold changes or timeout increases were used.
  • No GPU execution claim. Local pre-review cannot run without the Claude CLI; remote review/CI remain separate.

Current-head review correction at 7cfab04

The empty-placement MUST_FIX is addressed: both bursts admission checks use spec is not None, so an explicitly empty --n-l is validated and refused instead of silently becoming an omitted placement. The added real-CLI regression failed before the correction and passes after it. Actual CLI execution now exits 1 naming --n-l, without a traceback; omitted, zero-card and partial-card reports remain byte-for-byte unchanged. Both full replay self-tests pass.

The final owning run at committed 7cfab049 passed 5 / 5 (fmt, check-arch, check-comments, check-levers, full check-recipes), wall 159 s. Check-recipes took 138 s; all original bounds and units remain in place. The omitted/empty distinction is documented.

@github-actions github-actions Bot added documentation Improvements or additions to documentation tools Tools, recipes, CI and the toolchain: tools/, justfile, .github/, Cargo labels Oct 22, 2026

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Verdict: MUST_FIX: bursts accepts an explicitly empty placement and reports a successful host-only replay.

Must fix

1. Send an empty --n-l through placement validation

tools/ref/router-coverage.py:471 bursts <valid-set> --window 4 --n-l "" passes an empty string to bursts. Both truthiness checks skip placement validation, build empty card sets, and return 0 with the same report as omitting the option. Direct parse_n_l("", layers, n_expert) rejects it with a named error. This is a reachable kind A failure in the placement-validation path this fix PR changes.

Fixing both checks now closes the bypass while the placement-validation tests are being added.

Replace the assignment at line 466 with:

    wu = window_union() if spec is not None else None

Replace the condition at line 471 with:

        if spec is not None:

Add this entry to cases in window-union.py's existing CLI refusal test:

            ("router-coverage.py", ["bursts", cli, "--window", "4", "--n-l", ""], "--n-l"),

Checked

Duplicates: no new functions, types, or constants; no duplicate finding.
Complexity: placement-validation and CLI-refusal branches; no engine hot path changes.
Silent failure: followed the empty placement from CLI parsing through card construction to the successful report.
Tests: the CLI entry point with in-memory trace files reproduces the bypass. Both replacements compile and make empty input return 1 naming --n-l; omitted and valid-placement reports remain identical. All three bursts options still reject repetition. The added refusal cases omit empty input.
Gates: no thresholds or pins moved; the upper-count refusal assertion moved to the parser.
Escape catalog: C1–C4 do not match the diff.

Notes

Dryer and crapper did not run because no Rust file changed. Full self-tests were not rerun during validation.

🔨 Shingler, bloomery's review bot: approves a clean pull request and requests changes on a must-fix (how it works)

@Burntgogi

Burntgogi commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor Author

Addressed the current MUST_FIX in 7cfab04.

Both placement-admission checks now distinguish omission (None) from an explicitly empty string. The empty value reaches the same parse_n_l validation and named-error boundary as other supplied placements. The existing CLI-refusal fixture includes bursts --window 4 --n-l ""; the contributor documentation states the omitted/empty distinction.

FAIL-first: the added regression failed because the command returned 0 with a host-only report. After the fix, the actual command exits 1 naming --n-l and has no traceback. Separate omitted, zero-card, and partial-card report controls remain byte-for-byte unchanged. Both full replay-tool self-tests pass. The final isolated owning checks at committed 7cfab049 passed 5/5 in 159 s (full check-recipes 138 s), with all original units and limits retained.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Since the last review: must-fix 1 is fixed at tools/ref/router-coverage.py:471. Explicitly empty --n-l reaches placement validation and returns a named error. The new CLI case covers it.

Verdict: CLEAN: The empty-placement bypass is fixed, and the incremental diff introduces no proven defect.

Checked

Duplicates: 0 new functions, types, or constants; no duplicate finding.

Complexity: two guard substitutions; no added branches or engine hot-path changes.

Silent failure: both placement guards traced. Empty input reaches parse_n_l; its named error is translated to the CLI's SetError and returns 1 before printing a report.

Tests: the added CLI case asserts exit 1, a named --n-l error, and no traceback. Restoring the first old guard would produce a traceback; restoring the second would return a successful report. Either mutation fails the new assertions.

Gates: no gates removed, thresholds changed, or pins moved.

Escape catalog: C1–C4 do not match.

Notes

Dryer and crapper did not run because no Rust file changed. Validation used source inspection; full self-tests were not rerun.

🔨 Shingler, bloomery's review bot: approves a clean pull request and requests changes on a must-fix (how it works)

@juliankang4
juliankang4 merged commit 7487861 into midagedev:main Oct 22, 2026
7 checks passed
@juliankang4

Copy link
Copy Markdown
Collaborator

@Burntgogi Thanks for the contribution. The review is done, so I'm merging this.

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

Labels

documentation Improvements or additions to documentation tools Tools, recipes, CI and the toolchain: tools/, justfile, .github/, Cargo

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants