Skip to content

fix(schema): accept unknown speaker_map source instead of aborting the parse (#595) - #597

Merged
silverstein merged 1 commit into
mainfrom
fix/lenient-attribution-source
Jul 29, 2026
Merged

fix(schema): accept unknown speaker_map source instead of aborting the parse (#595)#597
silverstein merged 1 commit into
mainfrom
fix/lenient-attribution-source

Conversation

@silverstein

Copy link
Copy Markdown
Owner

Fixes #595, reported by @jmh1313 with a diagnosis that identified both the bug and the thing that caused it.

The bug

An out-of-vocabulary speaker_map[].source aborted the entire frontmatter parse, hard-blocking minutes resummarize on that file. The sharp part, as the report puts it: resummarize's own documented field contract lists speaker_map among the fields preserved untouched, and it failed before the model call. So the command refused to run because of a value it would never have read or written.

Hand-edited files are a supported input class. The desktop app's Open in Editor button invites direct edits, resummarize's own premise is that the file is open in an editor right now, and minutes import text ingests third-party archives that never went through the pipeline. A label describing how an attribution was derived should not be able to make a meeting unreadable.

The trap that generated it

user-confirmed is not a value Minutes has ever emitted. The schema doc listed the valid enum, then eleven lines later labelled the confidence ladder L3 (user-confirmed). Someone hand-editing reads that and writes source: user-confirmed. The actual variant is manual.

Fix

  • AttributionSource gains an untagged Unknown(String) in both definitions (core and reader). The raw label round-trips verbatim rather than being normalized, so provenance survives a rewrite by a command that never consumed it. This drops Copy; three call sites now take a reference.
  • The schema doc now states the L-levels are a conceptual ladder, not the on-disk vocabulary, and gives the source: value for each level, explicitly noting L3 is manual and that user-confirmed is invalid.
  • The hand-maintained TypeScript copy is widened to match, and the JSON schema snapshot now describes the lenient shape (anyOf: [known enum, string]).

Not done: ask 3, a minutes consistency --fix repair path for out-of-vocabulary values. Worth doing, but it is a separate feature rather than part of unbreaking the read path.

Verification against the reporter's exact repro

unfixed:  Error: frontmatter does not parse: speaker_map[0].source: unknown variant `user-confirmed`
fixed:    preview completes; --apply writes; file still reads `source: user-confirmed`

Core lib 1176 passed, CLI 82 passed, clippy clean on core and reader, fmt clean, SDK typecheck clean.

One note on the diff

tauri/src-tauri/gen/schemas/*.json are regenerated files carrying the tauri 2.11.5 permission additions from #590, which landed without regenerating them. They are unrelated to this fix but correct, and dropping them would leave main stale.

🤖 Generated with Claude Code

…e parse (#595)

An out-of-vocabulary speaker_map[].source aborted the whole frontmatter parse,
which hard-blocked `minutes resummarize` on that file, even though resummarize's
documented field contract lists speaker_map among the fields preserved
untouched. It failed before the model call on a value it would never read.

Hand-edited files are a supported input class: the desktop app's Open in Editor
button invites direct edits, resummarize's own premise is that the file is open
in an editor, and `minutes import text` ingests third-party archives that never
went through the pipeline. A provenance label describing how an attribution was
derived should not be able to make a meeting unreadable.

AttributionSource gains an untagged Unknown(String) variant in both definitions
(core and reader). The raw label round-trips verbatim rather than being
normalized, so provenance survives a rewrite by a command that never consumed
it. This drops Copy; the three affected call sites now take a reference.

Also closes the trap that generated the bad value: the schema doc presented
L0-L3 as parallel to the source enum, but L3's label 'user-confirmed' has no
matching variant (the real one is 'manual'). The ladder is now explicitly
labelled conceptual, with the on-disk value given for each level. The
TypeScript copy in the SDK is widened to match, and the JSON schema snapshot
now describes the lenient shape.

Verified against the reporter's exact repro: the unfixed binary reproduces
'unknown variant `user-confirmed`', the fixed one completes a preview and an
--apply, and the file still reads `source: user-confirmed` afterwards.

Reported by @jmh1313. Fixes #595

Co-Authored-By: Claude Opus 5 <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.

resummarize hard-fails on an unknown speaker_map[].source, a field its own contract preserves untouched (and the schema doc invites the invalid value)

1 participant