Description
writeFrontmatter (in @codeassembly/kb) renders title, created, and updated unconditionally, in a fixed order. The Frontmatter model treats them as first-class string fields, and parse-note.ts defaults each to '' when the source omits it. This is assertion-shaped: assertions carry title/created/updated, but event records do not (they use captured-at, have no title, and — until #809 — no updated).
So writing an event back through writeFrontmatter injects title: '' and created: '' into it. Validation then rejects the record, because created is a date field (DATE_FIELDS) and '' is not a valid date:
created: expected YYYY-MM-DD or YYYY-MM-DDTHH:MM:SSZ, got ""
writeBackNote validates before the atomic write, so the write is refused and the note is left untouched — which means every kb-edit operation on an event fails outright. --add-addressed-by (#785) is the first operation pointed at events, so it is the first to surface that the write path cannot round-trip a non-assertion record.
This is independent of the schema declarations in #809: even with updated/addressed-by declared on the event type, the writer still injects an empty title/created, and the date rule still rejects the empty created.
Context
Acceptance criteria
Must have
Description
writeFrontmatter(in@codeassembly/kb) renderstitle,created, andupdatedunconditionally, in a fixed order. TheFrontmattermodel treats them as first-class string fields, andparse-note.tsdefaults each to''when the source omits it. This is assertion-shaped: assertions carrytitle/created/updated, buteventrecords do not (they usecaptured-at, have no title, and — until #809 — noupdated).So writing an
eventback throughwriteFrontmatterinjectstitle: ''andcreated: ''into it. Validation then rejects the record, becausecreatedis a date field (DATE_FIELDS) and''is not a valid date:writeBackNotevalidates before the atomic write, so the write is refused and the note is left untouched — which means everykb-editoperation on aneventfails outright.--add-addressed-by(#785) is the first operation pointed at events, so it is the first to surface that the write path cannot round-trip a non-assertion record.This is independent of the schema declarations in #809: even with
updated/addressed-bydeclared on theeventtype, the writer still injects an emptytitle/created, and the date rule still rejects the emptycreated.Context
packages/kb/src/frontmatter/write-frontmatter.ts(unconditional emit),packages/kb/src/frontmatter/parse-note.ts(defaults to''),packages/kb/src/types.tsandfrontmatter-schema.ts(first-class fields),packages/kb/src/rules/frontmatter-rule.ts(DATE_FIELDS).title/created/updatedonly when the record actually carries them, rather than always — so it round-trips events (and any future non-assertion record) without injecting empty values. The deeper modeling smell — assertion-specific fields baked into a sharedFrontmattertype — can be resolved here or noted for later.addressed-by; blocks that marking.Acceptance criteria
Must have
writeFrontmatterround-trips aneventrecord without injectingtitle,created, orupdatedfields the record does not carry.kb-editoperation (e.g.--add-addressed-by) on aneventproduces a record that passes schema validation, including the date-format rule (no emptycreated).title/created/updated(assertions) still round-trip unchanged.eventthrough a write operation.