Skip to content

Route the capture-event add path through the KbEvent record contract #958

Description

@williamthorsen

Problem

capture-event's fresh-capture path (prepareEvent) hand-assembles a raw frontmatter field array and serializes it through a bespoke renderEventNote helper family, instead of composing a KbEvent and rendering it through the record module's renderEvent. It is the last event write path outside the KbEvent contract: the amend path already composes a KbEvent and round-trips through renderEvent/parseEvent, and #853 already moved add-path validation to parseEvent. Because the bespoke renderer orders fields differently from renderEvent, the same event captured then amended silently reorders its frontmatter.

Context

Part of the per-type record architecture epic (#848). Sibling pattern: kb-add composes a KbAssertion and renders via renderAssertion (#852). #853 already removed the generic loadSchema/frontmatterRule/runRules path from capture-event — those symbols no longer exist anywhere in the repo — so this is the composition remainder, not a rule-engine migration.

The add path writes via the collision-safe hard-link writer (writeEvent), which the amend path's overwrite writer (writeNote) cannot replace; so the add path renders to a string via note-io's renderNote and keeps writeEvent.

Proposed solution

Compose a KbEvent in prepareEvent (with repo/skill/model/harness carried in extra, since KbEvent has no typed field for them) and render it via renderEvent → note-io renderNote, deleting the bespoke renderEventNote/renderFlowList/renderScalar/SCALAR_STRINGIFY_OPTIONS family. Retain the post-render re-parse guard through parseEvent, mirroring the amend path.

Acceptance criteria

Must have

  • prepareEvent composes a KbEvent and renders it via renderEvent, not a hand-assembled field array.
  • The bespoke event serializer (renderEventNote and its scalar/list helpers) is removed.
  • A freshly captured event's frontmatter field order matches the amend path's renderEvent output (typed fields first; repo/skill/model/harness as trailing extra fields).
  • The rendered record is validated by re-parsing through parseEvent.
  • New and modified behavior in this change is covered by tests.

Metadata

Metadata

Assignees

No one assigned

    Labels

    refactoringImprovement to code without change in functionalityscope:agents

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions