From bc1be6bae97c915579ce89317df751a2274855fa Mon Sep 17 00:00:00 2001 From: Leo Date: Tue, 14 Jul 2026 09:49:42 -0400 Subject: [PATCH] docs(adr): ADR-041 Amendment A3 - SearchExecuted polymorphic result_kind (#806) Entity searches project Candidate/Selected rows as entity referents via a closed result_kind payload key; legacy payloads without the key keep the historical note-shape projection, never a decode error. Co-Authored-By: Claude Fable 5 --- .../ADR-041-event-provenance-projection.md | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/docs/adr/ADR-041-event-provenance-projection.md b/docs/adr/ADR-041-event-provenance-projection.md index 15f17cd83..a52eadcfe 100644 --- a/docs/adr/ADR-041-event-provenance-projection.md +++ b/docs/adr/ADR-041-event-provenance-projection.md @@ -658,6 +658,35 @@ event, `decode_signal_observation` picks `ReferentKind` from `event.substrate` ( back to `Entity` for pre-fix historical events still carrying the `SubstrateKind::Event` placeholder), and `observed_as_signal` admits both entity and note referents. +## Amendment A3: `SearchExecuted` admits a typed `result_kind` (2026-07-14, khive#806) + +§3's per-verb role mapping and the per-kind decoder examples describe `SearchExecuted` +`Candidate`/`Selected` projections as note rows only. Entity searches (`search(kind="entity")`) +also serve results and must be observable with correct typing: stamping entity UUIDs as +`ReferentKind::Note` would durably misclassify references in the append-only projection. + +This amendment makes the `SearchExecuted` referent typing polymorphic: + +**Payload key.** `SearchExecuted` payloads gain a `result_kind` string with exactly two +accepted values, `"entity"` and `"note"`, describing the substrate of every UUID in that +payload's `candidates` and `selected` lists. A single `SearchExecuted` event never mixes +substrates; the emitting handler sets `result_kind` from the search's resolved kind. + +**Projection rule.** The decoder stamps both `Candidate` and `Selected` rows with +`ReferentKind::Entity` when `result_kind` is `"entity"` and `ReferentKind::Note` when it is +`"note"`. Any other present value is a decode error for that event (consistent with the +closed-value posture elsewhere in this ADR); the error is surfaced, not silently coerced. + +**Legacy payloads.** A `SearchExecuted` payload with no `result_kind` key is the documented +historical note shape: the decoder projects note rows exactly as before this amendment. +Missing `result_kind` is never a decode error and requires no payload migration — the +event log is append-only and historical events remain valid as written. + +**Query surface.** Synthetic `observed_as_*` traversal and `EventFilter::observed`/`selected` +matching follow the projected `referent_kind`; entity-search observations resolve to entity +referents. `RecallExecuted` and `RerankExecuted` are unchanged by this amendment: their +`Candidate`/`Selected` projections remain note rows (memory recall serves memory notes). + --- ## References