agentfootprint-lens 0.68.0 → 0.69.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +54 -1
- package/dist/chunk-5S5JD7BV.js +361 -0
- package/dist/chunk-5S5JD7BV.js.map +1 -0
- package/dist/{chunk-P63SOXBD.js → chunk-6RNHIZHE.js} +97 -4
- package/dist/chunk-6RNHIZHE.js.map +1 -0
- package/dist/{chunk-M5P65VVK.js → chunk-TIEKHJOS.js} +945 -564
- package/dist/chunk-TIEKHJOS.js.map +1 -0
- package/dist/context.cjs +1435 -843
- package/dist/context.cjs.map +1 -1
- package/dist/context.d.cts +46 -3
- package/dist/context.d.ts +46 -3
- package/dist/context.js +7 -3
- package/dist/{contextAt-Cmfc5OgF.d.cts → contextAt--ZlgSt8X.d.cts} +229 -1
- package/dist/{contextAt-Dzkug_Oy.d.ts → contextAt-4NIoC8U9.d.ts} +229 -1
- package/dist/core.cjs +319 -2
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +229 -3
- package/dist/core.d.ts +229 -3
- package/dist/core.js +13 -3
- package/dist/index.cjs +1787 -962
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +51 -5
- package/dist/index.d.ts +51 -5
- package/dist/index.js +399 -246
- package/dist/index.js.map +1 -1
- package/package.json +4 -3
- package/dist/chunk-3LXZ7D65.js +0 -142
- package/dist/chunk-3LXZ7D65.js.map +0 -1
- package/dist/chunk-M5P65VVK.js.map +0 -1
- package/dist/chunk-P63SOXBD.js.map +0 -1
package/README.md
CHANGED
|
@@ -951,7 +951,8 @@ if (recording.snapshot) {
|
|
|
951
951
|
}
|
|
952
952
|
```
|
|
953
953
|
|
|
954
|
-
(Under footprintjs 9.17 —
|
|
954
|
+
(Under footprintjs 9.17 — the floor when this narrowing landed, now below
|
|
955
|
+
the peer floor of `^9.26.0` — the same call needs
|
|
955
956
|
`recording.snapshot as unknown as TimeTravelSource`, and a bad row throws
|
|
956
957
|
inside the fold; a types-only difference the lens's `foldFactsAt` reports as
|
|
957
958
|
`foldError`.) **Movement never needs a snapshot at all**: `openLensCursor`
|
|
@@ -1083,6 +1084,58 @@ summary card, the transport and the commentary under a native **More detail**
|
|
|
1083
1084
|
Needs agentfootprint ≥ 9.116.0 (the release that ships `AnswerAccount` and the
|
|
1084
1085
|
op) — the lens's peer floor since 0.68.0.
|
|
1085
1086
|
|
|
1087
|
+
## Time — what the run took "now" to be, and which window each call read
|
|
1088
|
+
|
|
1089
|
+
**Every time decision an armed agent makes, as the record holds it.** With
|
|
1090
|
+
agentfootprint's time layer armed (`.time()`, 9.129.0), the run files rows on
|
|
1091
|
+
its honesty ledger: the clock it froze for the turn, what it read from the
|
|
1092
|
+
person's words, which window each call carries and how, whether a call reads
|
|
1093
|
+
MORE than was asked, and how far the wall clock had moved by the time the
|
|
1094
|
+
tool ran. `<TimeBand>` draws them; `<ContextView>` mounts it under the
|
|
1095
|
+
Findings band, so it moves with the one cursor.
|
|
1096
|
+
|
|
1097
|
+
### Why
|
|
1098
|
+
|
|
1099
|
+
A time bug is quiet. "Yesterday" sent to a tool that only takes a look-back
|
|
1100
|
+
reads from yesterday's midnight to NOW — a day and a half, not a day — and
|
|
1101
|
+
the answer looks fine. After a 30-minute pause, a "last hour" look-back reads
|
|
1102
|
+
a different hour than the person asked about. The library records each of
|
|
1103
|
+
these; this band is where a person sees them: a widened fill says **wider
|
|
1104
|
+
than asked** with the extra ranges, a drift says `redrawn` or `shifted` and by
|
|
1105
|
+
how much, a result whose held range is unknown says **clock unknown**.
|
|
1106
|
+
|
|
1107
|
+
### Mount it
|
|
1108
|
+
|
|
1109
|
+
```tsx
|
|
1110
|
+
import { ContextView, TimeBand } from 'agentfootprint-lens/context';
|
|
1111
|
+
|
|
1112
|
+
<ContextView runner={recording} /> // the band appears once the ledger holds a time row
|
|
1113
|
+
|
|
1114
|
+
// or on its own, over rows you already hold:
|
|
1115
|
+
<TimeBand rows={state.findingsLedger} coverage={state.coverageDeclared} />
|
|
1116
|
+
```
|
|
1117
|
+
|
|
1118
|
+
A paused ask with a time field (`requestInput` with `format`) shows its time
|
|
1119
|
+
half inside `<AwaitingPane>` — the choices with the library's labels and, on
|
|
1120
|
+
a re-ask, the refused value with the library's reason. A `dataset/rows`
|
|
1121
|
+
artifact that declares a time axis shows it above the table
|
|
1122
|
+
(`<TimeAxisLine meta rows>`), judged by the library: column, unit, zone,
|
|
1123
|
+
grain, and how many values have no known clock.
|
|
1124
|
+
|
|
1125
|
+
### The laws it keeps
|
|
1126
|
+
|
|
1127
|
+
- **Omit, never deny.** No time row at the stop, no band — an unarmed run has
|
|
1128
|
+
no band, never an empty one. A row prints no field it does not carry.
|
|
1129
|
+
- **Never infer.** Nothing here compares two instants. `wider than asked`
|
|
1130
|
+
renders only on a row that carries `differs`; a drift only on a call row
|
|
1131
|
+
that carries `drift`; `clock unknown` only where the record says `unknown`.
|
|
1132
|
+
- **No sentence of its own.** Every printed string is a value off the record
|
|
1133
|
+
or a `TIME_LABELS` entry; the one sentence it shows — an ask's refusal
|
|
1134
|
+
reason — is the library's, printed as data.
|
|
1135
|
+
|
|
1136
|
+
Headless: `foldTimeRows(ledger, coverage?)`, `timeAskOf(pause)`,
|
|
1137
|
+
`datasetTimeAxisOf(meta, rows?)`.
|
|
1138
|
+
|
|
1086
1139
|
## The Served tab
|
|
1087
1140
|
|
|
1088
1141
|
**At every LLM call, exactly what the model was served — provable from the log.**
|
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
import {
|
|
2
|
+
servedRowAt,
|
|
3
|
+
servedRowForEpoch,
|
|
4
|
+
sincePrevious,
|
|
5
|
+
verify
|
|
6
|
+
} from "./chunk-XEAZRBOH.js";
|
|
7
|
+
|
|
8
|
+
// src/core/context/contextAt.ts
|
|
9
|
+
import * as trace from "footprintjs/trace";
|
|
10
|
+
import { stateAt } from "footprintjs/trace";
|
|
11
|
+
function firstSegment(path) {
|
|
12
|
+
const helper = trace.pathSegments;
|
|
13
|
+
if (typeof helper === "function") return helper(path)[0];
|
|
14
|
+
const unit = path.indexOf("");
|
|
15
|
+
if (unit >= 0) return path.slice(0, unit);
|
|
16
|
+
const dot = path.indexOf(".");
|
|
17
|
+
return dot >= 0 ? path.slice(0, dot) : path;
|
|
18
|
+
}
|
|
19
|
+
function logOf(snapshot) {
|
|
20
|
+
const s = snapshot;
|
|
21
|
+
return Array.isArray(s?.commitLog) ? s.commitLog : [];
|
|
22
|
+
}
|
|
23
|
+
function writersUpTo(log, commitIdx) {
|
|
24
|
+
const out = /* @__PURE__ */ new Map();
|
|
25
|
+
const last = Math.min(commitIdx, log.length - 1);
|
|
26
|
+
for (let i = 0; i <= last; i++) {
|
|
27
|
+
const bundle = log[i];
|
|
28
|
+
if (bundle === void 0 || typeof bundle.runtimeStageId !== "string" || !Array.isArray(bundle.trace))
|
|
29
|
+
continue;
|
|
30
|
+
for (const row of bundle.trace) {
|
|
31
|
+
const key = firstSegment(row.path);
|
|
32
|
+
if (key === void 0) continue;
|
|
33
|
+
const prior = out.get(key);
|
|
34
|
+
out.set(key, {
|
|
35
|
+
wroteBy: bundle.runtimeStageId,
|
|
36
|
+
wroteAt: i,
|
|
37
|
+
enteredAt: prior?.enteredAt ?? i,
|
|
38
|
+
verb: row.verb
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return out;
|
|
43
|
+
}
|
|
44
|
+
function foldAt(snapshot, commitIdx) {
|
|
45
|
+
const source = typeof snapshot === "object" && snapshot !== null ? snapshot : void 0;
|
|
46
|
+
try {
|
|
47
|
+
return stateAt(source, commitIdx);
|
|
48
|
+
} catch (e) {
|
|
49
|
+
return { error: e instanceof Error ? e.message : String(e) };
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
var same = (a, b) => JSON.stringify(a) === JSON.stringify(b);
|
|
53
|
+
function servedFor(snapshot, cursor) {
|
|
54
|
+
try {
|
|
55
|
+
const row = servedRowAt(snapshot, cursor);
|
|
56
|
+
if (row === void 0) return {};
|
|
57
|
+
const checks = verify(row.view, row.receipt, row.receipt?.basis.runId ?? "", row.receiptCause);
|
|
58
|
+
const previous = row.previousEpoch !== void 0 ? servedRowForEpoch(snapshot, row.previousEpoch) : void 0;
|
|
59
|
+
const since = previous !== void 0 ? sincePrevious(row, previous) : void 0;
|
|
60
|
+
return {
|
|
61
|
+
served: Object.freeze({
|
|
62
|
+
row,
|
|
63
|
+
checks,
|
|
64
|
+
...since !== void 0 ? { since } : {}
|
|
65
|
+
})
|
|
66
|
+
};
|
|
67
|
+
} catch (e) {
|
|
68
|
+
return { servedError: e instanceof Error ? e.message : String(e) };
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
function whyFor(events, stages) {
|
|
72
|
+
if (events === void 0 || stages.size === 0) return Object.freeze([]);
|
|
73
|
+
const out = [];
|
|
74
|
+
for (const entry of events) {
|
|
75
|
+
const id = entry.runtimeStageId;
|
|
76
|
+
if (id === void 0 || !stages.has(id)) continue;
|
|
77
|
+
out.push({ seq: entry.seq, name: entry.event.type, runtimeStageId: id });
|
|
78
|
+
}
|
|
79
|
+
return Object.freeze(out);
|
|
80
|
+
}
|
|
81
|
+
function contextAt(recording, cursor, options = {}) {
|
|
82
|
+
const log = logOf(recording);
|
|
83
|
+
const folded = foldAt(recording, cursor.commitIdx);
|
|
84
|
+
if ("error" in folded) {
|
|
85
|
+
return Object.freeze({
|
|
86
|
+
cursor,
|
|
87
|
+
keys: Object.freeze([]),
|
|
88
|
+
left: Object.freeze([]),
|
|
89
|
+
rows: Object.freeze([]),
|
|
90
|
+
redacted: false,
|
|
91
|
+
foldError: folded.error,
|
|
92
|
+
why: Object.freeze([])
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
const writers = writersUpTo(log, cursor.commitIdx);
|
|
96
|
+
const previous = options.previous !== void 0 ? foldAt(recording, options.previous.commitIdx) : void 0;
|
|
97
|
+
const previousState = previous !== void 0 && !("error" in previous) ? previous.state : void 0;
|
|
98
|
+
const keys = [];
|
|
99
|
+
for (const [path, value] of Object.entries(folded.state)) {
|
|
100
|
+
const w = writers.get(path);
|
|
101
|
+
const since = previousState === void 0 ? void 0 : !(path in previousState) ? "entered" : same(previousState[path], value) ? "unchanged" : "changed";
|
|
102
|
+
keys.push(
|
|
103
|
+
Object.freeze({
|
|
104
|
+
path,
|
|
105
|
+
value,
|
|
106
|
+
...w !== void 0 ? {
|
|
107
|
+
wroteBy: w.wroteBy,
|
|
108
|
+
wroteAt: w.wroteAt,
|
|
109
|
+
enteredAt: w.enteredAt,
|
|
110
|
+
verb: w.verb
|
|
111
|
+
} : {},
|
|
112
|
+
...since !== void 0 ? { since } : {}
|
|
113
|
+
})
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
const left = previousState === void 0 ? [] : Object.keys(previousState).filter((k) => !(k in folded.state));
|
|
117
|
+
const bundle = log[cursor.commitIdx];
|
|
118
|
+
const rows = Array.isArray(bundle?.trace) ? bundle.trace.map((r) => Object.freeze({ path: r.path, verb: r.verb })) : [];
|
|
119
|
+
const stages = /* @__PURE__ */ new Set();
|
|
120
|
+
if (bundle !== void 0 && typeof bundle.runtimeStageId === "string") stages.add(bundle.runtimeStageId);
|
|
121
|
+
for (const k of keys)
|
|
122
|
+
if (k.since !== void 0 && k.since !== "unchanged" && k.wroteBy !== void 0) stages.add(k.wroteBy);
|
|
123
|
+
const skipped = folded.skipped !== void 0 && folded.skipped.length > 0 ? folded.skipped.map((g) => g.index) : void 0;
|
|
124
|
+
const { served, servedError } = servedFor(recording, cursor);
|
|
125
|
+
return Object.freeze({
|
|
126
|
+
cursor,
|
|
127
|
+
keys: Object.freeze(keys),
|
|
128
|
+
left: Object.freeze(left),
|
|
129
|
+
rows: Object.freeze(rows),
|
|
130
|
+
basis: folded.basis,
|
|
131
|
+
redacted: folded.redacted,
|
|
132
|
+
...skipped !== void 0 ? { skipped: Object.freeze(skipped) } : {},
|
|
133
|
+
...served !== void 0 ? { served } : {},
|
|
134
|
+
...servedError !== void 0 ? { servedError } : {},
|
|
135
|
+
why: whyFor(options.events, stages)
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// src/core/time/labels.ts
|
|
140
|
+
var LABELS = Object.freeze({
|
|
141
|
+
band: "time",
|
|
142
|
+
rows: "rows",
|
|
143
|
+
turn: "turn",
|
|
144
|
+
clock: "clock",
|
|
145
|
+
now: "now",
|
|
146
|
+
zone: "zone",
|
|
147
|
+
source: "source",
|
|
148
|
+
window: "window",
|
|
149
|
+
clockOnResume: "clock on resume",
|
|
150
|
+
passed: "passed",
|
|
151
|
+
kept: "kept",
|
|
152
|
+
readings: "readings",
|
|
153
|
+
reader: "reader",
|
|
154
|
+
tzdata: "tz database",
|
|
155
|
+
noMentions: "no mentions",
|
|
156
|
+
quote: "quote",
|
|
157
|
+
candidates: "candidates",
|
|
158
|
+
choice: "choice",
|
|
159
|
+
remaining: "remaining",
|
|
160
|
+
open: "open",
|
|
161
|
+
policy: "policy",
|
|
162
|
+
refused: "refused",
|
|
163
|
+
problem: "problem",
|
|
164
|
+
said: "said",
|
|
165
|
+
implied: "implied",
|
|
166
|
+
notes: "notes",
|
|
167
|
+
grain: "grain",
|
|
168
|
+
calls: "calls",
|
|
169
|
+
how: "how",
|
|
170
|
+
form: "form",
|
|
171
|
+
asked: "asked",
|
|
172
|
+
person: "person",
|
|
173
|
+
mention: "mention",
|
|
174
|
+
by: "by",
|
|
175
|
+
rounded: "rounded",
|
|
176
|
+
why: "why",
|
|
177
|
+
sent: "sent",
|
|
178
|
+
widened: "wider than asked",
|
|
179
|
+
extra: "extra",
|
|
180
|
+
trimmedByTool: "trimmed by tool",
|
|
181
|
+
partlyBeyondRetention: "partly beyond retention",
|
|
182
|
+
argument: "argument",
|
|
183
|
+
dispatchedAt: "dispatched at",
|
|
184
|
+
drift: "drift at dispatch",
|
|
185
|
+
period: "period",
|
|
186
|
+
verdict: "verdict",
|
|
187
|
+
queried: "queried",
|
|
188
|
+
held: "held",
|
|
189
|
+
readAt: "read at",
|
|
190
|
+
clockUnknown: "clock unknown",
|
|
191
|
+
ask: "time ask",
|
|
192
|
+
request: "request",
|
|
193
|
+
repeat: "asked again",
|
|
194
|
+
answer: "answer",
|
|
195
|
+
reason: "reason",
|
|
196
|
+
field: "field",
|
|
197
|
+
format: "format",
|
|
198
|
+
choices: "choices",
|
|
199
|
+
strict: "strict",
|
|
200
|
+
missing: "missing",
|
|
201
|
+
axis: "time axis",
|
|
202
|
+
column: "column",
|
|
203
|
+
unit: "unit",
|
|
204
|
+
interval: "interval",
|
|
205
|
+
aggregate: "aggregate",
|
|
206
|
+
summary: "summary",
|
|
207
|
+
malformed: "malformed",
|
|
208
|
+
unjudged: "not checked",
|
|
209
|
+
values: "values",
|
|
210
|
+
placed: "placed",
|
|
211
|
+
dstGap: "dst gap",
|
|
212
|
+
unreadable: "unreadable"
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
// src/core/time/timeRows.ts
|
|
216
|
+
var isRec = (v) => v !== null && typeof v === "object" && !Array.isArray(v);
|
|
217
|
+
var isStr = (v) => typeof v === "string" && v.length > 0;
|
|
218
|
+
var isCount = (v) => typeof v === "number" && Number.isInteger(v) && v >= 0;
|
|
219
|
+
function isRangeShape(v) {
|
|
220
|
+
return isRec(v) && isStr(v.from) && isStr(v.to);
|
|
221
|
+
}
|
|
222
|
+
var hasTurn = (r) => isCount(r.turn) && isCount(r.iteration);
|
|
223
|
+
function clockOf(r) {
|
|
224
|
+
return isStr(r.now) && isStr(r.zone) && isStr(r.nowSource) && isStr(r.zoneSource) ? r : void 0;
|
|
225
|
+
}
|
|
226
|
+
function resumeOf(r) {
|
|
227
|
+
return isRec(r.passed) && isRec(r.kept) ? r : void 0;
|
|
228
|
+
}
|
|
229
|
+
function readingOf(r) {
|
|
230
|
+
const reader = r.reader;
|
|
231
|
+
if (!isRec(reader) || !isStr(reader.id) || !isStr(reader.version) || !isCount(r.mentions)) {
|
|
232
|
+
return void 0;
|
|
233
|
+
}
|
|
234
|
+
if (r.candidates !== void 0 && !Array.isArray(r.candidates)) return void 0;
|
|
235
|
+
return r;
|
|
236
|
+
}
|
|
237
|
+
var callIdentity = (r) => isStr(r.toolCallId) && typeof r.toolName === "string";
|
|
238
|
+
function windowOf(r) {
|
|
239
|
+
return callIdentity(r) && isStr(r.how) ? r : void 0;
|
|
240
|
+
}
|
|
241
|
+
function dispatchOf(r) {
|
|
242
|
+
return callIdentity(r) && isStr(r.dispatchedAt) ? r : void 0;
|
|
243
|
+
}
|
|
244
|
+
function periodOf(r) {
|
|
245
|
+
return callIdentity(r) && isStr(r.verdict) ? r : void 0;
|
|
246
|
+
}
|
|
247
|
+
function declaredPeriods(coverage) {
|
|
248
|
+
const out = /* @__PURE__ */ new Map();
|
|
249
|
+
for (const row of coverage ?? []) {
|
|
250
|
+
if (!isRec(row) || !isStr(row.toolCallId) || !isRec(row.period)) continue;
|
|
251
|
+
const p = row.period;
|
|
252
|
+
if (!isRangeShape(p.queried) || !(p.held === "unknown" || isRangeShape(p.held))) continue;
|
|
253
|
+
out.set(row.toolCallId, p);
|
|
254
|
+
}
|
|
255
|
+
return out;
|
|
256
|
+
}
|
|
257
|
+
function foldTimeRows(ledger, coverage) {
|
|
258
|
+
if (!Array.isArray(ledger)) return void 0;
|
|
259
|
+
const turns = /* @__PURE__ */ new Map();
|
|
260
|
+
const declared = declaredPeriods(coverage);
|
|
261
|
+
let rows = 0;
|
|
262
|
+
const turnOf = (n) => {
|
|
263
|
+
let t = turns.get(n);
|
|
264
|
+
if (t === void 0) {
|
|
265
|
+
t = { turn: n, resumes: [], readings: [], calls: /* @__PURE__ */ new Map() };
|
|
266
|
+
turns.set(n, t);
|
|
267
|
+
}
|
|
268
|
+
return t;
|
|
269
|
+
};
|
|
270
|
+
const callOf = (t, r) => {
|
|
271
|
+
const id = r.toolCallId;
|
|
272
|
+
let c = t.calls.get(id);
|
|
273
|
+
if (c === void 0) {
|
|
274
|
+
c = { toolCallId: id, toolName: r.toolName, iteration: r.iteration };
|
|
275
|
+
const d = declared.get(id);
|
|
276
|
+
if (d !== void 0) c.declared = d;
|
|
277
|
+
t.calls.set(id, c);
|
|
278
|
+
}
|
|
279
|
+
return c;
|
|
280
|
+
};
|
|
281
|
+
for (const row of ledger) {
|
|
282
|
+
if (!isRec(row) || !hasTurn(row)) continue;
|
|
283
|
+
const t = () => turnOf(row.turn);
|
|
284
|
+
switch (row.kind) {
|
|
285
|
+
case "clock": {
|
|
286
|
+
const clock = clockOf(row);
|
|
287
|
+
if (clock === void 0) continue;
|
|
288
|
+
t().clock = clock;
|
|
289
|
+
break;
|
|
290
|
+
}
|
|
291
|
+
case "clock-on-resume": {
|
|
292
|
+
const resume = resumeOf(row);
|
|
293
|
+
if (resume === void 0) continue;
|
|
294
|
+
t().resumes.push(resume);
|
|
295
|
+
break;
|
|
296
|
+
}
|
|
297
|
+
case "time-reading": {
|
|
298
|
+
const reading = readingOf(row);
|
|
299
|
+
if (reading === void 0) continue;
|
|
300
|
+
t().readings.push(reading);
|
|
301
|
+
break;
|
|
302
|
+
}
|
|
303
|
+
case "call-window": {
|
|
304
|
+
const w = windowOf(row);
|
|
305
|
+
if (w === void 0) continue;
|
|
306
|
+
callOf(t(), row).window = w;
|
|
307
|
+
break;
|
|
308
|
+
}
|
|
309
|
+
case "call": {
|
|
310
|
+
const d = dispatchOf(row);
|
|
311
|
+
if (d === void 0) continue;
|
|
312
|
+
callOf(t(), row).dispatch = d;
|
|
313
|
+
break;
|
|
314
|
+
}
|
|
315
|
+
case "period": {
|
|
316
|
+
const p = periodOf(row);
|
|
317
|
+
if (p === void 0) continue;
|
|
318
|
+
callOf(t(), row).period = p;
|
|
319
|
+
break;
|
|
320
|
+
}
|
|
321
|
+
default:
|
|
322
|
+
continue;
|
|
323
|
+
}
|
|
324
|
+
rows += 1;
|
|
325
|
+
}
|
|
326
|
+
if (rows === 0) return void 0;
|
|
327
|
+
return {
|
|
328
|
+
rows,
|
|
329
|
+
turns: [...turns.values()].map((t) => ({
|
|
330
|
+
turn: t.turn,
|
|
331
|
+
...t.clock !== void 0 ? { clock: t.clock } : {},
|
|
332
|
+
resumes: t.resumes,
|
|
333
|
+
readings: t.readings,
|
|
334
|
+
calls: [...t.calls.values()]
|
|
335
|
+
}))
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
function spellMs(ms) {
|
|
339
|
+
const sign = ms < 0 ? "-" : "+";
|
|
340
|
+
let rest = Math.abs(ms);
|
|
341
|
+
const parts = [];
|
|
342
|
+
for (const [unit, size] of [
|
|
343
|
+
["h", 36e5],
|
|
344
|
+
["m", 6e4],
|
|
345
|
+
["s", 1e3]
|
|
346
|
+
]) {
|
|
347
|
+
const n = Math.floor(rest / size);
|
|
348
|
+
if (n > 0) parts.push(`${n}${unit}`);
|
|
349
|
+
rest -= n * size;
|
|
350
|
+
}
|
|
351
|
+
if (rest > 0 || parts.length === 0) parts.push(`${rest}ms`);
|
|
352
|
+
return sign + parts.join(" ");
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
export {
|
|
356
|
+
contextAt,
|
|
357
|
+
LABELS,
|
|
358
|
+
foldTimeRows,
|
|
359
|
+
spellMs
|
|
360
|
+
};
|
|
361
|
+
//# sourceMappingURL=chunk-5S5JD7BV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/context/contextAt.ts","../src/core/time/labels.ts","../src/core/time/timeRows.ts"],"sourcesContent":["/**\n * core/context/contextAt — the context object at a stop, with who wrote each\n * key, what moved since the previous stop, and what was served beside it.\n *\n * THE JOIN, nothing more. Three records already exist and this file writes\n * none of its own:\n *\n * 1. the COMMIT LOG — `stateAt(snapshot, commitIdx)` is the object at the\n * stop; the trace rows of the bundles up to it name, per top-level key,\n * the stage that last wrote it (`runtimeStageId`) and the first that\n * did; the bundle's own rows are the DELTA of the stop;\n * 2. the RECEIPT at the stop's epoch — `servedRowAt` (the Served tab's own\n * core) says what crossed into the model call and what the catalogue\n * withheld; it is handed through untouched, never re-derived;\n * 3. the EVENT STREAM — entries stamped with the stages that wrote this\n * stop's delta, or with the stop's own stage, are the \"why\" beside the\n * keys; names only, no sentence.\n *\n * Join keys: `runtimeStageId` (commit log ⟂ events), `epoch` (commit log ⟂\n * receipt, through `servedRowAt`). A key the fold holds with no writer row —\n * the run's initial state, or a row the log lost — is `wroteBy: undefined`:\n * UNATTRIBUTED, never guessed (the reads law: omit, never deny). Owners are\n * stage ids, because that is what the record says; a word like \"host\" or\n * \"model\" is a reader's mapping, not this file's.\n *\n * Pure; frozen returns; no React. Consumers with their own UI read this.\n */\nimport * as trace from 'footprintjs/trace';\nimport { stateAt } from 'footprintjs/trace';\nimport type { FoldSource, FoldedState } from 'footprintjs/trace';\n\nimport type { EventLogEntry } from '../types.js';\nimport { servedRowAt, servedRowForEpoch } from '../served/servedRowAt.js';\nimport { sincePrevious, type SincePrevious } from '../served/sincePrevious.js';\nimport { verify, type ServedVerification } from '../served/verify.js';\nimport type { ServedCursor, ServedRow } from '../served/types.js';\n\n/** The slice of a footprintjs commit bundle this file reads — narrowed per row, never trusted whole. */\ninterface TraceRow {\n readonly path: string;\n readonly verb: string;\n}\ninterface CommitBundle {\n readonly idx?: number;\n readonly runtimeStageId: string;\n readonly trace?: readonly TraceRow[];\n}\n\n/** One top-level key of the context object at the stop. */\nexport interface ContextKey {\n readonly path: string;\n readonly value: unknown;\n /** The stage that LAST wrote the key, from its trace row; absent = unattributed. */\n readonly wroteBy?: string;\n /** The commit index of that last write. */\n readonly wroteAt?: number;\n /** The first commit that wrote the key — when it ENTERED the context. */\n readonly enteredAt?: number;\n /** The verb of the last write, from the trace row. */\n readonly verb?: string;\n /** How the key moved since the previous stop (absent when no previous stop was given). */\n readonly since?: 'entered' | 'changed' | 'unchanged';\n}\n\n/** What is served beside the object at this stop — the Served tab's own row, handed through. */\nexport interface ContextServed {\n readonly row: ServedRow;\n readonly checks: ServedVerification;\n readonly since?: SincePrevious;\n}\n\nexport interface ContextAt {\n readonly cursor: ServedCursor;\n /** Every top-level key of the fold at the stop, in the fold's key order. */\n readonly keys: readonly ContextKey[];\n /** Keys the previous stop held that this one does not (only with a previous stop). */\n readonly left: readonly string[];\n /** The trace rows the stop's own bundle wrote — its delta as the log spells it. */\n readonly rows: readonly { readonly path: string; readonly verb: string }[];\n /** The fold's honesty facts, as `stateAt` reports them. */\n readonly basis?: FoldedState['basis'];\n readonly redacted: boolean;\n readonly skipped?: readonly number[];\n readonly foldError?: string;\n /** The served side at this stop's epoch, when the stop is at or after a model call. */\n readonly served?: ContextServed;\n /** The Served core refused this snapshot — its message, verbatim; `served` is then absent. */\n readonly servedError?: string;\n /** Event names raised by the stages that wrote this stop's delta, or by its own stage. */\n readonly why: readonly {\n readonly seq: number;\n readonly name: string;\n readonly runtimeStageId: string;\n }[];\n}\n\nexport interface ContextAtOptions {\n /** The previous stop on the reader's axis — enables `since` and `left`. */\n readonly previous?: ServedCursor;\n /** The recording's event stream, when the reader has one (a replay's `getEntries()`). */\n readonly events?: readonly EventLogEntry[];\n}\n\n/**\n * The top-level key a trace-row path names. footprintjs 9.22.0 exports\n * `pathSegments` (its paths are joined with U+001F since then); the lens's\n * peer floor is 9.17.0, whose paths are dotted and which has no such export —\n * so the helper is read at call time, the way `tagStops` is, and a floor\n * substrate gets the split it used (0.53.4: a consumer on 9.21.1 could not\n * even bundle the lens while this was a static import).\n */\nexport function firstSegment(path: string): string | undefined {\n const helper = (trace as { pathSegments?: (p: string) => string[] }).pathSegments;\n if (typeof helper === 'function') return helper(path)[0];\n const unit = path.indexOf('\\u001F');\n if (unit >= 0) return path.slice(0, unit);\n const dot = path.indexOf('.');\n return dot >= 0 ? path.slice(0, dot) : path;\n}\n\ninterface WriterFacts {\n readonly wroteBy: string;\n readonly wroteAt: number;\n readonly enteredAt: number;\n readonly verb: string;\n}\n\nfunction logOf(snapshot: unknown): readonly CommitBundle[] {\n const s = snapshot as { commitLog?: unknown } | null | undefined;\n return Array.isArray(s?.commitLog) ? (s.commitLog as CommitBundle[]) : [];\n}\n\n/** Per top-level key, the first and last trace rows up to `commitIdx` (inclusive). */\nfunction writersUpTo(log: readonly CommitBundle[], commitIdx: number): ReadonlyMap<string, WriterFacts> {\n const out = new Map<string, WriterFacts>();\n const last = Math.min(commitIdx, log.length - 1);\n for (let i = 0; i <= last; i++) {\n const bundle = log[i];\n if (bundle === undefined || typeof bundle.runtimeStageId !== 'string' || !Array.isArray(bundle.trace))\n continue;\n for (const row of bundle.trace) {\n const key = firstSegment(row.path);\n if (key === undefined) continue;\n const prior = out.get(key);\n out.set(key, {\n wroteBy: bundle.runtimeStageId,\n wroteAt: i,\n enteredAt: prior?.enteredAt ?? i,\n verb: row.verb,\n });\n }\n }\n return out;\n}\n\nfunction foldAt(snapshot: unknown, commitIdx: number): FoldedState | { readonly error: string } {\n const source: FoldSource | undefined =\n typeof snapshot === 'object' && snapshot !== null ? (snapshot as FoldSource) : undefined;\n try {\n return stateAt(source, commitIdx);\n } catch (e) {\n return { error: e instanceof Error ? e.message : String(e) };\n }\n}\n\nconst same = (a: unknown, b: unknown): boolean => JSON.stringify(a) === JSON.stringify(b);\n\nfunction servedFor(\n snapshot: unknown,\n cursor: ServedCursor,\n): { readonly served?: ContextServed; readonly servedError?: string } {\n try {\n const row = servedRowAt(snapshot, cursor);\n if (row === undefined) return {};\n const checks = verify(row.view, row.receipt, row.receipt?.basis.runId ?? '', row.receiptCause);\n const previous =\n row.previousEpoch !== undefined ? servedRowForEpoch(snapshot, row.previousEpoch) : undefined;\n const since = previous !== undefined ? sincePrevious(row, previous) : undefined;\n return {\n served: Object.freeze({\n row,\n checks,\n ...(since !== undefined ? { since } : {}),\n }),\n };\n } catch (e) {\n return { servedError: e instanceof Error ? e.message : String(e) };\n }\n}\n\nfunction whyFor(events: readonly EventLogEntry[] | undefined, stages: ReadonlySet<string>): ContextAt['why'] {\n if (events === undefined || stages.size === 0) return Object.freeze([]);\n const out: { seq: number; name: string; runtimeStageId: string }[] = [];\n for (const entry of events) {\n const id = entry.runtimeStageId;\n if (id === undefined || !stages.has(id)) continue;\n out.push({ seq: entry.seq, name: entry.event.type, runtimeStageId: id });\n }\n return Object.freeze(out);\n}\n\n/**\n * The context at `cursor`: the fold's keys with their writers, the delta\n * since `options.previous`, the served side at this epoch, and the events\n * beside the delta. Returns a frozen object; a fold that cannot be replayed\n * reports `foldError` with no keys rather than an empty object pretending to\n * be one.\n */\nexport function contextAt(\n recording: unknown,\n cursor: ServedCursor,\n options: ContextAtOptions = {},\n): ContextAt {\n const log = logOf(recording);\n const folded = foldAt(recording, cursor.commitIdx);\n if ('error' in folded) {\n return Object.freeze({\n cursor,\n keys: Object.freeze([]),\n left: Object.freeze([]),\n rows: Object.freeze([]),\n redacted: false,\n foldError: folded.error,\n why: Object.freeze([]),\n });\n }\n const writers = writersUpTo(log, cursor.commitIdx);\n const previous = options.previous !== undefined ? foldAt(recording, options.previous.commitIdx) : undefined;\n const previousState = previous !== undefined && !('error' in previous) ? previous.state : undefined;\n\n const keys: ContextKey[] = [];\n for (const [path, value] of Object.entries(folded.state)) {\n const w = writers.get(path);\n const since: ContextKey['since'] | undefined =\n previousState === undefined\n ? undefined\n : !(path in previousState)\n ? 'entered'\n : same(previousState[path], value)\n ? 'unchanged'\n : 'changed';\n keys.push(\n Object.freeze({\n path,\n value,\n ...(w !== undefined\n ? {\n wroteBy: w.wroteBy,\n wroteAt: w.wroteAt,\n enteredAt: w.enteredAt,\n verb: w.verb,\n }\n : {}),\n ...(since !== undefined ? { since } : {}),\n }),\n );\n }\n const left =\n previousState === undefined ? [] : Object.keys(previousState).filter((k) => !(k in folded.state));\n\n const bundle = log[cursor.commitIdx];\n const rows = Array.isArray(bundle?.trace)\n ? bundle.trace.map((r: TraceRow) => Object.freeze({ path: r.path, verb: r.verb }))\n : [];\n\n const stages = new Set<string>();\n if (bundle !== undefined && typeof bundle.runtimeStageId === 'string') stages.add(bundle.runtimeStageId);\n for (const k of keys)\n if (k.since !== undefined && k.since !== 'unchanged' && k.wroteBy !== undefined) stages.add(k.wroteBy);\n\n const skipped =\n folded.skipped !== undefined && folded.skipped.length > 0\n ? folded.skipped.map((g) => g.index)\n : undefined;\n const { served, servedError } = servedFor(recording, cursor);\n\n return Object.freeze({\n cursor,\n keys: Object.freeze(keys),\n left: Object.freeze(left),\n rows: Object.freeze(rows),\n basis: folded.basis,\n redacted: folded.redacted,\n ...(skipped !== undefined ? { skipped: Object.freeze(skipped) } : {}),\n ...(served !== undefined ? { served } : {}),\n ...(servedError !== undefined ? { servedError } : {}),\n why: whyFor(options.events, stages),\n });\n}\n","/**\n * The time views' own words — names for rows and fields, never a claim.\n *\n * Every other string the time views print is a value off the record (an\n * instant, a zone, a tool name, the record's own word for `how`, `choice.by`,\n * `outcome`, `verdict`, a refusal code) or a library sentence handed through\n * (an ask's `refused.reason`). `test/served/no-own-claims.test.ts` walks\n * `src/core/time/` and the three time components against this set.\n *\n * Two labels carry a MEANING the reader must not miss, and are chosen from\n * the design page's own words (agentfootprint docs/design/time § 8, § 10.2):\n * `widened` (\"wider than asked\") on a fill that reads more than was asked,\n * and `clockUnknown` (\"clock unknown\") on a value, a tz database or a held\n * range whose clock the record does not know.\n */\nexport const LABELS = Object.freeze({\n band: 'time',\n rows: 'rows',\n turn: 'turn',\n clock: 'clock',\n now: 'now',\n zone: 'zone',\n source: 'source',\n window: 'window',\n clockOnResume: 'clock on resume',\n passed: 'passed',\n kept: 'kept',\n readings: 'readings',\n reader: 'reader',\n tzdata: 'tz database',\n noMentions: 'no mentions',\n quote: 'quote',\n candidates: 'candidates',\n choice: 'choice',\n remaining: 'remaining',\n open: 'open',\n policy: 'policy',\n refused: 'refused',\n problem: 'problem',\n said: 'said',\n implied: 'implied',\n notes: 'notes',\n grain: 'grain',\n calls: 'calls',\n how: 'how',\n form: 'form',\n asked: 'asked',\n person: 'person',\n mention: 'mention',\n by: 'by',\n rounded: 'rounded',\n why: 'why',\n sent: 'sent',\n widened: 'wider than asked',\n extra: 'extra',\n trimmedByTool: 'trimmed by tool',\n partlyBeyondRetention: 'partly beyond retention',\n argument: 'argument',\n dispatchedAt: 'dispatched at',\n drift: 'drift at dispatch',\n period: 'period',\n verdict: 'verdict',\n queried: 'queried',\n held: 'held',\n readAt: 'read at',\n clockUnknown: 'clock unknown',\n ask: 'time ask',\n request: 'request',\n repeat: 'asked again',\n answer: 'answer',\n reason: 'reason',\n field: 'field',\n format: 'format',\n choices: 'choices',\n strict: 'strict',\n missing: 'missing',\n axis: 'time axis',\n column: 'column',\n unit: 'unit',\n interval: 'interval',\n aggregate: 'aggregate',\n summary: 'summary',\n malformed: 'malformed',\n unjudged: 'not checked',\n values: 'values',\n placed: 'placed',\n dstGap: 'dst gap',\n unreadable: 'unreadable',\n});\n","/**\n * foldTimeRows — the time layer's rows on the honesty ledger, grouped for\n * reading (agentfootprint 9.129.0, time design § 10.6; the row shapes are\n * `core/time/rows.ts` · `TimeRow` and `coverage/period.ts` · `PeriodRow`).\n *\n * WHY. An armed agent (`.time()`) files five row kinds on\n * `AgentState.findingsLedger` beside the findings rows: one `clock` per turn,\n * a `clock-on-resume` when a resume passed a different `time`, a\n * `time-reading` per mention the reader found, a `call-window` per call to a\n * tool that declares period forms, and a `call` per dispatched call. The\n * results layer files a `period` verdict per call whose tool declares a\n * period. Read raw, one call's story is spread over three rows; this fold\n * joins them by `toolCallId` under their turn, and joins the call's own\n * declared period (`coverageDeclared` · `period`) beside the verdict, so the\n * reader sees asked → sent → covered in one place.\n *\n * THE LAWS THIS FILE KEEPS:\n *\n * 1. A SHAPE THE LENS DOES NOT OWN. The rows came off a recording as JSON,\n * so each is narrowed by its shape here and a row that does not fit is\n * passed over (the `FindingsBand.tsx` · `standingOf` precedent). Types\n * mirror the library's (`shapes.ts`, pinned to them by a type test).\n * 2. NEVER INFER. Nothing here compares instants, computes a verdict or\n * decides that a window differs: `wider than asked` is printed only\n * where the row carries `differs`, a drift only where it carries\n * `drift`. A row kind the lens does not know is skipped.\n * 3. OMIT, NEVER DENY. `undefined` when the ledger holds no time row and no\n * period row — an unarmed run has no band, never an empty one.\n *\n * Pure: no React, no clock, no I/O.\n */\n\nimport type {\n CallRowShape as CallRow,\n CallWindowRowShape as CallWindowRow,\n ClockOnResumeRowShape as ClockOnResumeRow,\n ClockRowShape as ClockRow,\n TimeReadingRowShape as TimeReadingRow,\n TimeRangeShape as TimeRange,\n} from './shapes.js';\n\n/** A period verdict row, as read (the library does not export the type from its root). */\nexport interface PeriodRowShape {\n readonly kind: 'period';\n readonly turn: number;\n readonly toolCallId: string;\n readonly toolName: string;\n readonly iteration: number;\n readonly verdict: string;\n readonly argument?: string;\n}\n\n/** What a result declared its read covered (`DeclaredPeriod`), as read. */\nexport interface DeclaredPeriodShape {\n readonly queried: TimeRange;\n readonly held: TimeRange | 'unknown';\n readonly readAt?: string;\n}\n\n/** One call's time story: its window decision, its dispatch moment, its period verdict. */\nexport interface TimeCall {\n readonly toolCallId: string;\n readonly toolName: string;\n readonly iteration: number;\n readonly window?: CallWindowRow;\n readonly dispatch?: CallRow;\n readonly period?: PeriodRowShape;\n /** The period the call's result declared (`coverageDeclared` · `period`), joined by `toolCallId`. */\n readonly declared?: DeclaredPeriodShape;\n}\n\n/** One turn's time rows, in the order the ledger holds them. */\nexport interface TimeTurn {\n readonly turn: number;\n readonly clock?: ClockRow;\n readonly resumes: readonly ClockOnResumeRow[];\n readonly readings: readonly TimeReadingRow[];\n readonly calls: readonly TimeCall[];\n}\n\nexport interface TimeFold {\n /** How many ledger rows the fold read (time kinds and `period`). */\n readonly rows: number;\n readonly turns: readonly TimeTurn[];\n}\n\n// ─── Narrowing ────────────────────────────────────────────────────────────\n\ntype Rec = Readonly<Record<string, unknown>>;\n\nconst isRec = (v: unknown): v is Rec => v !== null && typeof v === 'object' && !Array.isArray(v);\nconst isStr = (v: unknown): v is string => typeof v === 'string' && v.length > 0;\nconst isCount = (v: unknown): v is number => typeof v === 'number' && Number.isInteger(v) && v >= 0;\n\n/** `{ from, to }` of two strings — the one range shape every time row carries. */\nexport function isRangeShape(v: unknown): v is TimeRange {\n return isRec(v) && isStr(v.from) && isStr(v.to);\n}\n\nconst hasTurn = (r: Rec): boolean => isCount(r.turn) && isCount(r.iteration);\n\nfunction clockOf(r: Rec): ClockRow | undefined {\n return isStr(r.now) && isStr(r.zone) && isStr(r.nowSource) && isStr(r.zoneSource)\n ? (r as unknown as ClockRow)\n : undefined;\n}\n\nfunction resumeOf(r: Rec): ClockOnResumeRow | undefined {\n return isRec(r.passed) && isRec(r.kept) ? (r as unknown as ClockOnResumeRow) : undefined;\n}\n\nfunction readingOf(r: Rec): TimeReadingRow | undefined {\n const reader = r.reader;\n if (!isRec(reader) || !isStr(reader.id) || !isStr(reader.version) || !isCount(r.mentions)) {\n return undefined;\n }\n if (r.candidates !== undefined && !Array.isArray(r.candidates)) return undefined;\n return r as unknown as TimeReadingRow;\n}\n\nconst callIdentity = (r: Rec): boolean => isStr(r.toolCallId) && typeof r.toolName === 'string';\n\nfunction windowOf(r: Rec): CallWindowRow | undefined {\n return callIdentity(r) && isStr(r.how) ? (r as unknown as CallWindowRow) : undefined;\n}\n\nfunction dispatchOf(r: Rec): CallRow | undefined {\n return callIdentity(r) && isStr(r.dispatchedAt) ? (r as unknown as CallRow) : undefined;\n}\n\nfunction periodOf(r: Rec): PeriodRowShape | undefined {\n return callIdentity(r) && isStr(r.verdict) ? (r as unknown as PeriodRowShape) : undefined;\n}\n\n/** The `period` a `coverageDeclared` row carries, by its `toolCallId`. */\nfunction declaredPeriods(coverage: readonly unknown[] | undefined): Map<string, DeclaredPeriodShape> {\n const out = new Map<string, DeclaredPeriodShape>();\n for (const row of coverage ?? []) {\n if (!isRec(row) || !isStr(row.toolCallId) || !isRec(row.period)) continue;\n const p = row.period;\n if (!isRangeShape(p.queried) || !(p.held === 'unknown' || isRangeShape(p.held))) continue;\n out.set(row.toolCallId, p as unknown as DeclaredPeriodShape);\n }\n return out;\n}\n\n// ─── The fold ─────────────────────────────────────────────────────────────\n\ninterface TurnDraft {\n turn: number;\n clock?: ClockRow;\n resumes: ClockOnResumeRow[];\n readings: TimeReadingRow[];\n calls: Map<string, { -readonly [K in keyof TimeCall]: TimeCall[K] }>;\n}\n\n/**\n * The time rows of `ledger`, grouped by turn and, within a turn, by call —\n * or `undefined` when the ledger holds none (law 3). `coverage` is the\n * state's `coverageDeclared` at the same stop, read only for each call's\n * declared `period`.\n */\nexport function foldTimeRows(\n ledger: readonly unknown[] | undefined,\n coverage?: readonly unknown[],\n): TimeFold | undefined {\n if (!Array.isArray(ledger)) return undefined;\n const turns = new Map<number, TurnDraft>();\n const declared = declaredPeriods(coverage);\n let rows = 0;\n const turnOf = (n: number): TurnDraft => {\n let t = turns.get(n);\n if (t === undefined) {\n t = { turn: n, resumes: [], readings: [], calls: new Map() };\n turns.set(n, t);\n }\n return t;\n };\n const callOf = (t: TurnDraft, r: Rec) => {\n const id = r.toolCallId as string;\n let c = t.calls.get(id);\n if (c === undefined) {\n c = { toolCallId: id, toolName: r.toolName as string, iteration: r.iteration as number };\n const d = declared.get(id);\n if (d !== undefined) c.declared = d;\n t.calls.set(id, c);\n }\n return c;\n };\n\n for (const row of ledger) {\n if (!isRec(row) || !hasTurn(row)) continue;\n const t = (): TurnDraft => turnOf(row.turn as number);\n switch (row.kind) {\n case 'clock': {\n const clock = clockOf(row);\n if (clock === undefined) continue;\n t().clock = clock;\n break;\n }\n case 'clock-on-resume': {\n const resume = resumeOf(row);\n if (resume === undefined) continue;\n t().resumes.push(resume);\n break;\n }\n case 'time-reading': {\n const reading = readingOf(row);\n if (reading === undefined) continue;\n t().readings.push(reading);\n break;\n }\n case 'call-window': {\n const w = windowOf(row);\n if (w === undefined) continue;\n callOf(t(), row).window = w;\n break;\n }\n case 'call': {\n const d = dispatchOf(row);\n if (d === undefined) continue;\n callOf(t(), row).dispatch = d;\n break;\n }\n case 'period': {\n const p = periodOf(row);\n if (p === undefined) continue;\n callOf(t(), row).period = p;\n break;\n }\n default:\n continue;\n }\n rows += 1;\n }\n if (rows === 0) return undefined;\n return {\n rows,\n turns: [...turns.values()].map((t) => ({\n turn: t.turn,\n ...(t.clock !== undefined ? { clock: t.clock } : {}),\n resumes: t.resumes,\n readings: t.readings,\n calls: [...t.calls.values()],\n })),\n };\n}\n\n// ─── Spelling ─────────────────────────────────────────────────────────────\n\n/**\n * A signed millisecond count as the shortest exact spelling: `+30m`,\n * `-1h 5m`, `+45s`, `+250ms`. A drift is printed as the record's number,\n * spelled — never rounded into a different number.\n */\nexport function spellMs(ms: number): string {\n const sign = ms < 0 ? '-' : '+';\n let rest = Math.abs(ms);\n const parts: string[] = [];\n for (const [unit, size] of [\n ['h', 3_600_000],\n ['m', 60_000],\n ['s', 1_000],\n ] as const) {\n const n = Math.floor(rest / size);\n if (n > 0) parts.push(`${n}${unit}`);\n rest -= n * size;\n }\n if (rest > 0 || parts.length === 0) parts.push(`${rest}ms`);\n return sign + parts.join(' ');\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1141,10 +1141,10 @@ function approveDecision(input) {
|
|
|
1141
1141
|
function declineDecision(input) {
|
|
1142
1142
|
return buildConsent(false, input, "declineDecision");
|
|
1143
1143
|
}
|
|
1144
|
-
function buildConsent(approved, input,
|
|
1144
|
+
function buildConsent(approved, input, door2) {
|
|
1145
1145
|
if (typeof input?.by !== "string" || input.by.trim().length === 0) {
|
|
1146
1146
|
throw new Error(
|
|
1147
|
-
`${
|
|
1147
|
+
`${door2} needs \`by\` \u2014 who is deciding (an operator id, an email). The decision is an audit record, and a record with no actor names nobody; it cannot be defaulted.`
|
|
1148
1148
|
);
|
|
1149
1149
|
}
|
|
1150
1150
|
return {
|
|
@@ -1194,6 +1194,97 @@ function isConsentDecision(value) {
|
|
|
1194
1194
|
return typeof value === "object" && value !== null && typeof value.approved === "boolean" && typeof value.by === "string";
|
|
1195
1195
|
}
|
|
1196
1196
|
|
|
1197
|
+
// src/core/time/timeAsk.ts
|
|
1198
|
+
var isRec = (v) => v !== null && typeof v === "object" && !Array.isArray(v);
|
|
1199
|
+
var isValue = (v) => typeof v === "string" || typeof v === "number" || typeof v === "boolean";
|
|
1200
|
+
function awaitingOf(value) {
|
|
1201
|
+
if (!isRec(value)) return void 0;
|
|
1202
|
+
if (Array.isArray(value.fields)) return value;
|
|
1203
|
+
if (isRec(value.awaitingInput)) return awaitingOf(value.awaitingInput);
|
|
1204
|
+
if (isRec(value.pauseData)) return awaitingOf(value.pauseData);
|
|
1205
|
+
return void 0;
|
|
1206
|
+
}
|
|
1207
|
+
function fieldOf(raw, missing) {
|
|
1208
|
+
if (!isRec(raw) || typeof raw.id !== "string" || typeof raw.format !== "string") return void 0;
|
|
1209
|
+
const values = Array.isArray(raw.enum) ? raw.enum.filter(isValue) : [];
|
|
1210
|
+
const labels = Array.isArray(raw.labels) ? raw.labels : [];
|
|
1211
|
+
return {
|
|
1212
|
+
id: raw.id,
|
|
1213
|
+
format: raw.format,
|
|
1214
|
+
required: raw.required !== false,
|
|
1215
|
+
missing: missing.has(raw.id),
|
|
1216
|
+
...typeof raw.description === "string" ? { description: raw.description } : {},
|
|
1217
|
+
choices: values.map((value, i) => {
|
|
1218
|
+
const label = labels[i];
|
|
1219
|
+
return typeof label === "string" ? { value, label } : { value };
|
|
1220
|
+
}),
|
|
1221
|
+
strict: raw.strict === true
|
|
1222
|
+
};
|
|
1223
|
+
}
|
|
1224
|
+
function answerOf(raw) {
|
|
1225
|
+
if (!isRec(raw)) return void 0;
|
|
1226
|
+
const out = {};
|
|
1227
|
+
for (const [k, v] of Object.entries(raw)) if (isValue(v)) out[k] = v;
|
|
1228
|
+
return Object.keys(out).length > 0 ? out : void 0;
|
|
1229
|
+
}
|
|
1230
|
+
function timeAskOf(value) {
|
|
1231
|
+
const awaiting = awaitingOf(value);
|
|
1232
|
+
if (awaiting === void 0) return void 0;
|
|
1233
|
+
const missing = new Set(
|
|
1234
|
+
Array.isArray(awaiting.missing) ? awaiting.missing.filter((m) => typeof m === "string") : []
|
|
1235
|
+
);
|
|
1236
|
+
const fields = awaiting.fields.map((f) => fieldOf(f, missing)).filter((f) => f !== void 0);
|
|
1237
|
+
if (fields.length === 0) return void 0;
|
|
1238
|
+
const refused = awaiting.refused;
|
|
1239
|
+
const repeat = awaiting.repeat;
|
|
1240
|
+
const answer = isRec(refused) ? answerOf(refused.answer) : void 0;
|
|
1241
|
+
return {
|
|
1242
|
+
...typeof awaiting.requestId === "string" ? { requestId: awaiting.requestId } : {},
|
|
1243
|
+
...typeof awaiting.question === "string" ? { question: awaiting.question } : {},
|
|
1244
|
+
fields,
|
|
1245
|
+
...isRec(refused) && typeof refused.reason === "string" ? { refused: { reason: refused.reason, ...answer !== void 0 ? { answer } : {} } } : {},
|
|
1246
|
+
...isRec(repeat) && typeof repeat.count === "number" ? { repeat: repeat.count } : {}
|
|
1247
|
+
};
|
|
1248
|
+
}
|
|
1249
|
+
|
|
1250
|
+
// src/core/time/timeAxis.ts
|
|
1251
|
+
import * as agentfootprint from "agentfootprint";
|
|
1252
|
+
function door() {
|
|
1253
|
+
return agentfootprint;
|
|
1254
|
+
}
|
|
1255
|
+
function valuesOf(rows, axis) {
|
|
1256
|
+
const normalise = door().normaliseInstants;
|
|
1257
|
+
if (typeof normalise !== "function") return void 0;
|
|
1258
|
+
try {
|
|
1259
|
+
const view = normalise(rows, axis);
|
|
1260
|
+
return {
|
|
1261
|
+
status: view.status,
|
|
1262
|
+
placed: view.status === "refused" ? 0 : view.points.length,
|
|
1263
|
+
clockUnknown: view.status === "instants" ? 0 : view.count,
|
|
1264
|
+
counts: view.counts
|
|
1265
|
+
};
|
|
1266
|
+
} catch {
|
|
1267
|
+
return void 0;
|
|
1268
|
+
}
|
|
1269
|
+
}
|
|
1270
|
+
function datasetTimeAxisOf(meta, rows) {
|
|
1271
|
+
const raw = meta !== null && typeof meta === "object" ? meta.timeAxis : void 0;
|
|
1272
|
+
if (raw === void 0) return { status: "absent" };
|
|
1273
|
+
const { readTimeAxis, describeTimeAxis } = door();
|
|
1274
|
+
if (typeof readTimeAxis !== "function") return { status: "unjudged", raw };
|
|
1275
|
+
const reading = readTimeAxis(meta);
|
|
1276
|
+
if (reading.status === "absent") return { status: "absent" };
|
|
1277
|
+
if (reading.status === "malformed") return { status: "malformed", issues: reading.issues };
|
|
1278
|
+
const summary = typeof describeTimeAxis === "function" ? describeTimeAxis(reading.axis) : void 0;
|
|
1279
|
+
const values = rows !== void 0 ? valuesOf(rows, reading.axis) : void 0;
|
|
1280
|
+
return {
|
|
1281
|
+
status: "declared",
|
|
1282
|
+
axis: reading.axis,
|
|
1283
|
+
...summary !== void 0 ? { summary } : {},
|
|
1284
|
+
...values !== void 0 ? { values } : {}
|
|
1285
|
+
};
|
|
1286
|
+
}
|
|
1287
|
+
|
|
1197
1288
|
export {
|
|
1198
1289
|
buildStepGraphFromSnapshot,
|
|
1199
1290
|
buildSpecTreeFromBoundary,
|
|
@@ -1234,6 +1325,8 @@ export {
|
|
|
1234
1325
|
declineDecision,
|
|
1235
1326
|
decisionRequestBody,
|
|
1236
1327
|
decisionSentence,
|
|
1237
|
-
isConsentDecision
|
|
1328
|
+
isConsentDecision,
|
|
1329
|
+
timeAskOf,
|
|
1330
|
+
datasetTimeAxisOf
|
|
1238
1331
|
};
|
|
1239
|
-
//# sourceMappingURL=chunk-
|
|
1332
|
+
//# sourceMappingURL=chunk-6RNHIZHE.js.map
|