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
//! The **hold** on the declared surface (ARCH §5.5 *prefix edits ride a
//! paid miss*; yog bl-b6f9, litany bl-b902).
//!
//! Provider prompt caching is keyed on the request's leading bytes in
//! cache order — tools, then system, then messages — so any byte that
//! moves ahead of the transcript tail re-bills the whole context behind
//! it. Between two steps the composed `tools` array can move for a
//! reason nobody chose to pay for: a host retired a tool it had injected
//! (yog's `clients unload`), a followed config commit revoked a grant.
//! Each is a **subtraction** — the model loses nothing it needs by not
//! hearing about it yet, since a call into a retired name is refused in
//! band exactly as today — and each, landed on its own, costs a full
//! rebuild.
//!
//! **The invariant: a prefix edit is applied only at a boundary that
//! already invalidates the prefix.** A subtraction from the declared
//! surface is *held*: the request keeps sending the array the previous
//! step sent, byte for byte, until some other part of the prefix moves
//! anyway — the model or the system slot changed (a config edit, a
//! retarget), or the first wire message did (a compaction landing, the
//! head recomposed) — and then the current composition goes out whole,
//! the subtraction riding a miss that was being paid regardless. An
//! **addition** is never held: a tool the model must be able to reach
//! now is a miss the act itself chose, and it carries every pending
//! subtraction with it, since the array is re-sent whole.
//!
//! **The queue's home is the previous step's own record.** The last
//! request sent is on disk at `steps/<agent>/<NNN>/request.json` —
//! written before the call, recorded rather than re-derived, the same
//! discipline `meta.json` keeps — so the held array is read back from
//! there and nowhere else: no second tree path, no boundary flag on the
//! executor, no list of boundary kinds to keep in step with the acts
//! that make them. Whether the miss is inevitable is answered by
//! comparing the two records, which is the only place the question can
//! be answered without re-deriving what the adapter was actually handed.
//! The first step of a branch, or one whose predecessor left no request,
//! sends its own composition — the general path with empty inputs.
//!
//! What this holds is the **tools array alone**. Head material rides the
//! first wire message and is a function of the tree; a subtraction there
//! (an agent's `rm`, §5.4) is priced from its position as before. The
//! hold compares serialized forms — `request.json` is the serialized
//! request — so a round trip through brazen's decoder is never on the
//! comparison path.
use crateError;
use crate;
use ;
use Value;
use Path;
/// The request `agent`'s step before `seq` sent, as recorded — `None`
/// for a first step or a predecessor with no request on disk.
pub
/// Apply the hold (module docs): `current` with its `tools` replaced by
/// `previous`'s when the prefix ahead of the tail is otherwise intact and
/// the current array is a strict subsequence of the previous one. A
/// record whose held array does not read back as tools is a fault of the
/// record, surfaced rather than sent around.
pub
/// The first wire message of `prev` is a prefix of the first of `now`:
/// the head blocks and whatever first entry grouped onto them (§2.3)
/// are where they were, and only the tail has moved.
/// `sub` is `of` with zero or more entries removed, order kept.