@affiant/core 0.1.0-alpha.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.
Files changed (96) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +354 -0
  3. package/dist/context.d.ts +136 -0
  4. package/dist/context.d.ts.map +1 -0
  5. package/dist/context.js +30 -0
  6. package/dist/context.js.map +1 -0
  7. package/dist/docket/entry.d.ts +421 -0
  8. package/dist/docket/entry.d.ts.map +1 -0
  9. package/dist/docket/entry.js +155 -0
  10. package/dist/docket/entry.js.map +1 -0
  11. package/dist/docket/expiry.d.ts +82 -0
  12. package/dist/docket/expiry.d.ts.map +1 -0
  13. package/dist/docket/expiry.js +106 -0
  14. package/dist/docket/expiry.js.map +1 -0
  15. package/dist/docket/memory.d.ts +163 -0
  16. package/dist/docket/memory.d.ts.map +1 -0
  17. package/dist/docket/memory.js +528 -0
  18. package/dist/docket/memory.js.map +1 -0
  19. package/dist/docket/store.d.ts +387 -0
  20. package/dist/docket/store.d.ts.map +1 -0
  21. package/dist/docket/store.js +51 -0
  22. package/dist/docket/store.js.map +1 -0
  23. package/dist/errors.d.ts +153 -0
  24. package/dist/errors.d.ts.map +1 -0
  25. package/dist/errors.js +164 -0
  26. package/dist/errors.js.map +1 -0
  27. package/dist/gate/coverage.d.ts +152 -0
  28. package/dist/gate/coverage.d.ts.map +1 -0
  29. package/dist/gate/coverage.js +114 -0
  30. package/dist/gate/coverage.js.map +1 -0
  31. package/dist/gate/decide.d.ts +207 -0
  32. package/dist/gate/decide.d.ts.map +1 -0
  33. package/dist/gate/decide.js +559 -0
  34. package/dist/gate/decide.js.map +1 -0
  35. package/dist/gate/gate.d.ts +212 -0
  36. package/dist/gate/gate.d.ts.map +1 -0
  37. package/dist/gate/gate.js +175 -0
  38. package/dist/gate/gate.js.map +1 -0
  39. package/dist/gate/pipeline.d.ts +285 -0
  40. package/dist/gate/pipeline.d.ts.map +1 -0
  41. package/dist/gate/pipeline.js +515 -0
  42. package/dist/gate/pipeline.js.map +1 -0
  43. package/dist/gate/policy.d.ts +272 -0
  44. package/dist/gate/policy.d.ts.map +1 -0
  45. package/dist/gate/policy.js +396 -0
  46. package/dist/gate/policy.js.map +1 -0
  47. package/dist/gate/wrap.d.ts +107 -0
  48. package/dist/gate/wrap.d.ts.map +1 -0
  49. package/dist/gate/wrap.js +164 -0
  50. package/dist/gate/wrap.js.map +1 -0
  51. package/dist/index.d.ts +95 -0
  52. package/dist/index.d.ts.map +1 -0
  53. package/dist/index.js +111 -0
  54. package/dist/index.js.map +1 -0
  55. package/dist/model/affidavit.d.ts +354 -0
  56. package/dist/model/affidavit.d.ts.map +1 -0
  57. package/dist/model/affidavit.js +417 -0
  58. package/dist/model/affidavit.js.map +1 -0
  59. package/dist/model/amendments.d.ts +160 -0
  60. package/dist/model/amendments.d.ts.map +1 -0
  61. package/dist/model/amendments.js +183 -0
  62. package/dist/model/amendments.js.map +1 -0
  63. package/dist/model/canonical.d.ts +311 -0
  64. package/dist/model/canonical.d.ts.map +1 -0
  65. package/dist/model/canonical.js +665 -0
  66. package/dist/model/canonical.js.map +1 -0
  67. package/dist/model/money.d.ts +127 -0
  68. package/dist/model/money.d.ts.map +1 -0
  69. package/dist/model/money.js +177 -0
  70. package/dist/model/money.js.map +1 -0
  71. package/dist/model/provenance.d.ts +315 -0
  72. package/dist/model/provenance.d.ts.map +1 -0
  73. package/dist/model/provenance.js +223 -0
  74. package/dist/model/provenance.js.map +1 -0
  75. package/dist/ports.d.ts +269 -0
  76. package/dist/ports.d.ts.map +1 -0
  77. package/dist/ports.js +34 -0
  78. package/dist/ports.js.map +1 -0
  79. package/dist/store-memory.d.ts +21 -0
  80. package/dist/store-memory.d.ts.map +1 -0
  81. package/dist/store-memory.js +20 -0
  82. package/dist/store-memory.js.map +1 -0
  83. package/dist/telemetry-keys.d.ts +65 -0
  84. package/dist/telemetry-keys.d.ts.map +1 -0
  85. package/dist/telemetry-keys.js +72 -0
  86. package/dist/telemetry-keys.js.map +1 -0
  87. package/dist/telemetry.d.ts +77 -0
  88. package/dist/telemetry.d.ts.map +1 -0
  89. package/dist/telemetry.js +43 -0
  90. package/dist/telemetry.js.map +1 -0
  91. package/dist/testing.d.ts +574 -0
  92. package/dist/testing.d.ts.map +1 -0
  93. package/dist/testing.js +1291 -0
  94. package/dist/testing.js.map +1 -0
  95. package/package.json +75 -0
  96. package/telemetry-keys.json +92 -0
@@ -0,0 +1,515 @@
1
+ /**
2
+ * The gate pipeline: everything between a tool call and a Docket row, in the order
3
+ * the protocol fixes.
4
+ *
5
+ * **Rules served: GT-1** (the order itself), **GT-3** (runtime substance refusal),
6
+ * **GT-4** (TTL stamped from the policy result, after the chain; a re-file keeps the
7
+ * existing deadline), **PV-1** (confidence clamped, merge by confidence then
8
+ * determinism), **PV-3** (the inference step cannot mint `UserStated`), **AF-1**
9
+ * (every proposed field present, unknown provenance recorded as `Empty`), **AF-3**
10
+ * (create carries no previous values; update carries the key on every field),
11
+ * **AZ-1** (a Standing Order writes its attestation in the same operation as the
12
+ * filing), **AZ-4** (a requirement this version does not run is filed blocked),
13
+ * **CV-4** (a declared-uncovered tool's proposal is filed blocked), **SR-4** (the
14
+ * card names the protocol version it conforms to), **TL-1** (the events).
15
+ *
16
+ * ## The order, and why it is this order (GT-1)
17
+ *
18
+ * 1. **Turn context** arrives as a parameter. Nothing here reads a global, and the
19
+ * accumulators below are function-local, so two conversations interleaved in one
20
+ * isolate cannot see each other's fields (GT-2).
21
+ * 2. **Deterministic interceptors** first, because a value a host can look up is
22
+ * better evidence than a value a model can guess, and running them first means the
23
+ * merge in step 4 is comparing against something rather than filling a blank.
24
+ * 3. **One tool-free structured inference** against the *unmodified* turn. One,
25
+ * because a second pass over a turn a previous pass has already been told about is
26
+ * a model agreeing with itself. Tool-free, because a model that can call tools
27
+ * while being asked what a person said can go and find out.
28
+ * 4. **Merge** (PV-1): higher confidence wins, ties toward the more deterministic
29
+ * source, the loser kept in the chain so a card can show a reviewer that the model
30
+ * and the system of record disagreed.
31
+ * 5. **Projection**, then the Affidavit is built (AF-1, AF-3, AF-2).
32
+ * 6. **Substance refusal** (GT-3) — *before* the policy chain. A proposal that swears
33
+ * to nothing must not reach a policy that might approve it, and must not be filed,
34
+ * counted or broadcast.
35
+ * 7. **Policy** (AZ-4, PV-4, GT-5).
36
+ * 8. **TTL** (GT-4) — *after* the policy, because the deadline is part of what the
37
+ * policy decided, and a global default stamped before the chain is the
38
+ * non-conformant shape the rule names.
39
+ * 9. **File** (DK-1), idempotent by entry id.
40
+ *
41
+ * ## Entry ids are derived, not minted
42
+ *
43
+ * The id is a SHA-256 over the tenant, the conversation, the tool name and the
44
+ * canonical form of the operation and its arguments, laid out as a UUID. So a retry
45
+ * of the same call in the same conversation is the *same* entry: `store.file` returns
46
+ * the row that is already there, with its **existing** `expiresAt` (GT-4), and the
47
+ * card the model gets back is the card a reviewer is already looking at. A random id
48
+ * would file a second row for a retried call and start a second clock, which is the
49
+ * shape GT-4 names as wrong.
50
+ *
51
+ * A resubmission adds the id of the entry it supersedes to that material, so it is a
52
+ * different entry from the one it replaces (DK-1) and resubmitting the same expired
53
+ * entry twice is still one row.
54
+ *
55
+ * @packageDocumentation
56
+ */
57
+ import { newEntry } from "../docket/entry.js";
58
+ import { instantMs } from "../docket/expiry.js";
59
+ import { AffiantError } from "../errors.js";
60
+ import { buildAffidavit, isJsonValue, presentationToWire, toWire } from "../model/affidavit.js";
61
+ import { canonicalJson, sha256Hex } from "../model/canonical.js";
62
+ import { chainOf, merge, mintConversation, mintInferred, mintTag } from "../model/provenance.js";
63
+ import { coverageRefusedMarker } from "./coverage.js";
64
+ import { evaluatePolicies } from "./policy.js";
65
+ /**
66
+ * Run steps 2 through 9 for `proposal` in `ctx` and return the filed entry with its
67
+ * card.
68
+ *
69
+ * @throws AffiantError `"substance-refused"` when the proposal swears to nothing
70
+ * (GT-3). Nothing is filed, nothing is broadcast, and the refusal is on the
71
+ * telemetry port before the throw.
72
+ * @throws RangeError when a port hands back something that is not a JSON value, or
73
+ * an interceptor claims a field the operation does not propose. Neither is a
74
+ * refusal the gate hands back to a model: they are host programming errors,
75
+ * and an `AffiantError` code would invite a host to catch and continue.
76
+ */
77
+ export async function runPipeline(proposal, ctx, deps) {
78
+ const now = deps.clock.now();
79
+ const op = proposal.operation;
80
+ const proposed = new Set(op.fields);
81
+ const schemaByName = new Map((proposal.schema?.fields ?? []).map((entry) => [entry.name, entry]));
82
+ // Function-local, so nothing survives the call and nothing is shared between two
83
+ // interleaved conversations (GT-2).
84
+ const states = new Map();
85
+ /** Admit a tag and its value, merging by PV-1 and keeping the loser in the chain. */
86
+ const admit = (name, tag, value) => {
87
+ const state = states.get(name);
88
+ if (state === undefined) {
89
+ states.set(name, { chain: chainOf(tag), value });
90
+ return;
91
+ }
92
+ const chain = merge(state.chain, tag);
93
+ // `merge` returns the winner as `current`; identity tells us whose value is now
94
+ // in force without re-deciding the contest here.
95
+ states.set(name, { chain, value: chain.current === tag ? value : state.value });
96
+ };
97
+ if (proposal.preparedFields === null) {
98
+ // ---- step 2: deterministic interceptors (PV-2) -------------------------
99
+ for (const interceptor of deps.interceptors) {
100
+ const produced = await interceptor.resolve(op, ctx);
101
+ for (const [name, intercepted] of Object.entries(produced)) {
102
+ if (!proposed.has(name)) {
103
+ throw new RangeError(`AF-1: interceptor ${JSON.stringify(interceptor.name)} resolved field ` +
104
+ `${JSON.stringify(name)}, which operation ${op.kind} on ${op.entityType} does not ` +
105
+ `propose; a field the operation does not propose is absent from the Affidavit`);
106
+ }
107
+ // `InterceptedField.source` is `"External" | "Computed"`, so PV-3's other
108
+ // half — a host resolver cannot claim the person said it — is a type, not a
109
+ // check. A binding is required by the same type (PV-2).
110
+ admit(name, mintTag({
111
+ source: intercepted.source,
112
+ confidence: intercepted.confidence,
113
+ at: now,
114
+ note: intercepted.evidence,
115
+ binding: intercepted.binding,
116
+ }), requireJsonValue(intercepted.value, `interceptor ${interceptor.name} field ${name}`));
117
+ }
118
+ }
119
+ // ---- step 3: one tool-free structured inference; step 4: merge ---------
120
+ if (proposal.schema !== null) {
121
+ const inferred = await deps.inference.infer(ctx.turn, proposal.schema);
122
+ for (const [name, structured] of Object.entries(inferred.fields)) {
123
+ // A model naming a field the operation does not propose is the model being
124
+ // a model, not the host being wrong: the extra field is dropped, and AF-1
125
+ // still holds because the Affidavit is built from `op.fields`.
126
+ if (!proposed.has(name))
127
+ continue;
128
+ const value = requireJsonValue(structured.value, `inferred field ${name}`);
129
+ // PV-3: `mintConversation` and `mintInferred` are the only two mints reachable
130
+ // from here, and neither can name `UserStated` — the parameter type forbids it
131
+ // and the runtime guard in `mintInference` catches an untyped caller.
132
+ const tag = structured.presence === "literal"
133
+ ? mintConversation({
134
+ confidence: structured.confidence,
135
+ at: now,
136
+ note: `Literally present in the turn: ${name}`,
137
+ binding: await utteranceSpanBinding(ctx.turn.utterance, structured.utteranceSpan),
138
+ })
139
+ : mintInferred({
140
+ confidence: structured.confidence,
141
+ at: now,
142
+ note: `Inferred from the turn: ${name}`,
143
+ });
144
+ admit(name, tag, value);
145
+ }
146
+ }
147
+ }
148
+ else {
149
+ for (const prepared of proposal.preparedFields) {
150
+ if (!proposed.has(prepared.name)) {
151
+ throw new RangeError(`AF-1: prepared field ${JSON.stringify(prepared.name)} is not proposed by the ` +
152
+ `operation; a field the operation does not propose is absent from the Affidavit`);
153
+ }
154
+ if (prepared.provenance !== undefined) {
155
+ states.set(prepared.name, { chain: prepared.provenance, value: prepared.value });
156
+ }
157
+ }
158
+ }
159
+ // ---- step 5: projection, then the Affidavit (AF-1, AF-3, AF-2) -----------
160
+ // The port is consulted for an update only: AF-3 says a create carries
161
+ // `previousValue: null` on every field, and there is nothing for a host to look up
162
+ // for an entity that does not exist yet.
163
+ const previous = op.kind === "update" ? ((await deps.projection.previousValues(op, ctx)) ?? {}) : {};
164
+ const preparedByName = new Map((proposal.preparedFields ?? []).map((prepared) => [prepared.name, prepared]));
165
+ const inputs = op.fields.map((name) => {
166
+ const state = states.get(name);
167
+ const prepared = preparedByName.get(name);
168
+ const schemaEntry = schemaByName.get(name);
169
+ const previousValue = op.kind === "update"
170
+ ? requireJsonValue(previous[name] ?? null, `previous value of ${name}`)
171
+ : null;
172
+ return {
173
+ name,
174
+ kind: prepared?.kind ?? schemaEntry?.kind ?? "text",
175
+ value: state?.value ?? prepared?.value ?? null,
176
+ previousValue,
177
+ isMandatory: prepared?.isMandatory ?? schemaEntry?.required ?? false,
178
+ // Absent, not `undefined`: `buildAffidavit` reads the absence as "provenance
179
+ // unknown" and writes an `Empty` tag (AF-1).
180
+ ...(state === undefined ? {} : { provenance: state.chain }),
181
+ };
182
+ });
183
+ const affidavit = buildAffidavit(op, inputs, { createdAt: now });
184
+ // ---- step 6: runtime substance refusal (GT-3) ----------------------------
185
+ refuseHollow(affidavit, proposal, ctx, deps, now);
186
+ // ---- step 7: the policy chain (AZ-4, PV-4, GT-5) -------------------------
187
+ const outcome = await evaluatePolicies(deps.policies, affidavit, ctx, {
188
+ riskScorer: deps.riskScorer,
189
+ telemetry: deps.telemetry,
190
+ now,
191
+ });
192
+ // ---- step 8: TTL, from the policy result (GT-4) --------------------------
193
+ const ttlMs = outcome.ttlMs ?? deps.defaultTtlMs;
194
+ const expiresAt = new Date(instantMs(now, "clock.now()") + ttlMs).toISOString();
195
+ // ---- step 9: file (DK-1, AZ-1, AZ-4, CV-4) ------------------------------
196
+ const uncovered = deps.coverage.lookup(proposal.toolName);
197
+ const blocked = blockedMarker(proposal.toolName, uncovered, outcome.requirement);
198
+ // A blocked entry is never auto-approved: AZ-4 says a level the implementation does
199
+ // not run is filed `pending` and refuses every decision, and CV-4 says the same of a
200
+ // tool the host cannot cover. Both are a move *toward* a person, which is the
201
+ // direction AZ-4 permits.
202
+ const fires = outcome.requirement === "StandingOrder" && blocked === null;
203
+ const entryId = await deriveEntryId(ctx, proposal);
204
+ if (uncovered !== null) {
205
+ deps.telemetry.emit({
206
+ key: "coverage.refused",
207
+ at: now,
208
+ attributes: {
209
+ "gen_ai.tool.name": proposal.toolName,
210
+ "coverage.category": uncovered,
211
+ phase: "proposal",
212
+ },
213
+ });
214
+ }
215
+ const attestation = fires && outcome.policy !== null
216
+ ? {
217
+ by: {
218
+ kind: "standing-order",
219
+ policyId: outcome.policy.id,
220
+ version: outcome.policy.version,
221
+ },
222
+ at: now,
223
+ entryId,
224
+ }
225
+ : null;
226
+ const init = {
227
+ entryId,
228
+ tenantId: ctx.tenantId,
229
+ conversationId: ctx.conversationId,
230
+ channel: ctx.channel,
231
+ // On the row so a resubmission can re-run the coverage lookup against the tool
232
+ // that actually proposed the write (CV-4), and so an audit can name it.
233
+ toolName: proposal.toolName,
234
+ affidavit,
235
+ requirement: outcome.requirement,
236
+ filedAt: now,
237
+ expiresAt,
238
+ // DK-1: a resubmission names what it replaces on the way in. The successor link
239
+ // is written on the *other* row, by `resubmit`, after this filing succeeds.
240
+ ...(proposal.supersedes === null ? {} : { supersedes: proposal.supersedes }),
241
+ // A Standing Order writes status, execution outcome and attestation in the same
242
+ // operation as the filing (AZ-1) — never a file followed by an approve, which
243
+ // would leave a window in which an approved write had no attestation.
244
+ ...(attestation === null
245
+ ? {}
246
+ : { status: "approved", execution: "unexecuted", attestation }),
247
+ ...(blocked === null ? {} : { blocked }),
248
+ };
249
+ const { entry, created } = await deps.store.file(newEntry(init));
250
+ if (fires && outcome.policy !== null) {
251
+ deps.telemetry.emit({
252
+ key: "standing-order.fired",
253
+ at: now,
254
+ attributes: {
255
+ "policy.id": outcome.policy.id,
256
+ "policy.version": outcome.policy.version,
257
+ "entry.id": entry.entryId,
258
+ "risk.score": outcome.riskScore,
259
+ },
260
+ });
261
+ }
262
+ deps.telemetry.emit({
263
+ key: "affidavit.filed",
264
+ at: now,
265
+ attributes: {
266
+ "gen_ai.tool.name": proposal.toolName,
267
+ "gen_ai.conversation.id": ctx.conversationId,
268
+ "entry.id": entry.entryId,
269
+ "docket.requirement": entry.requirement,
270
+ "docket.status": entry.status,
271
+ "affidavit.field_count": entry.affidavit.fields.length,
272
+ created,
273
+ },
274
+ });
275
+ return { entry, created, card: evidenceCard(entry, proposal, outcome) };
276
+ }
277
+ // ---------------------------------------------------------------------------
278
+ // Step 6 — substance (GT-3)
279
+ // ---------------------------------------------------------------------------
280
+ /**
281
+ * Refuse a proposal that swears to nothing: no field carrying provenance other than
282
+ * `Empty`, or a non-empty value sitting under an `Empty` tag (GT-3).
283
+ *
284
+ * The hollow case is checked first because it is the more specific diagnosis — an
285
+ * all-`Empty` Affidavit with values in it satisfies both descriptions, and "you filled
286
+ * in a value and told me nothing about where it came from" is the more useful thing to
287
+ * say.
288
+ *
289
+ * A value counts as empty when it is `null` or a string that is blank. `0` and `false`
290
+ * are values somebody meant, and a field carrying one under an `Empty` tag is exactly
291
+ * the hollow shape the rule is about.
292
+ */
293
+ function refuseHollow(affidavit, proposal, ctx, deps, now) {
294
+ const hollow = affidavit.fields.find((field) => field.provenance.current.source === "Empty" && !isEmptyValue(field.value));
295
+ const reason = hollow !== undefined
296
+ ? `field ${JSON.stringify(hollow.name)} carries a value with Empty provenance`
297
+ : affidavit.fields.every((field) => field.provenance.current.source === "Empty")
298
+ ? "no proposed field carries provenance other than Empty"
299
+ : null;
300
+ if (reason === null)
301
+ return;
302
+ deps.telemetry.emit({
303
+ key: "affidavit.refused.substance",
304
+ at: now,
305
+ attributes: {
306
+ "gen_ai.tool.name": proposal.toolName,
307
+ "gen_ai.conversation.id": ctx.conversationId,
308
+ "affidavit.field_count": affidavit.fields.length,
309
+ reason,
310
+ },
311
+ });
312
+ throw new AffiantError("substance-refused", `GT-3: this proposal swears to nothing — ${reason}. It is not filed, not counted and ` +
313
+ `not broadcast.`, { toolName: proposal.toolName, reason, entityType: affidavit.entityType });
314
+ }
315
+ /** Whether `value` is the absence of a value: `null`, or a string with nothing in it. */
316
+ function isEmptyValue(value) {
317
+ if (value === null)
318
+ return true;
319
+ return typeof value === "string" && value.trim() === "";
320
+ }
321
+ // ---------------------------------------------------------------------------
322
+ // Step 9 — the row and the card
323
+ // ---------------------------------------------------------------------------
324
+ /**
325
+ * The AZ-4 marker the entry is filed with, or `null` when it can be decided.
326
+ *
327
+ * Coverage comes first: a tool the host cannot intercept is the more fundamental
328
+ * problem, and its category is the more useful thing on the row.
329
+ */
330
+ function blockedMarker(toolName, uncovered, requirement) {
331
+ if (uncovered !== null)
332
+ return coverageRefusedMarker(toolName, uncovered);
333
+ if (requirement === "MultiParty" || requirement === "ReferralRequired") {
334
+ // Recorded verbatim (AZ-4): the row says what was asked for, and no code path
335
+ // turns it into the weaker requirement this version does know how to run.
336
+ return { code: "requirement-not-implemented", level: requirement };
337
+ }
338
+ return null;
339
+ }
340
+ /** The card a host delivers, built from the **stored** entry (GT-4) and the wire carry. */
341
+ function evidenceCard(entry, proposal, outcome) {
342
+ // AF-2's three numbers come off the stored Affidavit, so the card and the record
343
+ // can never disagree about them: all three ride the wire Affidavit, and two of
344
+ // them are repeated on the envelope for the one version the superseded wire's
345
+ // consumers are still reading.
346
+ const sworn = entry.amendedAffidavit ?? entry.affidavit;
347
+ const carry = wireCarry(entry, proposal, outcome);
348
+ return {
349
+ protocolVersion: entry.protocolVersion,
350
+ docketId: entry.entryId,
351
+ // The record's own version, not the row's envelope tag (SR-4). SR-1's canonical
352
+ // form is over the Affidavit as the schema defines it, `protocolVersion`
353
+ // included, so re-stamping the record on the way onto the card would produce a
354
+ // document whose hash is not the row's `canonicalHash` — the substitution the
355
+ // form exists to make impossible. The two are the same value on every path a
356
+ // host takes; they differ only where a caller pinned the row to another tag,
357
+ // and then it is the envelope that carries the pin, not the sworn record.
358
+ affidavit: toWire(sworn),
359
+ requiredBy: entry.expiresAt,
360
+ priorAmendments: proposal.priorAmendments ?? entry.preservedAmendments?.amendments ?? null,
361
+ populatedConfidence: sworn.populatedConfidence,
362
+ emptyFieldCount: sworn.emptyFieldCount,
363
+ blocked: entry.blocked,
364
+ ...presentationToWire(carry),
365
+ requiresConfirmation: carry.requiresConfirmation,
366
+ };
367
+ }
368
+ /**
369
+ * The presentation the core does not own: the sentences a reviewer should see,
370
+ * whether a person must confirm, the reviewer surface's per-field rendering hints,
371
+ * and the host's own verb for the operation.
372
+ */
373
+ function wireCarry(entry, proposal, outcome) {
374
+ const warnings = [];
375
+ if (outcome.reason !== null)
376
+ warnings.push(outcome.reason);
377
+ if (entry.blocked?.code === "coverage-refused") {
378
+ warnings.push(`CV-4: ${JSON.stringify(proposal.toolName)} is declared uncovered ` +
379
+ `(${String(entry.blocked.category)}); this proposal is on the record and cannot be ` +
380
+ `approved through the gate.`);
381
+ }
382
+ if (entry.blocked?.code === "requirement-not-implemented") {
383
+ warnings.push(`AZ-4: ${String(entry.blocked.level)} approval is not implemented in this version; the ` +
384
+ `entry is blocked and no decision on it will be accepted.`);
385
+ }
386
+ // One entry per field the host declared something about, naming a field the
387
+ // Affidavit carries — a hint for a field the record does not carry would render
388
+ // a control over nothing. A field the host said nothing about gets no entry at
389
+ // all, rather than an entry full of nulls: absence is how the wire spells "no
390
+ // hint, render from the field's own kind".
391
+ const presentation = [];
392
+ const schemaByName = new Map((proposal.schema?.fields ?? []).map((entry_) => [entry_.name, entry_]));
393
+ for (const field of (entry.amendedAffidavit ?? entry.affidavit).fields) {
394
+ const declared = schemaByName.get(field.name);
395
+ const allowedValues = declared?.allowedValues ?? null;
396
+ // Carried from the host's field schema, never invented here: the reviewer
397
+ // surface renders it as an input constraint and the gate validates nothing
398
+ // against it.
399
+ const pattern = declared?.pattern ?? null;
400
+ if (allowedValues === null && pattern === null)
401
+ continue;
402
+ presentation.push({
403
+ name: field.name,
404
+ kind: field.kind,
405
+ ...(allowedValues === null ? {} : { allowedValues }),
406
+ ...(pattern === null ? {} : { pattern }),
407
+ });
408
+ }
409
+ return {
410
+ warnings,
411
+ // A blocked entry sits in `pending` and refuses every decision (AZ-4, CV-4), so
412
+ // it is not a card a person can confirm. Saying `true` here would offer a
413
+ // reviewer surface an approve button that cannot work, on the same card that
414
+ // carries a warning saying no decision will be accepted.
415
+ requiresConfirmation: entry.status === "pending" && entry.blocked === null,
416
+ presentation,
417
+ // The host's word for what it is doing, carried onto the card so a reviewer
418
+ // surface can head the card with the verb a person recognises rather than with
419
+ // the protocol's two-valued shape. It comes from this filing, like the hints
420
+ // beside it — a resubmission builds its proposal from the row, which swears to
421
+ // the evidence and not to how the host labels it, so a resubmitted card carries
422
+ // neither until the host supplies them again.
423
+ hostOperation: proposal.operationLabel,
424
+ };
425
+ }
426
+ // ---------------------------------------------------------------------------
427
+ // Entry ids
428
+ // ---------------------------------------------------------------------------
429
+ /**
430
+ * The entry id for this proposal: a SHA-256 over the tenant, the conversation, the
431
+ * tool and the canonical form of the operation and its arguments, laid out as a UUID.
432
+ *
433
+ * The layout sets the version nibble to `8` and the variant bits to `10`, which RFC
434
+ * 9562 reserves for exactly this — a UUID whose bits are a hash an application chose.
435
+ * The shape matters because `docketId` is a UUID string on the wire; the determinism
436
+ * matters because it is what makes a retried tool call a replay rather than a second
437
+ * review (GT-4, DK-1).
438
+ *
439
+ * @throws TypeError if `args` contains something with no canonical form — a function,
440
+ * a symbol, a cycle. Tool arguments are JSON; anything else is a caller bug.
441
+ */
442
+ export async function deriveEntryId(ctx, proposal) {
443
+ const material = canonicalJson({
444
+ tenantId: ctx.tenantId,
445
+ conversationId: ctx.conversationId,
446
+ toolName: proposal.toolName,
447
+ operation: proposal.operation,
448
+ args: proposal.args ?? null,
449
+ // Only when there is one, so a first filing's id is exactly what it was before
450
+ // resubmission existed, and a retry of the original call is still a replay.
451
+ ...(proposal.supersedes === null ? {} : { supersedes: proposal.supersedes }),
452
+ });
453
+ const digest = await sha256Hex(new TextEncoder().encode(material));
454
+ return uuidFromDigest(digest);
455
+ }
456
+ /** Lay 128 bits of `digest` out as a UUID with version 8 and the RFC 9562 variant. */
457
+ function uuidFromDigest(digest) {
458
+ const nibbles = [...digest.slice(0, 32)];
459
+ nibbles[12] = "8";
460
+ nibbles[16] = "89ab"[Number.parseInt(nibbles[16] ?? "0", 16) % 4] ?? "8";
461
+ const hex = nibbles.join("");
462
+ return [
463
+ hex.slice(0, 8),
464
+ hex.slice(8, 12),
465
+ hex.slice(12, 16),
466
+ hex.slice(16, 20),
467
+ hex.slice(20, 32),
468
+ ].join("-");
469
+ }
470
+ // ---------------------------------------------------------------------------
471
+ // Bindings and values
472
+ // ---------------------------------------------------------------------------
473
+ /**
474
+ * The `utterance-span` binding for a value the port reported as literally present
475
+ * (PV-2), or `null` when there is no span or the span does not fit the turn.
476
+ *
477
+ * The hash is a SHA-256 of the span's own text, so an auditor holding the turn can
478
+ * re-derive it and see that the pointer still points where it did. A span that runs
479
+ * past the end of the utterance, or reads backwards, is not evidence: the binding is
480
+ * dropped and the tag stays `Conversation` with nothing behind it, which PV-4 then
481
+ * treats as unbound — the honest outcome.
482
+ */
483
+ async function utteranceSpanBinding(utterance, span) {
484
+ if (span === null)
485
+ return null;
486
+ if (!Number.isInteger(span.start) || !Number.isInteger(span.end))
487
+ return null;
488
+ if (span.start < 0 || span.end < span.start || span.end > utterance.length)
489
+ return null;
490
+ const text = utterance.slice(span.start, span.end);
491
+ return {
492
+ kind: "utterance-span",
493
+ ref: {
494
+ offset: span.start,
495
+ length: span.end - span.start,
496
+ hash: await sha256Hex(new TextEncoder().encode(text)),
497
+ },
498
+ };
499
+ }
500
+ /**
501
+ * `value` as a JSON value.
502
+ *
503
+ * @throws RangeError when a port hands back something with no JSON form. A port
504
+ * contract violation is a host programming error rather than a refusal, and
505
+ * letting it through would put an unserializable value on a record whose
506
+ * whole purpose is to be read back later.
507
+ */
508
+ function requireJsonValue(value, where) {
509
+ if (!isJsonValue(value)) {
510
+ throw new RangeError(`${where} is not a JSON value (${typeof value}); every value on an Affidavit must ` +
511
+ `survive serialization`);
512
+ }
513
+ return value;
514
+ }
515
+ //# sourceMappingURL=pipeline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../../src/gate/pipeline.ts"],"names":[],"mappings":"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"}