Skip to content

Add an addressed-by/addresses relation linking problems to their responses #763

Description

@williamthorsen

Problem

The substrate records problem observations (events) but has no way to thread a problem to what was done about it. When recall surfaces a recurring bug event, the reader's first question — "was this ever addressed, and how?" — has no answer in the record; the link to the response is a dead end. The only relation available today is supersedes/superseded-by, which is the wrong semantics: superseding deprecates the old record, but a problem that has been addressed is not deprecated. It remains a true observation, and its recurrence is signal worth keeping.

Context

  • supersedes/superseded-by is a 1:1 chain (recall walks it hop by hop in kb-retrieve's normalize.ts). The problem→response link is many-to-many: one response can address many problems, and one problem can accrue many responses.
  • The responder is frequently not a KB note — a commit, a PR, or a URL — so the relation often can only live on the problem record, not on the responder.
  • Recall is event-centric (recurrence-recency surfaces events), so the field recall reads must live on the event.
  • This emerged from Remove the unused immutable flag from the record-type schema #748 (removing the immutable flag). Annotating events with response pointers is the use case that motivated reconsidering event mutability; the conclusion was that a metadata relation, not a frozen or append-only model, is the right home.
  • Not strictly event-only: any record noting a problem could carry addressed-by, though events are the motivating case.

Why addressed-by, not resolved-by

The field is populated when a response is made, not when its success is confirmed. "Resolved" asserts an outcome the writer usually cannot vouch for at write time: some bugs are verifiably fixed (the steps to reproduce no longer reproduce the error), but refinements to agent guidance only reduce recurrence and are rarely verifiable. addressed-by stays true across that whole spectrum — a full fix and a mitigation both address the problem. Verifiable resolution is a status of the problem, orthogonal to what was done, so it does not belong in the relation name; if it is ever tracked, it belongs on the problem (for example, a tag), not as a second relation. A single neutral relation also matches the project's single-pair supersedes precedent and avoids the redundant double-pointer that a resolved-as-subset-of-addressed pair would force.

Proposed solution

Add an addressed-by/addresses inverse-pair relation, both multi-valued (list fields):

  • addressed-by on the problem record is the canonical, recall-facing field: a list of references to whatever was done about the problem. It is the workhorse and the only viable store when the responder is external (commit/PR/URL).
  • addresses on a KB-note responder is an optional inverse for the rare "what does this address?" query, documented as non-authoritative — not a required bidirectional invariant, since keeping it in sync would be an N-file write.
  • References are a heterogeneous free-form list: a KB wikilink or relative path, a commit SHA, a PR/issue ref, or a URL. The accepted forms are documented. The field's shape is validated as a list (like tags), while entries are not individually validated — they are free-form, like the existing sources field.
  • Placement: addressed-by is available on event (the motivating problem-bearer, and the field recall reads) and on assertion; addresses is available on assertion (the KB-note responder). Events do not carry addresses.
  • Recall surfaces an event's addressed-by alongside its recurrence signals, so a recurring-but-addressed problem reads as addressed rather than unaddressed. The list is surfaced flat — no chain-walking, unlike supersedes.
  • kb-curate deliberately gains no asymmetry or dangling checks for this relation; policing symmetry would contradict the non-authoritative inverse and the heterogeneous, often-external references the list is designed to hold.

Acceptance criteria

Must have

  • A problem record can declare addressed-by as a list of references to whatever was done about it.
  • addressed-by is an optional field on the event and assertion record types.
  • The accepted reference forms are defined and documented; list shape is validated (like tags), while entries are free-form (like sources).
  • Recall surfaces an event's addressed-by so an addressed recurring problem is distinguishable from an unaddressed one.
  • New behavior is covered by tests.
  • Documentation (README and affected skills) describes the relation, its many-to-many cardinality, and why it is distinct from supersedes/superseded-by.

Should have

  • addresses is available as the optional inverse on the assertion record type, documented as non-authoritative (the problem-side addressed-by is canonical).

Dependencies

Metadata

Metadata

Labels

featureAdded or improved external functionalityscope:kb

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions