Skip to content

Remove the unused immutable flag from the record-type schema #748

Description

@williamthorsen

Problem

The record-type schema declares an immutable: boolean per record type (event is true, assertion is false), but nothing reads it. kb-edit never gates on it, recall (kb-retrieve) ignores it, and validation never enforces it. So immutable: true is a declared-but-unconsumed field that implies an enforced write-once guarantee while providing none — a trust gap, since anyone reading the schema reasonably assumes the flag does something.

This ticket originally proposed making kb-edit honor the flag. Investigation showed enforcement would protect almost nothing: recall ranks events on captured-at and a repo-keyed recurrence count, never on updated; no kb-edit operation touches those recall-critical fields; the gate would be advisory only (a hand-edit, sed, or merge bypasses it); and freezing tags would actively degrade recall, since tags are a live recall signal that benefits from curation. Removing the false signal is the honest fix.

Context

  • The flag is declared in RecordTypeSchema (packages/kb/src/types.ts), set in default-schema.ts, parsed in load-schema.ts, and materialized into seed schemas via render-seeds.ts and bundle-skill-helpers.ts.
  • Events stay write-once in practice without the flag: capture-event only ever creates event records, and its SKILL.md already states "Captures are write-once: there is no edit or re-capture step." That guidance, not the schema flag, is what keeps events write-once.
  • The field lists already encode the lifecycle shape: event omits updated/last-verified/superseded-by from its required and optional sets. The boolean was a fuzzier restatement of that.
  • If genuine enforcement is ever wanted, the right mechanism is optional-allowlist validation (reject undeclared frontmatter fields), driven by the existing field lists. Tracked separately, not part of this change.

Proposed solution

Remove immutable from the schema vocabulary and every place that declares, parses, or materializes it. kb-edit is deliberately out of scope: it never read the flag, so its behavior is identical before and after, and adding an event-mutation guard was considered and declined (it would either resurrect the advisory enforcement we're removing or introduce an inconsistent partial check). capture-event's write-once narrative stays accurate, since it describes the helper's create-only write rather than the flag. An on-disk .kb/schema.yaml that still declares immutable: continues to load: the zod record-type shape strips the unknown key rather than rejecting it, so existing stores are unaffected.

Acceptance criteria

Must have

  • immutable is removed from RecordTypeSchema and from the default schema's record types.
  • load-schema no longer parses or normalizes immutable, and a .kb/schema.yaml that still declares immutable: loads successfully with the key ignored.
  • Seed/materialization paths (render-seeds, the bundled capture-event store schema in bundle-skill-helpers.ts) no longer emit immutable:.
  • Tests and fixtures that assert or seed immutable are updated or removed, and the schema-compat behavior above is covered by a test.

Should have

  • packages/kb/README.md's schema documentation is updated to drop immutable. Narrative write-once/immutable language describing capture-event's create-only write is left intact where still accurate.

Dependencies

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions