Skip to content

A plan's mistyped key is applied at its default while a bad value is refused by name #89

Description

@vyncint

Today — a plan is checked value by value and not at all key by key. Against 0.6.3, with a background plan the tool saved itself:

$ mossaic-art VYNCINT --year 2026 --start-week 6 --background 2 --save --plan ./bg.json --no-colour >/dev/null
$ mossaic-art --track --plan ./bg.json --merge … --format json | jq -c '{field_level}'
{"field_level":2}

$ # the same file with `background` renamed `backgruond`
$ mossaic-art --track --plan ./bgtypo.json --merge … --format json | jq -c '{field_level}'
{"field_level":0}
exit=0            (stderr empty)

$ # by contrast, a bad VALUE:
$ mossaic-art --track --plan ./bgbad.json --merge … --no-colour
mossaic-art: ./bgbad.json is not a plan these tools can … background is 99, which is not between 0 and 4

A key a build simply does not have behaves the same way. Dropping art, or renaming it Art, turns a 146-day picture into a 79-day text at exit 0:

plan.json    {"text":"Dragon","columns":53,"letters":146,"owing_commits":6902}
noart.json   {"text":"DRAGON","columns":35,"letters":79,"owing_commits":4602}

and --backfill then asks for a different date range and a different total (65 days / 4,294 contributions for the picture, 42 days / 4,382 commits from 2026-01-04 to 2026-08-18 for the text).

Worth saying what this is not, so it is not re-argued in the thread: a plan carrying keys this build has never heard of behaves identically to one without them (schema + outline added: byte-identical output), and the old-reader direction is already written down as deliberate and unfixable in CHANGELOG 0.6.0:302-308, with art's #[serde(default)] documented as intentional at src/plan.rs:583-589.

Why it is worth fixing — src/plan.rs:592-601 already argues the case: "A plan is input: --plan PATH names a file, and a file may have come from somewhere other than your own --save. Without this it was the way around every bound the command line enforces." validate() then bounds year, top, commits, start_week, background and the stored picture's width — every value, and no part of the shape. So the loader refuses background: 99 by name and accepts backgruond: 2 in silence, applying the default instead: about 290 background days become keep-dark days, the one kind the Action's README calls "do not commit today".

The plan is the input to --backfill --write, and contributions cannot be unlit. A hand-edit typo produces permanent commits with exit 0 and nothing on stderr to look back at, from a loader that is loud about every other kind of wrong.

Fix#[serde(deny_unknown_fields)] on plan::Spec is the mechanical part, and it turns a typo into the same loud refusal a bad value already gets. It is not free: it also refuses a plan written by a newer mossaic, which is the forward direction CHANGELOG 0.6.0 deliberately left open, so this is a policy call rather than a cleanup. Two ways to have both:

  • write a version (or schema) field on save and refuse only a version higher than the build understands, keeping unknown keys tolerated within a known version; or
  • take deny_unknown_fields and accept that a plan is version-locked to the tool that wrote it, which is closer to what the file already is in practice.

Either way the one-sentence caveat missing from docs/ART.md's "Saving the plan" section is not optional: that section teaches --save and never says a picture plan needs a mossaic that understands art.

Done when — a plan carrying a key Spec does not recognise is refused by name and non-zero rather than applied at its default, and the message says which key; the chosen forward-compatibility rule is written down in docs/ART.md's "Saving the plan" section alongside the picture-plan caveat; and tests/art_cli.rs covers a mistyped key, a bad value, and — if a version field lands — a plan from a future version.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions