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
//! `meta.json` — the step record's own metadata (ARCH §2.3).
//!
//! Split out of [`super`] (the step's on-disk *layout*: names, paths and
//! the derivations over them) because this is the record's *shape*: one
//! serde struct, its provenance rationale, and the grows-only round-trip
//! that keeps every older record readable.
use ;
/// On-disk shape of `meta.json`. The `commit` field is the branch
/// tip's sha at step-start — the read state for the model call
/// (§2.10). `started_at` / `ended_at` bookend the call's wall-clock
/// duration. Replay tooling reads `commit` to locate the tree state
/// the request was assembled against.
///
/// **The two config shas are the step's policy provenance** (bl-e4a0,
/// `docs/DESIGN_CONFIG_FOLLOW.md` §1). Under follow-the-tip a
/// conversation resolves the workspace's *current* config at every step
/// boundary, so "which config governed step N" stopped being derivable
/// from the branch's ancestry and became a fact about **when** the step
/// ran — knowable only if the step records it. `config_commit` is the
/// commit this step resolved all control from ([`crate::workspace::current_config`]);
/// `workflow_commit` is the commit its `workflow.yaml` came from — the
/// same sha for every unmarked agent, and the workflow mark's commit
/// when one stood (§6). Both are written whole rather than one being
/// conditional on the other, so a reader that finds them equal knows no
/// mark stood, rather than having to tell "no mark" from "not recorded".
///
/// **`provider` is the row the call was billed through** (bl-4c1c). The
/// model id is already on disk in the step's `request.json`, but a model
/// id does not price a step on its own: the same id costs nothing
/// marginal through a subscription row and list price through an
/// API-key row, so what a step's tokens cost is a fact about the pair
/// `(row, model)`. The row is knowable only here — it is the `provider:`
/// the role resolved from the config commit and the exact string the
/// harness hands `bz --provider` (§4.4) — so the step records it. Like
/// the two shas above it is *recorded, never computed* (§2.3): the fact
/// the adapter was invoked with, not a later re-resolution of a config
/// that may since have advanced. litany learns no rate from it, sums
/// nothing new, and the §6 budget derivation is untouched — the field is
/// provenance a reader prices, and pricing is not litany's question.
///
/// All three are `Option` for exactly one reason: a `meta.json` written
/// before the field existed carries none, and `None` says so. Every record
/// this harness writes carries all three. Diagnostic provenance, the same
/// class as `request.json` — read by audit and by a human, never a
/// control input the harness feeds back (§2.3 *Diagnostic-only
/// contract*); `commit` remains the one field replay is premised on.