Skip to main content

Module invalidation

Module invalidation 

Source
Expand description

v0.7.0 L2-3 (issue #668) — Reflection invalidation propagation (notification, not cascade).

§Wire contract

When a supersedes edge lands with both endpoints carrying memory_kind = 'reflection', the substrate

  1. Walks every memory Mi whose row satisfies (Mi.id, invalidated_reflection_id, "reflects_on") in memory_links. That is the set of memories which used the now-invalidated reflection as a reasoning source.
  2. For each Mi, writes one notification memory into the namespace <Mi.namespace>/_invalidations. The notification’s metadata carries the four identifiers a curator/operator needs to triage: dependent_id, invalidated_id, invalidating_id, and an RFC3339 timestamp.
  3. Appends one reflection.invalidation_notified row to signed_events per notification so an auditor can replay the exact set of dependents that were flagged for review.

§Why notification, not cascade

Dependents are not auto-superseded. A reflection that pointed at the invalidated reflection may still be valid (the new winner could be a narrower restatement, a rephrasing, or a strictly stronger claim that the dependent should adopt unchanged). Auto-cascading the invalidation would

  • destroy curator/operator judgment on whether the dependent chain is genuinely affected, and
  • burn the trust budget the substrate has built: a single bad supersession would silently nuke an arbitrarily large reflection sub-graph.

The notification memory is the explicit hand-off — operators (via the new memory_dependents_of_invalidated MCP tool) or the curator pass surface the flagged set and the human/agent decides per-dependent.

§Idempotency

The walker is not internally idempotent in v0.7.0 — calling it twice on the same invalidation produces two notification memories per dependent (they upsert on (title, namespace) so the row count stays bounded by the namespace+title combinatorics, but each call still attempts the insert). The MCP-side caller in mcp::tools::link::handle_link only fires the walker once per successful supersedes write, so duplicates require a deliberate re-invocation. This keeps the helper simple; the v0.8.0 backlog tracks moving idempotency into the walker itself if the cross-peer federation case demands it.

Structs§

DependentRecord
Wire shape for the memory_dependents_of_invalidated MCP tool.

Functions§

list_dependents_of_invalidated
List the dependents of an invalidated reflection — every memory whose row writes (self → invalidated_id, "reflects_on") into memory_links. Returned as (dependent_id, dependent_namespace) so the caller can shape the notification’s target namespace without a second DB round-trip.
propagate_reflection_invalidation
Public entry point for the substrate-side walker.