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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
//! **What a conversation is called** (DESIGN §3.3) and when it started
//! (bl-16da) — the §11 display ladder, its floor spelling, and the one stamp
//! grammar both read.
//!
//! Split off [`super`] at §12's pre-split band on the seam §3.3 already draws:
//! the parent folds the descent forest into conversations, and this names what
//! the fold produced. Every seat falls through the same rungs here — the §11
//! row title, the center header, the §3.6 deletion confirmation — so no two of
//! them can come to disagree about a name.
use preview;
use crateAgent;
/// What a conversation is called (DESIGN §3.3) — **the one function**, a ladder:
/// the agent's name fact, else the first payload line (`preview`), else the id's
/// [`id_floor`] — the terminal generation only (bl-63a1). `name` is [`Agent::name_fact`]'s fold — the litany-stored `name`
/// blob (rung one), else the legacy `You are <x>.` goal-stamp parse covering
/// pre-0.0.4 roots until retention ages them out. Every seat reads it and falls
/// through together — the §11 row title, the §11 center header, the §3.6
/// deletion confirmation. A named conversation (or a named descent child — same
/// rung, no special case) stops on rung one; a foreign or hand-typed root lands
/// on the payload line or the id. The rungs are **mutually exclusive by
/// construction**: the interim stamp comes off the payload at its source
/// ([`crate::start::strip_identity_stamp`], applied in `git_tree::detect` before
/// the cap), so the identity line reaches the name fact and nothing else.
/// The ladder's floor spelling (bl-63a1). A litany child id embeds the full
/// ancestry chain — one `<stamp>-<hash>` pair per generation — and the descent
/// tree's indentation already states the lineage, so a row re-spelling the
/// whole chain is a second spelling of a derivable fact (the operator:
/// "unparseable"). When the ladder bottoms out at the id, it spells only the
/// **terminal generation**: the substring from the last stamp segment on. A
/// root id is one generation, so it is its own terminal segment, and an id the
/// stamp grammar does not recognize (foreign, hand-made) is spelled whole —
/// the general path, no special case. The full id's display seat stays the
/// hover, exactly as before.
///
/// `pub(crate)` rather than `pub` deliberately: it hands back a borrow of its
/// argument, which the boundary forbids (AGENTS rule 2), and cloning to own it
/// would buy nothing — every caller is in this crate. It is `pub(crate)` at
/// all because the floor has **more than one seat**: a deposit's `from` is an
/// agent id too, and the inbox rows spelled the whole ancestry chain until
/// bl-3aa1 routed them here.
pub
/// The §11 header's when-seat: what a conversation id says to a human, and the
/// raw id that hovers behind it.
/// Explain the id in the hover, so dropping it from the headline costs nothing:
/// it is the branch name and the on-disk key, and that is why it is still here.
const ID_HOVER: &str = "the conversation's id — its branch name and on-disk key";
/// When a conversation started, read out of its own id (bl-16da). Operator:
/// *"the timestamp at the top of the chat is unconsumable. make it still
/// ISO8601, but less built for the machine."* — the id is
/// `20260801T225418Z-2286254c`, litany's compact ISO 8601 basic form plus a
/// discriminator, and the headline seat wants the extended form
/// (`2026-08-01 22:54:18Z`) with the hash suffix gone: a hash is not a
/// timestamp.
///
/// **Derived at render, never stored** — the id IS the storage, exactly as the
/// §3.3 stamp is for the name — and it is the same ladder discipline as
/// [`display_name`]: an id the stamp grammar does not recognize (a foreign or
/// hand-made branch) is its own label rather than a special case, and the raw
/// id hovers either way.
/// `20260801T225418Z-<any>` → `2026-08-01 22:54:18Z`. `None` unless the id
/// opens with exactly litany's stamp: 8 digits, `T`, 6 digits, `Z`, then either
/// the end or the `-` before the discriminator. Assembly is
/// [`crate::ui_state::format_iso8601`], the same call the activity row's
/// epoch-derived timestamp goes through (bl-61db) — one spelling either way.
/// The `<date>`/`<time>` halves of a litany stamp segment, or `None` when the
/// segment is not one: exactly 8 digits, `T`, 6 digits, `Z` — the one grammar
/// both the header's when-label ([`iso_extended`]) and the ladder's
/// [`id_floor`] read, so the two seats can never disagree on what a stamp is.
/// **Is this run of text a litany stamp segment?** — [`stamp_halves`] asked for
/// the answer alone, which is all [`id_floor`] ever wanted of it.
///
/// `pub(crate)` because the §3.3 naming invariant is asserted on *values* rather
/// than on field names since bl-45c7: the acceptance scan reads the painted
/// window and asks this of every token in it. Sharing the predicate with the
/// floor is the point — what counts as an agent id has one definition in the
/// tree, so the scan cannot come to disagree with the seats it polices.
pub
/// The same ladder for a seat holding agents rather than a [`ConvRow`] (the §11
/// center header, the §3.6 deletion gate): `root_id`'s own rungs off the
/// snapshot. An id no agent here carries lands on the floor — the same
/// [`id_floor`] spelling every other seat gets (rung three).
/// The same ladder for the one agent in hand — the §11 descent-tree member row
/// (bl-df72: that seat painted the raw id, the operator's "incoherent
/// timestamp") and the in-flight strip: the agent's own rungs, no snapshot
/// search. A nameless member is titled by its payload line; the id stays the
/// floor — an id is a fact — but **only the ladder may spell it**: no seat
/// formats an agent id as a display name (the acceptance naming scan holds
/// this), and the floor's spelling is [`id_floor`]'s terminal generation
/// (bl-63a1) — the full id's seat is the hover.
/// One agent's first payload line, capped — the weak text the §11 row paints
/// beside its title, and the same text the §8.5 decision queue carries so a
/// reader of the queue sees what a looker at the strip sees. The [`preview`]
/// fold with the agent in hand, exactly as [`member_title`] is
/// [`display_name`] with the agent in hand.