Skip to content

Heal legacy frontmatter automatically; never hard-fail on old enum values#4

Merged
execsumo merged 2 commits into
mainfrom
claude/dossier-backwards-compat-col8qd
Jun 25, 2026
Merged

Heal legacy frontmatter automatically; never hard-fail on old enum values#4
execsumo merged 2 commits into
mainfrom
claude/dossier-backwards-compat-col8qd

Conversation

@execsumo

Copy link
Copy Markdown
Owner

Problem

Updating Dossier on a machine with existing dossiers errored with invalid importance: "medium". Root cause is broader than stale data: the importance/urgency schema narrowed from a three-level scale to binary high|low (SPEC.md, Eisenhower 2×2), but the write side never locked down — the MCP tool schema still advertised low|medium|high, the CLI passed non-h/l values through verbatim, and SPEC.md documented h|m|l. So even a fresh install could regenerate the error. Validation runs on every write over the whole frontmatter (fsstore.go:291), so a single bad value locked the entire record against any edit.

Fix

A general normalization layer with the invariant "map toward attention, not away": any value that is no longer a valid enum member, or a field absent from an older file, coerces to its highest-attention valid value (importance/urgencyhigh, statusactive). Implemented once in Frontmatter.Normalize (internal/core/dossier.go) and wired at three layers so it self-heals without manual steps:

  • Read / sortCalculatePriorityScore normalizes its copy, so a legacy medium dossier sorts toward attention immediately instead of silently collapsing to low.
  • WriteService.Save heals + persists canonical + emits a Warning per coercion (surfaced via CLI/MCP/TUI).
  • Startup — a version-gated one-time sweep (Service.Migrate, config.schema_version vs core.CurrentSchemaVersion) runs from wire, rewriting every stale Dossier once and logging to stderr (never stdout, so mcp serve stays clean). The gate makes it a no-op on every subsequent launch.

doctor now reports legacy values as healable rather than fatal. The write-side source of medium was also closed: MCP tool schema, CLI --importance/--urgency mapping, and the SPEC.md CLI synopsis.

Extending for a future field: add the field's Normalize + one block in Frontmatter.Normalize, and bump CurrentSchemaVersion.

Verification

  • Table tests for the enum and Frontmatter normalizers (incl. idempotency), priority-score-toward-attention, Save heals+warns, and Migrate store-wide + idempotent.
  • Full suite, go vet, and gofmt all clean.
  • End-to-end against the real filesystem store: a hand-written legacy importance: medium file auto-healed to high on the next launch (with stderr warning + version bump), and the second run was silent.

Note for reviewers

One judgment call: an unknown status coerces to active (toward visibility). If unknown statuses should instead map to blocked (force triage), that's a one-line change.

🤖 Generated with Claude Code

https://claude.ai/code/session_016hmNrNMx38h6ewgJwJXpEp


Generated by Claude Code

claude added 2 commits June 25, 2026 17:18
…lues

A store written by an older build (e.g. importance: medium from before the
binary high/low schema) errored with "invalid importance" on load/edit. Add a
general normalization layer with the invariant "map toward attention, not
away": any value that is no longer a valid enum member, or a field absent from
an older file, coerces to its highest-attention valid value (importance/urgency
-> high, status -> active).

Wired at three layers so it is self-healing without manual steps:
- read: CalculatePriorityScore normalizes its copy, so legacy values sort
  toward attention immediately instead of silently collapsing to low.
- write: Service.Save heals + persists + emits a Warning per coercion.
- startup: a version-gated one-time sweep (Service.Migrate, config
  schema_version vs core.CurrentSchemaVersion) runs from wire, rewriting every
  stale Dossier once and logging to stderr (never stdout, so mcp serve stays
  clean).

doctor now reports legacy values as healable rather than fatal. Closed the
write-side source of "medium" (MCP tool schema, CLI --importance/--urgency
mapping, SPEC CLI synopsis). Extending for a future field: add its Normalize
plus one block in Frontmatter.Normalize and bump CurrentSchemaVersion.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016hmNrNMx38h6ewgJwJXpEp
Pre-existing formatting issue unrelated to the normalization change, but the
CI `gofmt -l .` gate checks the whole tree and was failing the build.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016hmNrNMx38h6ewgJwJXpEp
@execsumo
execsumo merged commit 0f3d7fb into main Jun 25, 2026
1 check passed
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.

2 participants