Skip to content

fix: job --dry-run would_slice matches real-run slicing decision - #88

Merged
DLANSAMA merged 1 commit into
mainfrom
fix/job-dry-run-would-slice
Jul 29, 2026
Merged

fix: job --dry-run would_slice matches real-run slicing decision#88
DLANSAMA merged 1 commit into
mainfrom
fix/job-dry-run-would-slice

Conversation

@DLANSAMA

@DLANSAMA DLANSAMA commented Jul 29, 2026

Copy link
Copy Markdown
Owner

Root cause

plate job/send <url> --dry-run --json predicted would_slice from the raw
URL-path extension via _predicted_url_download_extension, which returns None
when the URL path carries no file extension — the case for Printables model
pages
(/model/12345-foo) and extension-less direct links
(/download?id=1). With no extension, the dry-run branch in
bambu_cli/job/orchestrate.py left would_slice at its False default.

The real run decides slicing from the downloaded file's extension
(orchestrate.py: if ext in SLICEABLE_EXTENSIONS). The downloader falls back
to .stl when it cannot infer an extension (_download_source_extension), and
the Printables resolver prefers STL/STEP — both sliceable. So the real run
sliced while the dry-run reported would_slice: false. The predictor and doer
computed "does this need slicing?" differently.

The fix

One shared slicing predicate, used by both paths:

  • _ext_would_slice(ext) (bambu_cli/job/predict.py) — the single rule:
    ext in SLICEABLE_EXTENSIONS, applied to the single-suffix _file_extension
    so foo.gcode.3mf is print-ready .3mf on both sides. The real-run local,
    ZIP-member, and post-download branches in orchestrate.py all route through
    it.
  • _predicted_download_slice_extension(url, args) — resolves the URL's
    predicted extension by reusing the downloader's own
    _download_source_extension, which lands the same .stl fallback the real
    download uses for extension-unknowable sources. --name is intentionally
    ignored because the real download overrides the --name extension with the
    URL/resolved-name extension (_download_filename_with_extension), so honoring
    it in the predictor would reintroduce a divergence.

would_slice stays a boolean; no JSON shape / docs/schemas change. For a
Printables page, remote_name remains null (unpredictable offline) — the fix
does not fabricate one.

Test coverage

  • Extended the direct-URL dry-run matrix: .stl/.step/.obj → slice,
    .zip → extract, .3mf and .gcode.3mf → print-ready.
  • test_dry_run_printables_model_url_predicts_slice — the regression: Printables
    model page now reports would_slice: true, remote_name: null.
  • test_dry_run_extensionless_url_predicts_slice?id=1 predicts slicing.
  • test_predictor_and_doer_share_slice_predicate — asserts the predictor's
    decision equals the doer's for the same resolved extension (drift guard).
  • test_dry_run_local_gcode_3mf_is_print_ready_not_sliced — local .gcode.3mf.
  • test_dry_run_local_zip_member_slice_matches_predicate — ZIP members
    .stl (slice) vs .3mf/.gcode.3mf (print-ready).
  • Strengthened the Printables dry-run agent smoke to assert would_slice: true.

Sabotage-verified: reverting _predicted_download_slice_extension to the old
URL-path inference makes the three URL-prediction tests fail with the exact
would_slice False vs True divergence; restoring the fix makes them pass.

Gates (local)

  • pytest -m "not live" with coverage: 1018 passed, 84.57% (floor 83)
  • ruff check, ruff format --check: clean
  • mypy -p bambu_cli: no issues (56 files)
  • bandit -ll: exit 0
  • privacy_smoke, python_compat_smoke, agent_cli_smoke: ok

`plate job/send <url> --dry-run` predicted `would_slice` from the raw URL-path
extension, which is absent for Printables model pages and extension-less direct
links. In those cases the predictor returned `would_slice: false`, but the real
run downloads a model file (the downloader falls back to `.stl` when it cannot
infer an extension) and slices it — so the dry-run pre-check disagreed with what
actually happened.

Fix: share one slicing predicate between the predictor and the doer.

- `_ext_would_slice(ext)` in bambu_cli/job/predict.py is now the single rule
  (`ext in SLICEABLE_EXTENSIONS`, applied to the single-suffix `_file_extension`
  so `foo.gcode.3mf` stays print-ready). The real-run local, ZIP-member, and
  post-download branches in orchestrate.py all route through it.
- `_predicted_download_slice_extension(url, args)` resolves the URL's predicted
  extension by reusing the downloader's own `_download_source_extension`, which
  falls back to `.stl` for sources whose extension is unknowable offline. `--name`
  is intentionally ignored because the real download overrides the `--name`
  extension with the URL/resolved-name extension.

`would_slice` remains a boolean; no JSON shape or schema change.

Tests: extended the direct-URL dry-run matrix (.stl/.step/.obj/.zip/.3mf and
.gcode.3mf), added Printables-model-URL and extension-less-URL predictions, a
predictor/doer shared-predicate equivalence test, local .gcode.3mf print-ready,
and a ZIP-member matrix (.stl slices, .3mf/.gcode.3mf do not). Strengthened the
Printables dry-run agent smoke to assert would_slice=True.
@DLANSAMA
DLANSAMA force-pushed the fix/job-dry-run-would-slice branch from 61f089c to 08a4733 Compare July 29, 2026 18:44
@DLANSAMA
DLANSAMA merged commit 9bc90ca into main Jul 29, 2026
6 checks passed
@DLANSAMA
DLANSAMA deleted the fix/job-dry-run-would-slice branch July 29, 2026 19:28
DLANSAMA added a commit that referenced this pull request Jul 30, 2026
* fix: download/slice/job pipeline correctness from deep audit

* fix: kill slicer tree on Ctrl-C; restore #88 changelog; review minors

* docs: refresh test-count snapshots after audit-fix merges (1123 collected)

---------

Co-authored-by: DLANSAMA <258674612+DLANSAMA@users.noreply.github.com>
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.

1 participant