Skip to content

fix: surface two silently-dropped configs - #145

Merged
pedropaf merged 1 commit into
mainfrom
fix/silent-config-drops
Jul 20, 2026
Merged

pedropaf merged 1 commit into
mainfrom
fix/silent-config-drops

Conversation

@pedropaf

Copy link
Copy Markdown
Collaborator

Two bugs found while running a 36-image prompt experiment today. They share a failure mode: the config looks accepted, nothing errors, and the run is quietly not what was asked for. That's the worst kind of bug for batch work — you only find out by auditing output counts.

1. seeds: under defaults: was silently discarded

StepDefaults has seed (singular) and no deny_unknown_fields, so serde dropped seeds: without complaint.

defaults:
  seeds: [7, 42, 1234]   # ignored — 1 image per step, not 3

I hit this designing a seed-replication run. It only surfaced because I happened to --dry-run first and noticed count=1. Had I not, I'd have drawn conclusions from a third of the intended data.

Unknown keys are now captured via #[serde(flatten)] and warned at parse time, with a specific hint for seeds since it's step-level only:

! `seeds` is not a workflow default — it is only valid on a step, and was ignored here.
  Move `seeds: [...]` onto each step.
! unknown key `bogus` under `defaults:` — ignored

Warn rather than deny_unknown_fields so existing workflows carrying stray keys keep running. This catches every future typo under defaults:, not just this one.

2. Missing persistent worker was invisible

try_submit_via_socket swallowed the connect error and fell back to one-shot mode. Without a running daemon every job reloads the model from scratch — indefinitely, with no indication. Every run I did today paid this, and I only noticed by reading executor.rs.

Now hints once per process:

i No persistent worker — each job reloads the model.
  Start one with `modl worker start` to keep it in VRAM.

Not auto-started: that's a bigger decision about VRAM ownership and belongs in its own change.

3. Docs: --skip-existing doesn't exist

skills/modl/SKILL.md documented a flag that was never implemented. Skipping already-generated sub-jobs is the default; --force opts out. (The same error is in the org-level CLAUDE.md, which isn't in this repo — fixed separately.)

Testing

  • 232 tests pass (231 + 1 new regression test pinning the inert-seeds behaviour)
  • Both warnings verified firing against a real workflow
  • cargo fmt + clippy clean via pre-commit

🤖 Generated with Claude Code

Both bugs share a failure mode: the config looks accepted, nothing errors,
and the run is quietly not what was asked for.

`seeds:` under a workflow's `defaults:` was silently discarded. `StepDefaults`
has `seed` (singular) and no `deny_unknown_fields`, so serde dropped the key
without complaint — a 3-seed batch produced 1 image per step and looked fine.
Unknown keys are now captured via #[serde(flatten)] and warned at parse time,
with a specific hint for `seeds` since it is step-level only. This catches
every future typo under `defaults:`, not just this one.

`try_submit_via_socket` swallowed the worker connect error and fell back to
one-shot mode, so without a running daemon every job reloads the model from
scratch, forever, with no indication. Now hints once per process pointing at
`modl worker start`.

Docs: `--skip-existing` does not exist. Skipping already-generated sub-jobs is
the default; `--force` opts out. Corrected in skills/modl/SKILL.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@pedropaf
pedropaf merged commit cc40448 into main Jul 20, 2026
8 checks passed
@pedropaf
pedropaf deleted the fix/silent-config-drops branch July 20, 2026 09:26
pedropaf added a commit that referenced this pull request Jul 22, 2026
`modl run` skips sub-jobs whose work is already on disk, but the completion
key was only (prompt, seed, model). Re-running the same prompt/seed at a
different guidance or step count matched the old key, so the run skipped
generation and handed back the STALE image while printing `✓ complete` and
exiting 0. Any guidance/steps sweep was silently corrupted — the same
failure class as the silently-dropped configs (#145): it looks accepted,
nothing errors, and the run is quietly not what was asked for.

The completion key is now (prompt, seed, base_model, steps, guidance). The
generate spec is built before the skip check so the resolved steps/guidance
(after fast/lightning/default precedence) go into the key, then reused for
execution — no double build. Guidance is an f32 (neither Eq nor Hash), so it
is quantized to an integer (×1000, rounded) that round-trips stably through
the YAML sidecar. Edit steps have no skip path, so no change there.

Tests: completion_index_keys_on_steps_and_guidance (distinct settings are
distinct keys; unseen settings miss) and quantize_guidance_is_stable_and_distinct.
Verified end-to-end with SD-1.5: identical guidance skips, changed guidance
regenerates.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.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