agentfootprint-lens 0.71.0 → 0.72.1
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 +22 -3
- package/dist/{chunk-SYH5K5CL.js → chunk-6YXIST3E.js} +18 -3
- package/dist/chunk-6YXIST3E.js.map +1 -0
- package/dist/{chunk-OM2CDZJS.js → chunk-DBEVLCHX.js} +8 -3
- package/dist/chunk-DBEVLCHX.js.map +1 -0
- package/dist/{chunk-K6DNVTYE.js → chunk-ZYVDW34A.js} +25 -11
- package/dist/{chunk-K6DNVTYE.js.map → chunk-ZYVDW34A.js.map} +1 -1
- package/dist/context.cjs +40 -11
- package/dist/context.cjs.map +1 -1
- package/dist/context.d.cts +2 -2
- package/dist/context.d.ts +2 -2
- package/dist/context.js +2 -2
- package/dist/{contextAt-CwRRDQYD.d.ts → contextAt-Dj4FsdFX.d.ts} +28 -4
- package/dist/{contextAt-Cy5xTLup.d.cts → contextAt-Ng-DLxF3.d.cts} +28 -4
- package/dist/core.cjs +17 -2
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +6 -2
- package/dist/core.d.ts +6 -2
- package/dist/core.js +1 -1
- package/dist/{index-CJhcdeTi.d.cts → index-BT5Tsjz1.d.cts} +14 -6
- package/dist/{index-fj3hsuFi.d.ts → index-C8c9mOYy.d.ts} +14 -6
- package/dist/index.cjs +47 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -5
- package/dist/index.d.ts +8 -5
- package/dist/index.js +3 -3
- package/dist/why.cjs +7 -2
- package/dist/why.cjs.map +1 -1
- package/dist/why.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-OM2CDZJS.js.map +0 -1
- package/dist/chunk-SYH5K5CL.js.map +0 -1
package/README.md
CHANGED
|
@@ -1043,8 +1043,12 @@ const { account, shown } = await res.json();
|
|
|
1043
1043
|
library's `text`; the pane's own strings are `PLAIN_WORDS_LABELS` — names,
|
|
1044
1044
|
never claims (walked by `test/served/no-own-claims.test.ts`).
|
|
1045
1045
|
- **No HTML from data.** A sentence renders from its typed `parts` as text:
|
|
1046
|
-
`code` → `<code>`, `quote` →
|
|
1047
|
-
own voucher. A `<script>` in a question is shown as the characters
|
|
1046
|
+
`code` → `<code>`, `quote` → a span, a declared `label` → `<strong>` with
|
|
1047
|
+
its own voucher. A `<script>` in a question is shown as the characters
|
|
1048
|
+
`<script>`.
|
|
1049
|
+
- **No punctuation of its own.** The account's text carries its quotation
|
|
1050
|
+
marks (`“{{question:quote}}”`), so a quote is never a `<q>` — the browser
|
|
1051
|
+
would draw a second pair around it.
|
|
1048
1052
|
- **Show me = leaves.** A withheld leaf says why (`not shown here`, `too large
|
|
1049
1053
|
to show here`, …); a line into a call the model read without the tool's
|
|
1050
1054
|
report-only fields says so softly.
|
|
@@ -1199,7 +1203,22 @@ band and no reason above it:
|
|
|
1199
1203
|
timeStandingOf(undefined, ledger); // undefined — nothing filed, nothing listed
|
|
1200
1204
|
timeStandingOf(await agent.assessment(), ledger);
|
|
1201
1205
|
// { standing: 'not-sure', reasons: [{ reason: 'period-differs-from-asked',
|
|
1202
|
-
// calls: [{ toolCallId: 'c1', toolName: 'client_activity' }] }, …] }
|
|
1206
|
+
// calls: [{ toolCallId: 'c1', toolName: 'client_activity' }] }, …], otherReasons: 0 }
|
|
1207
|
+
```
|
|
1208
|
+
|
|
1209
|
+
**The standing is said, never silence.** An answer can be not sure for
|
|
1210
|
+
reasons that are not about time — a value no tool returned, an unverified
|
|
1211
|
+
argument. With an assessment that names no time reason, the view still draws
|
|
1212
|
+
the standing: `no time-related reason`, the standing as filed, and
|
|
1213
|
+
`other reasons — see In plain words` (counted in `otherReasons`, listed by
|
|
1214
|
+
In plain words) or `no reason filed`. An `argument-assumed` the lens cannot
|
|
1215
|
+
place — the data projection's bare name, or a ledger not handed in — is
|
|
1216
|
+
listed as `undetermined`, and "no time-related reason" is never said beside
|
|
1217
|
+
it:
|
|
1218
|
+
|
|
1219
|
+
```ts
|
|
1220
|
+
timeStandingOf({ standing: 'not-sure', reasons: [{ reason: 'value-survived-revision', witness: [] }] });
|
|
1221
|
+
// { standing: 'not-sure', reasons: [], otherReasons: 1 }
|
|
1203
1222
|
```
|
|
1204
1223
|
|
|
1205
1224
|
Headless: `foldTimeRows(ledger, coverage?)`, `answerOfReading(turn, reading)`,
|
|
@@ -233,6 +233,12 @@ var LABELS = Object.freeze({
|
|
|
233
233
|
"period-undeclared": "result declared no period",
|
|
234
234
|
"derived-from-reading": "time value spelled from the person's words",
|
|
235
235
|
"argument-assumed": "period filled from an assumed default",
|
|
236
|
+
// An answer with no time reason still has a standing: the Time view says the
|
|
237
|
+
// time half of it instead of drawing nothing (`timeStandingOf` laws 3 and 4).
|
|
238
|
+
noTimeReason: "no time-related reason",
|
|
239
|
+
otherReasons: "other reasons \u2014 see In plain words",
|
|
240
|
+
noReasonFiled: "no reason filed",
|
|
241
|
+
undetermined: "which argument it names: not told here",
|
|
236
242
|
// 0.71.0 — each call's window asked → sent → read: the sent range when the
|
|
237
243
|
// row's `asked` IS it (an exact fill, a bound or model window), and a fill
|
|
238
244
|
// whose bounds moved outward, whose sent range the record does not keep.
|
|
@@ -495,9 +501,13 @@ function timeStandingOf(assessment, ledger = []) {
|
|
|
495
501
|
const a = assessmentOf(assessment);
|
|
496
502
|
if (a === void 0) return void 0;
|
|
497
503
|
const reasons = [];
|
|
504
|
+
const undetermined = [];
|
|
505
|
+
let otherReasons = 0;
|
|
498
506
|
for (const entry of a.reasons) {
|
|
499
507
|
if (typeof entry === "string") {
|
|
500
508
|
if (isTimeReason(entry)) reasons.push({ reason: entry, calls: [] });
|
|
509
|
+
else if (entry === "argument-assumed") undetermined.push("argument-assumed");
|
|
510
|
+
else otherReasons += 1;
|
|
501
511
|
continue;
|
|
502
512
|
}
|
|
503
513
|
if (!isRec2(entry) || typeof entry.reason !== "string") continue;
|
|
@@ -508,12 +518,17 @@ function timeStandingOf(assessment, ledger = []) {
|
|
|
508
518
|
} else if (entry.reason === "argument-assumed") {
|
|
509
519
|
const periodRows = rows.filter(isPeriodArgument);
|
|
510
520
|
if (periodRows.length > 0) reasons.push({ reason: "argument-assumed", calls: callsOf(periodRows) });
|
|
521
|
+
else if (rows.length > 0) otherReasons += 1;
|
|
522
|
+
else undetermined.push("argument-assumed");
|
|
523
|
+
} else {
|
|
524
|
+
otherReasons += 1;
|
|
511
525
|
}
|
|
512
526
|
}
|
|
513
|
-
if (reasons.length === 0) return void 0;
|
|
514
527
|
return {
|
|
515
528
|
...typeof a.standing === "string" ? { standing: a.standing } : {},
|
|
516
|
-
reasons
|
|
529
|
+
reasons,
|
|
530
|
+
otherReasons,
|
|
531
|
+
...undetermined.length > 0 ? { undetermined } : {}
|
|
517
532
|
};
|
|
518
533
|
}
|
|
519
534
|
|
|
@@ -582,4 +597,4 @@ export {
|
|
|
582
597
|
timeStandingOf,
|
|
583
598
|
timeAskOf
|
|
584
599
|
};
|
|
585
|
-
//# sourceMappingURL=chunk-
|
|
600
|
+
//# sourceMappingURL=chunk-6YXIST3E.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/context/contextAt.ts","../src/core/time/labels.ts","../src/core/time/timeRows.ts","../src/core/time/timeStanding.ts","../src/core/time/timeAsk.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 *\n * The time-reason lines (keyed by the reason's own name, e.g.\n * `period-differs-from-asked`) are LABELS for a reason the library filed —\n * the view prints one only beside the library's reason, never in its place\n * and never for a reason the library did not file.\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 // 0.70.0 — agentfootprint 9.132.0's rows and the period row's result checks.\n answered: 'settled by the person',\n derived: 'derived from reading',\n sourceClock: 'source clock',\n differs: 'differs from asked',\n against: 'against',\n read: 'read',\n step: 'step',\n shifted: 'shifted',\n beyondRetention: 'beyond retention',\n // 0.70.0 — the answer's time standing (`<TimeView>`): the record's own\n // standing word beside these, and one plain line per time reason the\n // library filed, keyed by the reason's own name.\n standing: 'answer standing',\n timeReasons: 'time reasons',\n 'period-differs-from-asked': 'read differs from the window asked',\n 'period-beyond-retention': 'window older than the source keeps',\n 'period-not-held': 'source holds none of the period',\n 'period-partly-held': 'source holds part of the period',\n 'period-unknown': 'held period unknown to the source',\n 'period-undeclared': 'result declared no period',\n 'derived-from-reading': \"time value spelled from the person's words\",\n 'argument-assumed': 'period filled from an assumed default',\n // An answer with no time reason still has a standing: the Time view says the\n // time half of it instead of drawing nothing (`timeStandingOf` laws 3 and 4).\n noTimeReason: 'no time-related reason',\n otherReasons: 'other reasons — see In plain words',\n noReasonFiled: 'no reason filed',\n undetermined: 'which argument it names: not told here',\n // 0.71.0 — each call's window asked → sent → read: the sent range when the\n // row's `asked` IS it (an exact fill, a bound or model window), and a fill\n // whose bounds moved outward, whose sent range the record does not keep.\n sentAsAsked: 'as asked',\n sentRounded: 'asked, rounded outward',\n});\n","/**\n * foldTimeRows — the time layer's rows on the honesty ledger, grouped for\n * reading (agentfootprint 9.129.0 and 9.132.0, time design § 10.6; the row\n * shapes are `core/time/rows.ts` · `TimeRow` and `coverage/period.ts` ·\n * `PeriodRow`).\n *\n * WHY. An armed agent (`.time()`) files eight 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 `time-answer` per mention\n * the person settled in the time ask, a `call-window` per call to a tool that\n * declares period forms, a `call` per dispatched call, a `source-clock` per\n * call and zone whose dataset declares a wall-clock zone, and a\n * `time-derived` per judged answer that states values the library spelled\n * from a reading. The results layer files a `period` verdict per call whose\n * tool declares a period — under `.time()` with its result checks\n * (`differs`, `shifted`, `beyondRetention`, `partlyBeyondRetention`). Read\n * raw, one call's story is spread over four rows; this fold joins them by\n * `toolCallId` under their turn, and joins the call's own declared period\n * (`coverageDeclared` · `period`) beside the verdict, so the reader sees\n * asked → sent → covered in one place. A `time-answer` is joined to its\n * reading by `mention` within the turn (`answerOfReading` — the LATEST answer\n * for the mention, the one the library binds).\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 PeriodDiffersShape,\n SourceClockRowShape as SourceClockRow,\n TimeAnswerRowShape as TimeAnswerRow,\n TimeDerivedRowShape as TimeDerivedRow,\n TimeReadingRowShape as TimeReadingRow,\n TimeRangeShape as TimeRange,\n} from './shapes.js';\n\n/**\n * A period verdict row, as read — a mirror of the library's `PeriodRow`\n * (`test/time/shapes.types.test.ts` pins it). The four check fields are the\n * time layer's result checks (agentfootprint 9.132.0), filed only under\n * `.time()` and only when they hold; each is printed only where the row\n * carries it.\n */\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 /** `period-differs-from-asked` — what the call read is not the range compared against. */\n readonly differs?: PeriodDiffersShape;\n /** `period-shifted` — the look-back ran as sent, `byMs` after the turn's `now`. */\n readonly shifted?: { readonly byMs: number };\n /** `period-beyond-retention` — wholly older than the tool declares its source keeps. */\n readonly beyondRetention?: true;\n /** The read crosses the edge of what the source keeps; the verdict decides. */\n readonly partlyBeyondRetention?: true;\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 /** The wall-clock zones the call's datasets declare (`source-clock`, one per zone) — 9.132.0. */\n readonly sourceClocks?: readonly SourceClockRow[];\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 /** The windows the person settled in the time ask, in ledger order (9.132.0). */\n readonly answers: readonly TimeAnswerRow[];\n /** The answer values the library spelled from a reading of this turn (9.132.0). */\n readonly derived: readonly TimeDerivedRow[];\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\nconst isRanges = (v: unknown): v is readonly TimeRange[] => Array.isArray(v) && v.every(isRangeShape);\n\n/** A period row's `differs`, when every field fits; otherwise the field is passed over. */\nfunction differsOf(v: unknown): PeriodDiffersShape | undefined {\n if (!isRec(v) || !isStr(v.against) || !isStr(v.source) || !isRangeShape(v.asked)) return undefined;\n if (!isRanges(v.read) || !isRanges(v.missing) || !isRanges(v.extra)) return undefined;\n if (v.stepMs !== undefined && typeof v.stepMs !== 'number') return undefined;\n return v as unknown as PeriodDiffersShape;\n}\n\n/**\n * A period row, field by field: the identity and verdict, then each result\n * check only when it fits its shape — a malformed check is passed over, never\n * printed half, and the verdict still reads.\n */\nfunction periodOf(r: Rec): PeriodRowShape | undefined {\n if (!callIdentity(r) || !isStr(r.verdict)) return undefined;\n const differs = differsOf(r.differs);\n const shifted = isRec(r.shifted) && typeof r.shifted.byMs === 'number' ? { byMs: r.shifted.byMs } : undefined;\n return {\n kind: 'period',\n turn: r.turn as number,\n toolCallId: r.toolCallId as string,\n toolName: r.toolName as string,\n iteration: r.iteration as number,\n verdict: r.verdict,\n ...(isStr(r.argument) ? { argument: r.argument } : {}),\n ...(differs !== undefined ? { differs } : {}),\n ...(shifted !== undefined ? { shifted } : {}),\n ...(r.beyondRetention === true ? { beyondRetention: true as const } : {}),\n ...(r.partlyBeyondRetention === true ? { partlyBeyondRetention: true as const } : {}),\n };\n}\n\nfunction answerOf(r: Rec): TimeAnswerRow | undefined {\n return isCount(r.mention) &&\n isStr(r.zone) &&\n (r.how === 'confirmed' || r.how === 'edited') &&\n isStr(r.from) &&\n isStr(r.to)\n ? (r as unknown as TimeAnswerRow)\n : undefined;\n}\n\nfunction derivedOf(r: Rec): TimeDerivedRow | undefined {\n return Array.isArray(r.values) && r.values.length > 0 && r.values.every(isStr)\n ? (r as unknown as TimeDerivedRow)\n : undefined;\n}\n\nfunction sourceClockOf(r: Rec): SourceClockRow | undefined {\n return callIdentity(r) && isStr(r.zone) ? (r as unknown as SourceClockRow) : 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 answers: TimeAnswerRow[];\n derived: TimeDerivedRow[];\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: [], answers: [], derived: [], 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 case 'time-answer': {\n const a = answerOf(row);\n if (a === undefined) continue;\n t().answers.push(a);\n break;\n }\n case 'time-derived': {\n const d = derivedOf(row);\n if (d === undefined) continue;\n t().derived.push(d);\n break;\n }\n case 'source-clock': {\n const sc = sourceClockOf(row);\n if (sc === undefined) continue;\n const c = callOf(t(), row);\n c.sourceClocks = [...(c.sourceClocks ?? []), sc];\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 answers: t.answers,\n derived: t.derived,\n })),\n };\n}\n\n/**\n * The window the person settled for `reading`'s mention in this turn — the\n * LATEST `time-answer` row for that mention (the one the library binds,\n * `windows.ts` · `turnWindowsOf`) — or `undefined` when the person has not\n * answered it. Read only off the answer row; nothing is compared.\n */\nexport function answerOfReading(\n turn: Pick<TimeTurn, 'answers'>,\n reading: Pick<TimeReadingRow, 'mention'>,\n): TimeAnswerRow | undefined {\n if (reading.mention === undefined) return undefined;\n for (let i = turn.answers.length - 1; i >= 0; i--) {\n const a = turn.answers[i]!;\n if (a.mention === reading.mention) return a;\n }\n return undefined;\n}\n\n// ─── Asked → sent → read ──────────────────────────────────────────────────\n\n/**\n * What one call SENT, in the record's own words (agentfootprint\n * `core/time/rows.ts` · `CallWindowRow`):\n *\n * | `as` | When | Range |\n * |------|------|-------|\n * | `sent` | a widened fill — the row carries its own `sent` | the row's `sent` |\n * | `asked` | `filled` exactly, `bound`, `model-chosen`, `model` — the row's `asked` IS the sent range (\"the person's on a fill, the sent value read back otherwise\"; a fill went \"into form `form` exactly\") | the row's `asked` |\n * | `rounded` | a fill whose bounds moved outward (`rounded`) — the sent range is not on the record | none |\n *\n * `undefined` when the call sent no window: refused, not filled, unread, or no\n * row. Read off the row's `how` and the fields it carries; nothing compared.\n */\nexport type CallSent =\n | { readonly as: 'sent' | 'asked'; readonly range: TimeRange }\n | { readonly as: 'rounded' };\n\n/** The `how`s whose `asked` IS the range the call sent (rows.ts · `CallWindowRow`). */\nconst SENT_AS_ASKED = new Set(['filled', 'bound', 'model-chosen', 'model']);\n\nexport function sentOf(w: CallWindowRow | undefined): CallSent | undefined {\n if (w === undefined) return undefined;\n if (w.sent !== undefined) return { as: 'sent', range: w.sent };\n if (!SENT_AS_ASKED.has(w.how) || w.asked === undefined) return undefined;\n return w.rounded === true ? { as: 'rounded' } : { as: 'asked', range: w.asked };\n}\n\n/**\n * What one call READ, in the record's own words: the period its result\n * DECLARED (`coverageDeclared` · `period`, joined by `toolCallId` — what the\n * source queried and holds), or the `period` row's own verdict that the result\n * declared none (`undeclared`). `undefined` when the call did not run\n * (`refused` — its `period` row still files `undeclared`), when the result\n * has no `period` row yet, or when the host passed no `coverage` for a result\n * that did declare. The difference between asked and read is the `period`\n * row's own `differs` — never computed here.\n */\nexport type CallRead =\n | { readonly as: 'declared'; readonly declared: DeclaredPeriodShape }\n | { readonly as: 'undeclared' };\n\nexport function readOf(call: Pick<TimeCall, 'window' | 'period' | 'declared'>): CallRead | undefined {\n if (call.window?.how === 'refused') return undefined;\n if (call.declared !== undefined) return { as: 'declared', declared: call.declared };\n return call.period?.verdict === 'undeclared' ? { as: 'undeclared' } : undefined;\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","/**\n * timeStandingOf — the answer's time-related standing, as the library filed\n * it (agentfootprint 9.132.0, `agent.assessment()` /\n * `assessAnswer(recording)` / `turn_end.answerAssessment`).\n *\n * WHY. The library folds the answer's standing (known · consistent · not sure\n * · ask) from the record and names every reason that holds. Several of those\n * reasons are about TIME — the read was not the window asked, the window was\n * older than the source keeps, a value was spelled from a reading of the\n * person's words — and a Time view without them shows every row and hides\n * what the rows did to the answer.\n *\n * THE LAWS THIS FILE KEEPS:\n *\n * 1. NEVER COMPUTE A REASON. A reason is listed only when the assessment\n * the app passes names it. The ledger is read only to RESOLVE the\n * library's own witness pointers (`{ kind: 'state', key:\n * 'findingsLedger', path: '/<index>/…' }`) to the calls they name; no\n * row ever makes a reason on its own.\n * 2. TIME REASONS ONLY. `TIME_REASONS` below, in the order the library\n * filed them. `argument-assumed` is listed only when one of ITS\n * witnesses resolves to an `argument` row with `period: true` (the\n * period argument was filled from an assumed default) — the data\n * projection (`reasons` as bare names) carries no witness, so there it\n * is passed over: the lens cannot tell which argument it names.\n * 3. SAY THE STANDING, NEVER DENY. `undefined` only when the value is not\n * an assessment the lens can narrow. An assessment with no time reason\n * is NOT silence: the answer still has a standing, and the Time view\n * says the time half of it — no time-related reason, the standing as\n * filed, and whether OTHER reasons were filed (`otherReasons`, a count\n * off the assessment; the reasons themselves are In plain words' to\n * show). Silence there read as \"nothing to see\" beside an answer the\n * person was told is not sure (take-2 video, lens 0.71.0).\n * 4. A REASON THE LENS CANNOT PLACE IS NOT DENIED. `argument-assumed`\n * whose witnesses resolve to no ledger row (the data projection's bare\n * name, or a ledger not handed in) may or may not name the period\n * argument: it is listed as `undetermined`, and \"no time-related\n * reason\" is never said beside it.\n *\n * Pure: no React, no clock, no I/O.\n */\n\n/** The reasons the time view lists unconditionally when the library filed them. */\nexport const TIME_REASONS = Object.freeze([\n 'period-differs-from-asked',\n 'period-beyond-retention',\n 'period-not-held',\n 'period-partly-held',\n 'period-unknown',\n 'period-undeclared',\n 'derived-from-reading',\n] as const);\n\n/** A reason the time view can list (`argument-assumed` only on a period argument). */\nexport type TimeReason = (typeof TIME_REASONS)[number] | 'argument-assumed';\n\n/** One call a reason's witnesses name, off the ledger row the pointer resolves to. */\nexport interface TimeReasonCall {\n readonly toolCallId: string;\n readonly toolName: string;\n}\n\nexport interface TimeReasonItem {\n readonly reason: TimeReason;\n /** The calls its witnesses name — empty under the data projection, or for an answer-level reason. */\n readonly calls: readonly TimeReasonCall[];\n}\n\nexport interface TimeStanding {\n /** The library's word for the whole answer (`not-sure`, `ask`, …), as filed. */\n readonly standing?: string;\n /** The time reasons the assessment names — empty when it names none. */\n readonly reasons: readonly TimeReasonItem[];\n /**\n * How many reasons the assessment filed that are NOT about time — counted,\n * never listed (In plain words shows them). With `reasons` empty and\n * nothing `undetermined`, the answer's standing is set by these alone.\n */\n readonly otherReasons: number;\n /**\n * Reasons that may be about time but cannot be placed from what was handed\n * in (`argument-assumed` with no witness row to read). Absent when none.\n */\n readonly undetermined?: readonly TimeReason[];\n}\n\ntype Rec = Readonly<Record<string, unknown>>;\nconst isRec = (v: unknown): v is Rec => v !== null && typeof v === 'object' && !Array.isArray(v);\n\nconst isTimeReason = (r: string): r is (typeof TIME_REASONS)[number] =>\n (TIME_REASONS as readonly string[]).includes(r);\n\n/** The assessment wherever it travels: the value itself, or `turn_end`'s `{ answerAssessment }`. */\nfunction assessmentOf(value: unknown): Rec | undefined {\n if (!isRec(value)) return undefined;\n if (Array.isArray(value.reasons)) return value;\n if (isRec(value.answerAssessment)) return assessmentOf(value.answerAssessment);\n return undefined;\n}\n\n/** The ledger row a `findingsLedger` witness pointer names, when it is one. */\nfunction rowOf(pointer: unknown, ledger: readonly unknown[]): Rec | undefined {\n if (!isRec(pointer) || pointer.kind !== 'state' || pointer.key !== 'findingsLedger') return undefined;\n if (typeof pointer.path !== 'string') return undefined;\n const m = /^\\/(\\d+)(?:\\/|$)/.exec(pointer.path);\n if (m === null) return undefined;\n const row = ledger[Number(m[1])];\n return isRec(row) ? row : undefined;\n}\n\nconst callOfRow = (row: Rec): TimeReasonCall | undefined =>\n typeof row.toolCallId === 'string' && typeof row.toolName === 'string'\n ? { toolCallId: row.toolCallId, toolName: row.toolName }\n : undefined;\n\n/** The distinct calls the rows name, in witness order. */\nfunction callsOf(rows: readonly Rec[]): TimeReasonCall[] {\n const seen = new Set<string>();\n const out: TimeReasonCall[] = [];\n for (const row of rows) {\n const c = callOfRow(row);\n if (c === undefined || seen.has(c.toolCallId)) continue;\n seen.add(c.toolCallId);\n out.push(c);\n }\n return out;\n}\n\nconst isPeriodArgument = (row: Rec): boolean => row.kind === 'argument' && row.period === true;\n\n/**\n * The time reasons `assessment` names, each with the calls its witnesses\n * resolve to on `ledger`, beside the standing as filed and the count of the\n * reasons that are not about time — `undefined` only when `assessment` is not\n * an assessment (law 3).\n * `assessment` is `AnswerAssessment` (`agent.assessment()`,\n * `assessAnswer(recording)`), its data projection\n * (`turn_end.answerAssessment`), or the `turn_end` payload itself.\n */\nexport function timeStandingOf(\n assessment: unknown,\n ledger: readonly unknown[] = [],\n): TimeStanding | undefined {\n const a = assessmentOf(assessment);\n if (a === undefined) return undefined;\n const reasons: TimeReasonItem[] = [];\n const undetermined: TimeReason[] = [];\n let otherReasons = 0;\n for (const entry of a.reasons as readonly unknown[]) {\n // The data projection: a bare reason name, no witness.\n if (typeof entry === 'string') {\n if (isTimeReason(entry)) reasons.push({ reason: entry, calls: [] });\n else if (entry === 'argument-assumed') undetermined.push('argument-assumed');\n else otherReasons += 1;\n continue;\n }\n if (!isRec(entry) || typeof entry.reason !== 'string') continue;\n const witness = Array.isArray(entry.witness) ? entry.witness : [];\n const rows = witness\n .map((p) => rowOf(p, ledger))\n .filter((r): r is Rec => r !== undefined);\n if (isTimeReason(entry.reason)) {\n reasons.push({ reason: entry.reason, calls: callsOf(rows) });\n } else if (entry.reason === 'argument-assumed') {\n const periodRows = rows.filter(isPeriodArgument);\n if (periodRows.length > 0) reasons.push({ reason: 'argument-assumed', calls: callsOf(periodRows) });\n // Witness rows read, none a period argument: an assumed value of another argument.\n else if (rows.length > 0) otherReasons += 1;\n // No witness row to read: it may name the period argument — never denied (law 4).\n else undetermined.push('argument-assumed');\n } else {\n otherReasons += 1;\n }\n }\n return {\n ...(typeof a.standing === 'string' ? { standing: a.standing } : {}),\n reasons,\n otherReasons,\n ...(undetermined.length > 0 ? { undetermined } : {}),\n };\n}\n","/**\n * timeAskOf — the time half of a paused `requestInput` ask (agentfootprint\n * 9.129.0, time design § 6, step T4).\n *\n * WHY. A `requestInput` field may carry `format: 'instant' | 'time-range' |\n * 'zone'`; the library judges the person's answer at the resume door and,\n * when it refuses one, asks the SAME ask again (same `requestId`) with\n * `refused: { answer, reason }` — `reason` a sentence from the library's\n * catalog (`defaultTimeAskMessages`, overridable by the app) — and\n * `repeat: { count }`. A viewer that shows only the question hides that the\n * person already answered and was refused, and why.\n *\n * Reads the pause wherever it travels: the `AwaitingInput` itself, a pause\n * outcome or `pauseData` (`{ awaitingInput }`), or the lens's\n * `PendingAskView` (`{ pauseData: { awaitingInput } }`). Narrowed by shape,\n * never trusted whole; `undefined` when no field carries a `format` — an ask\n * with no time field has no time rows (omit, never deny).\n */\n\n/** A field value on the wire (`InputValue`). */\nexport type InputValue = string | number | boolean;\n\n/** One time field of the ask, as read. */\nexport interface TimeAskField {\n readonly id: string;\n readonly format: string;\n readonly required: boolean;\n /** In the ask's `missing` list — still to be answered. */\n readonly missing: boolean;\n readonly description?: string;\n /** The choices, each with its library-rendered label when the field carries `labels`. */\n readonly choices: readonly { readonly value: InputValue; readonly label?: string }[];\n readonly strict: boolean;\n}\n\n/** The ask's time half. */\nexport interface TimeAsk {\n readonly requestId?: string;\n readonly question?: string;\n readonly fields: readonly TimeAskField[];\n /** The refused answer — only the refused fields' values — and the catalog's reason, verbatim. */\n readonly refused?: {\n readonly answer?: Readonly<Record<string, InputValue>>;\n readonly reason: string;\n };\n /** How many times the person already answered this ask. */\n readonly repeat?: number;\n}\n\ntype Rec = Readonly<Record<string, unknown>>;\nconst isRec = (v: unknown): v is Rec => v !== null && typeof v === 'object' && !Array.isArray(v);\nconst isValue = (v: unknown): v is InputValue =>\n typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean';\n\n/** The `AwaitingInput` inside any of the three homes a pause travels in. */\nfunction awaitingOf(value: unknown): Rec | undefined {\n if (!isRec(value)) return undefined;\n if (Array.isArray(value.fields)) return value;\n if (isRec(value.awaitingInput)) return awaitingOf(value.awaitingInput);\n if (isRec(value.pauseData)) return awaitingOf(value.pauseData);\n return undefined;\n}\n\nfunction fieldOf(raw: unknown, missing: ReadonlySet<string>): TimeAskField | undefined {\n if (!isRec(raw) || typeof raw.id !== 'string' || typeof raw.format !== 'string') return undefined;\n const values = Array.isArray(raw.enum) ? raw.enum.filter(isValue) : [];\n const labels = Array.isArray(raw.labels) ? raw.labels : [];\n return {\n id: raw.id,\n format: raw.format,\n required: raw.required !== false,\n missing: missing.has(raw.id),\n ...(typeof raw.description === 'string' ? { description: raw.description } : {}),\n choices: values.map((value, i) => {\n const label = labels[i];\n return typeof label === 'string' ? { value, label } : { value };\n }),\n strict: raw.strict === true,\n };\n}\n\nfunction answerOf(raw: unknown): Readonly<Record<string, InputValue>> | undefined {\n if (!isRec(raw)) return undefined;\n const out: Record<string, InputValue> = {};\n for (const [k, v] of Object.entries(raw)) if (isValue(v)) out[k] = v;\n return Object.keys(out).length > 0 ? out : undefined;\n}\n\nexport function timeAskOf(value: unknown): TimeAsk | undefined {\n const awaiting = awaitingOf(value);\n if (awaiting === undefined) return undefined;\n const missing = new Set(\n Array.isArray(awaiting.missing) ? awaiting.missing.filter((m): m is string => typeof m === 'string') : [],\n );\n const fields = (awaiting.fields as readonly unknown[])\n .map((f) => fieldOf(f, missing))\n .filter((f): f is TimeAskField => f !== undefined);\n if (fields.length === 0) return undefined;\n const refused = awaiting.refused;\n const repeat = awaiting.repeat;\n const answer = isRec(refused) ? answerOf(refused.answer) : undefined;\n return {\n ...(typeof awaiting.requestId === 'string' ? { requestId: awaiting.requestId } : {}),\n ...(typeof awaiting.question === 'string' ? { question: awaiting.question } : {}),\n fields,\n ...(isRec(refused) && typeof refused.reason === 'string'\n ? { refused: { reason: refused.reason, ...(answer !== undefined ? { answer } : {}) } }\n : {}),\n ...(isRec(repeat) && typeof repeat.count === 'number' ? { repeat: repeat.count } : {}),\n };\n}\n"],"mappings":"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","names":["isRec","isRec","answerOf"]}
|
|
@@ -882,6 +882,9 @@ var LENS_STYLESHEET = `
|
|
|
882
882
|
.lens-plain-line, .lens-plain-text { overflow-wrap: anywhere; }
|
|
883
883
|
.lens-plain-line code { font-family: ${T.fontMono}; font-size: 0.92em; }
|
|
884
884
|
.lens-plain-label { font-weight: 600; }
|
|
885
|
+
/* The person's words, quoted \u2014 the account's text carries the marks, so this is a span, never a
|
|
886
|
+
<q> (which the browser draws with a second pair). A long unbroken token in them still wraps. */
|
|
887
|
+
.lens-plain-quote { overflow-wrap: anywhere; }
|
|
885
888
|
.lens-plain-chips { display: inline-flex; flex-wrap: wrap; gap: 6px; margin-left: 6px; vertical-align: middle; }
|
|
886
889
|
.lens-plain-chips--row { display: flex; margin: 6px 0 0; }
|
|
887
890
|
.lens-plain-chip {
|
|
@@ -1236,7 +1239,8 @@ import { coolDark, coolLight, tokensToCSSVars } from "footprint-explainable-ui";
|
|
|
1236
1239
|
import { Fragment, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1237
1240
|
var Parts = ({ parts }) => /* @__PURE__ */ jsx5(Fragment, { children: parts.map((part, i) => {
|
|
1238
1241
|
if ("code" in part) return /* @__PURE__ */ jsx5("code", { children: part.code }, i);
|
|
1239
|
-
if ("quote" in part)
|
|
1242
|
+
if ("quote" in part)
|
|
1243
|
+
return /* @__PURE__ */ jsx5("span", { className: "lens-plain-quote", children: part.quote }, i);
|
|
1240
1244
|
if ("label" in part)
|
|
1241
1245
|
return /* @__PURE__ */ jsx5("strong", { className: "lens-plain-label", title: `${LABELS.voucher}: ${part.source}`, children: part.label }, i);
|
|
1242
1246
|
return /* @__PURE__ */ jsx5(React5.Fragment, { children: part.text }, i);
|
|
@@ -1449,7 +1453,8 @@ var PRINT_ANSWER_FOLD = 1200;
|
|
|
1449
1453
|
var iso = (ms) => new Date(ms).toISOString();
|
|
1450
1454
|
var Text = ({ sentence }) => /* @__PURE__ */ jsx6(Fragment2, { children: sentence.parts.map((part, i) => {
|
|
1451
1455
|
if ("code" in part) return /* @__PURE__ */ jsx6("code", { children: part.code }, i);
|
|
1452
|
-
if ("quote" in part)
|
|
1456
|
+
if ("quote" in part)
|
|
1457
|
+
return /* @__PURE__ */ jsx6("span", { className: "lens-plain-quote", children: part.quote }, i);
|
|
1453
1458
|
if ("label" in part) return /* @__PURE__ */ jsx6("strong", { children: part.label }, i);
|
|
1454
1459
|
return /* @__PURE__ */ jsx6(React6.Fragment, { children: part.text }, i);
|
|
1455
1460
|
}) });
|
|
@@ -5448,4 +5453,4 @@ export {
|
|
|
5448
5453
|
useBookmarkSidecar,
|
|
5449
5454
|
Lens
|
|
5450
5455
|
};
|
|
5451
|
-
//# sourceMappingURL=chunk-
|
|
5456
|
+
//# sourceMappingURL=chunk-DBEVLCHX.js.map
|