1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
//! Supersession: the ONE `superseded_by` writer, shared by the dream cycle and
//! the share path (#5902).
//!
//! Why: an edited memory has different content, so it has a different content
//! hash, so it is a different memory. The old one must not simply orphan — a
//! reader that finds only the new fact has no way back to what it replaced, and
//! the estate hand-wrote 109 amendment edges precisely so corrections stay
//! traceable (ADR-0028 D6). The mechanism for that already existed:
//! `dream::cycle::record_provenance_and_collect_superseded` asserts
//! `Triple { subject: "drawer:{orig}", predicate: "superseded_by",
//! object: "drawer:{canonical}" }` and — this is the load-bearing half, issue
//! #1713 — only reports the original as evictable once that triple write
//! durably succeeded. Before #1713, consolidation pushed every original onto the
//! eviction list whether or not the provenance landed, so a canonical drawer
//! could exist with the original gone and no link back.
//!
//! Rather than write a second supersede concept for the share path, this module
//! IS that writer and the dream cycle now calls it. CLAUDE.md's
//! common-entry-point rule: the guarantee lands once, so a fix to it cannot land
//! in one copy and miss the other.
//!
//! What: [`assert_superseded_by`] (one edge, fail-loud) and
//! [`supersede_drawer`] (write the replacement, then link it, and report whether
//! the original may be retired).
//! Test: `supersede_mints_a_new_hash_and_links_the_original`,
//! `assert_superseded_by_fails_loud_on_an_unwritable_kg`,
//! `dream::tests::apply_consolidation_result_keeps_original_when_kg_write_fails`.
use ;
use Uuid;
use crateRoomType;
use crate;
use crate;
/// The predicate every supersession edge uses.
///
/// Why: two spellings of this string would split the amendment graph in half
/// while every write still reported success. It is read by KG queries in
/// `trusty-memory`, so it is a wire constant, not an implementation detail.
pub const SUPERSEDED_BY: &str = "superseded_by";
/// Assert that `original` was superseded by `replacement`.
///
/// Why: the caller's next step is almost always to retire, evict, or stop
/// surfacing `original`, and that step is only safe once this edge is durable.
/// So this returns `Result` and never swallows the failure — a caller that
/// treated a failed provenance write as success is exactly the #1713 defect.
/// What: asserts the `drawer:{original}` → `superseded_by` → `drawer:{replacement}`
/// triple with confidence 1.0 and `provenance` naming the pass that decided it.
/// Test: `supersede_mints_a_new_hash_and_links_the_original`,
/// `assert_superseded_by_fails_loud_on_an_unwritable_kg`.
pub async
/// What a supersession left behind.
///
/// Test: `supersede_mints_a_new_hash_and_links_the_original`.
/// Replace a memory's body with `new_content`, minting a new identity and
/// linking the old one to it (#5902).
///
/// Why: this is what "editing a memory" means once identity is content-derived.
/// The body changes, so the content hash changes, so what exists afterwards is a
/// NEW memory — there is no in-place edit that preserves identity, and pretending
/// otherwise is what would strand the original. Writing the replacement first and
/// linking second is deliberate: if the link fails, the estate holds two live
/// drawers and a missing edge, which a re-run can repair. Reversed, a failed
/// write after a successful link would leave an edge pointing at nothing.
///
/// What: writes `new_content` through `PalaceHandle::remember_with_options` — so
/// it passes the same filter, classification, and Tier C gates as any other write
/// — then asserts the supersession edge. `linked: false` means the caller must
/// leave the original entirely alone. This function never evicts, forgets, or
/// tombstones anything: supersession is an added edge, and demotion is the
/// caller's decision (ADR-0028 D6, "demoted, never deleted").
/// Test: `supersede_mints_a_new_hash_and_links_the_original`,
/// `assert_superseded_by_fails_loud_on_an_unwritable_kg`.
pub async