@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 @@
1
+ {"version":3,"file":"provenance.d.ts","sourceRoot":"","sources":["../../src/model/provenance.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,223 @@
1
+ /**
2
+ * Provenance: the seven-source ladder, the tag, the binding that makes a tag
3
+ * checkable, the chain that keeps every superseded tag, and the merge rule.
4
+ *
5
+ * **Rules served: PV-1** (the ladder, the chain, confidence-first /
6
+ * determinism-second merge, confidence clamped into `[0, 1]`), **PV-2** (a tag
7
+ * above `Conversation` carries a binding, and the binding kinds are a fixed set),
8
+ * **PV-3** (an implementation's own inference never mints `UserStated`), **PV-5**
9
+ * (no wire type raises a grade: an asserted grade above `Conversation` with no
10
+ * binding is carried on the record but is not honourable).
11
+ *
12
+ * The idea in one paragraph: a value on an Affidavit is worth exactly what its
13
+ * evidence is worth. A provenance tag says where the value came from
14
+ * ({@link ProvenanceSource}), how confident its producer was, and — for the grades
15
+ * that claim more than "a model read it in the conversation" — a {@link Binding}:
16
+ * a pointer at something an auditor can go and check years later. A tag with no
17
+ * binding is not a lie, it is a weaker claim, and the framework's job is to keep
18
+ * the difference visible rather than to average it away.
19
+ *
20
+ * Nothing here reads a clock. Every function that stamps a time takes the instant
21
+ * as a parameter, so a fixture can pin it (RT-1, and the same reason the clock is
22
+ * a port rather than a call to `Date.now()`).
23
+ *
24
+ * @packageDocumentation
25
+ */
26
+ // ---------------------------------------------------------------------------
27
+ // The ladder (PV-1)
28
+ // ---------------------------------------------------------------------------
29
+ /**
30
+ * The seven provenance sources, **most deterministic first**.
31
+ *
32
+ * This order is not a preference, it is the tie-breaker: when two tags carry equal
33
+ * confidence the one nearer the front of this list wins the merge (PV-1). Read it
34
+ * as a claim about who could re-derive the value — the person said it; a system of
35
+ * record holds it; a named rule computes it; it was literally present in the
36
+ * conversation; a model reasoned to it; a default filled it in; nobody knows.
37
+ *
38
+ * Spelled out here rather than re-exported from `@affiant/contract` so the gate's
39
+ * ordering is a fact of the gate. `test/provenance.test.ts` asserts the two lists
40
+ * are identical, which is what keeps them from drifting apart.
41
+ */
42
+ export const PROVENANCE_LADDER = [
43
+ "UserStated",
44
+ "External",
45
+ "Computed",
46
+ "Conversation",
47
+ "Inferred",
48
+ "Default",
49
+ "Empty",
50
+ ];
51
+ /** Rank by position in {@link PROVENANCE_LADDER}, computed once. */
52
+ const RANK = Object.freeze(Object.fromEntries(PROVENANCE_LADDER.map((source, index) => [source, index])));
53
+ /**
54
+ * How deterministic `source` is: `0` for `UserStated`, `6` for `Empty`.
55
+ *
56
+ * **Lower is more deterministic.** The number is an index into
57
+ * {@link PROVENANCE_LADDER}, so it is a comparison key and nothing else — never a
58
+ * score, never a weight, never something to multiply a confidence by.
59
+ */
60
+ export function determinismRank(source) {
61
+ return RANK[source];
62
+ }
63
+ /**
64
+ * Whether a tag with this source must carry a {@link Binding} to be worth its grade
65
+ * (PV-2): the three sources **above** `Conversation` — `UserStated`, `External`,
66
+ * `Computed`.
67
+ *
68
+ * At or below `Conversation` the grade already says "this came from the turn, or
69
+ * from a model reading the turn", and the turn is itself the artifact. Above it,
70
+ * the tag claims an artifact outside the conversation, and a claim with no pointer
71
+ * at that artifact is not checkable — see {@link isBound} and PV-4, where the pair
72
+ * decides whether a person-free approval may rest on the tag.
73
+ */
74
+ export function requiresBinding(source) {
75
+ return determinismRank(source) < determinismRank("Conversation");
76
+ }
77
+ /** Every {@link Binding} kind, as data. */
78
+ export const BINDING_KINDS = [
79
+ "utterance-span",
80
+ "reviewer-act",
81
+ "form-input",
82
+ "external-ref",
83
+ "computation-ref",
84
+ ];
85
+ /**
86
+ * Clamp a producer-reported confidence into `[0, 1]` (PV-1).
87
+ *
88
+ * `NaN` becomes `0`: a number that is not a number is not a claim, and the shipped
89
+ * .NET inference step floors at 0 without capping, which is the defect this closes.
90
+ */
91
+ function clampConfidence(confidence) {
92
+ if (Number.isNaN(confidence))
93
+ return 0;
94
+ if (confidence < 0)
95
+ return 0;
96
+ if (confidence > 1)
97
+ return 1;
98
+ return confidence;
99
+ }
100
+ /**
101
+ * Mint a tag for any source, clamping the confidence into `[0, 1]` (PV-1).
102
+ *
103
+ * A tag whose source is `Empty` is forced to confidence `0`: "nobody knows where
104
+ * this came from" cannot also be a confident claim, and AF-2 counts every `Empty`
105
+ * field as `0` in the aggregate anyway — forcing it here means the two can never
106
+ * disagree.
107
+ *
108
+ * This is the general minting surface, used by deterministic interceptors, by the
109
+ * projection step and by a reviewer's amendment. **It is not the surface the
110
+ * inference step gets:** PV-3 forbids an implementation's own inference from
111
+ * minting `UserStated`, so the inference step is handed {@link mintInference},
112
+ * whose source parameter is typed {@link InferenceSource} and cannot name it.
113
+ */
114
+ export function mintTag(options) {
115
+ const confidence = options.source === "Empty" ? 0 : clampConfidence(options.confidence);
116
+ return {
117
+ source: options.source,
118
+ confidence,
119
+ note: options.note ?? null,
120
+ at: options.at,
121
+ conversationTurn: options.conversationTurn ?? null,
122
+ binding: options.binding ?? null,
123
+ };
124
+ }
125
+ /**
126
+ * Mint a tag from the inference step. The source parameter is
127
+ * {@link InferenceSource}, so `UserStated` is a compile error here (PV-3).
128
+ *
129
+ * The runtime guard exists for callers with no type-checker — a JavaScript host, a
130
+ * value cast at the boundary — because PV-3 is a rule about what the record may
131
+ * say, not about what TypeScript can see.
132
+ *
133
+ * @throws RangeError if `source` is anything but `Conversation` or `Inferred`.
134
+ */
135
+ export function mintInference(source, options) {
136
+ if (source !== "Conversation" && source !== "Inferred") {
137
+ throw new RangeError(`PV-3: inference may mint only "Conversation" or "Inferred", not ${JSON.stringify(source)}; ` +
138
+ `"UserStated" is an observation of a person's act, never the host vouching for its own value`);
139
+ }
140
+ return mintTag({ ...options, source });
141
+ }
142
+ /** {@link mintInference} with source `Conversation`: the value was literally in the turn. */
143
+ export function mintConversation(options) {
144
+ return mintInference("Conversation", options);
145
+ }
146
+ /** {@link mintInference} with source `Inferred`: the model reasoned to the value. */
147
+ export function mintInferred(options) {
148
+ return mintInference("Inferred", options);
149
+ }
150
+ /**
151
+ * The tag a field carries when nobody knows where its value came from: source
152
+ * `Empty`, confidence `0` (AF-1 — present and tagged, never omitted).
153
+ */
154
+ export function emptyTag(at, note = null) {
155
+ return mintTag({ source: "Empty", confidence: 0, at, note });
156
+ }
157
+ /** Whether `tag` points at something an auditor can check (PV-2). */
158
+ export function isBound(tag) {
159
+ return tag.binding !== null && tag.binding !== undefined;
160
+ }
161
+ /**
162
+ * Whether `tag`'s grade is one a person-free verdict may rest on: either the grade
163
+ * needs no binding, or it has one (PV-4, PV-5).
164
+ *
165
+ * The unhonourable case is exactly the one PV-5 names: a caller asserts
166
+ * `UserStated` on the wire and points at nothing. The tag is still recorded — the
167
+ * record says what the caller claimed — but a Standing Order that predicates on it
168
+ * falls back to asking a person.
169
+ */
170
+ export function isHonourable(tag) {
171
+ return !requiresBinding(tag.source) || isBound(tag);
172
+ }
173
+ // ---------------------------------------------------------------------------
174
+ // Chains and the merge rule (PV-1)
175
+ // ---------------------------------------------------------------------------
176
+ /** A fresh chain holding one tag and no history. */
177
+ export function chainOf(tag) {
178
+ return { current: tag, prior: [] };
179
+ }
180
+ /**
181
+ * Whether `challenger` beats `incumbent`: higher confidence first, ties broken
182
+ * toward the more deterministic source (PV-1).
183
+ *
184
+ * An exact tie — same confidence, same source — leaves the incumbent in force. It
185
+ * was there first and the challenger brings nothing new; the challenger is still
186
+ * preserved in the chain, so the fact that two producers agreed is on the record.
187
+ */
188
+ function beats(challenger, incumbent) {
189
+ if (challenger.confidence !== incumbent.confidence) {
190
+ return challenger.confidence > incumbent.confidence;
191
+ }
192
+ return determinismRank(challenger.source) < determinismRank(incumbent.source);
193
+ }
194
+ /**
195
+ * Merge `incoming` into `chain` (PV-1): the higher confidence wins, ties break
196
+ * toward the more deterministic source, **and the loser is preserved** at the head
197
+ * of `prior`.
198
+ *
199
+ * This is the step where a deterministic interceptor's `External` value displaces
200
+ * a model's guess, or fails to. Either way both tags survive, so a card can show a
201
+ * reviewer that the model said one thing and the system of record said another.
202
+ */
203
+ export function merge(chain, incoming) {
204
+ if (beats(incoming, chain.current)) {
205
+ return { current: incoming, prior: [chain.current, ...chain.prior] };
206
+ }
207
+ return { current: chain.current, prior: [incoming, ...chain.prior] };
208
+ }
209
+ /**
210
+ * Put `tag` in force unconditionally, pushing the tag it displaces onto `prior`.
211
+ *
212
+ * Not a merge: a reviewer's amendment is not a confidence contest it might lose
213
+ * (AF-4, PV-2). When a person corrects a field, their act is the provenance of the
214
+ * new value even if the machine was more sure of the old one.
215
+ */
216
+ export function supersede(chain, tag) {
217
+ return { current: tag, prior: [chain.current, ...chain.prior] };
218
+ }
219
+ /** Every tag in `chain`, in force first and then oldest-displaced last. */
220
+ export function tagsOf(chain) {
221
+ return [chain.current, ...chain.prior];
222
+ }
223
+ //# sourceMappingURL=provenance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provenance.js","sourceRoot":"","sources":["../../src/model/provenance.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,269 @@
1
+ /**
2
+ * The ports a host supplies. Types only — this module has no runtime behaviour
3
+ * beyond {@link defaultClock}.
4
+ *
5
+ * **Rules served: GT-1** (the pipeline runs in protocol order, and every step it
6
+ * cannot do itself is a port), **GT-5** (a Standing Order that declares a risk
7
+ * threshold is compared against a host-supplied scorer), **AZ-2** (decision
8
+ * authorization is the host's answer, and the gate fails closed on it), **CV-1**
9
+ * (a port the gate needs and does not have is a wire-up failure, not a runtime
10
+ * surprise), **GT-2** (every port method that needs to know who is asking is
11
+ * handed the {@link TurnContext}; none of them may go looking).
12
+ *
13
+ * The shape of this file is the framework's central claim: **the core ships no
14
+ * model client, no scoring formula, no executor and no store.** It decides *what
15
+ * must be sworn to and who must agree*, and it asks the host for everything else.
16
+ * That is what lets one gate sit in front of any model, any database and any
17
+ * approval surface — and it is why a host cannot accidentally end up with a gate
18
+ * that scores its own risk or executes its own writes.
19
+ *
20
+ * @packageDocumentation
21
+ */
22
+ import type { Principal, TurnContext, Turn } from "./context.js";
23
+ import type { DocketEntry } from "./docket/entry.js";
24
+ import type { Affidavit, JsonValue } from "./model/affidavit.js";
25
+ import type { InterceptorBinding } from "./model/provenance.js";
26
+ export type { TelemetryPort, TelemetryEvent, TelemetryAttributes } from "./telemetry.js";
27
+ /**
28
+ * The bindings a deterministic interceptor may mint, re-exported from the model.
29
+ *
30
+ * The type lives in `model/provenance.ts` with the other four binding kinds (PV-2);
31
+ * it is re-exported here because an interceptor is a port, and a host writing one
32
+ * should not have to know which module the binding came from.
33
+ */
34
+ export type { InterceptorBinding };
35
+ /**
36
+ * The write being proposed, named the way the host names it.
37
+ *
38
+ * `create` carries no `entityId` because none exists yet; `update` always carries
39
+ * one. That is the distinction the projection step turns into `previousValue:
40
+ * null` on every field of a create (AF-3), so it is spelled as a discriminated
41
+ * union rather than a nullable string a caller could get wrong.
42
+ */
43
+ export type Operation = {
44
+ /** A new entity. */
45
+ readonly kind: "create";
46
+ /** The kind of domain entity being written, named by the host. */
47
+ readonly entityType: string;
48
+ /** Always `null` for a create — no identifier exists yet. */
49
+ readonly entityId: null;
50
+ /** The names of the fields being proposed. */
51
+ readonly fields: readonly string[];
52
+ } | {
53
+ /** An existing entity. */
54
+ readonly kind: "update";
55
+ /** The kind of domain entity being written, named by the host. */
56
+ readonly entityType: string;
57
+ /** The identifier of the entity being written. Never `null` for an update. */
58
+ readonly entityId: string;
59
+ /** The names of the fields being proposed. */
60
+ readonly fields: readonly string[];
61
+ };
62
+ /**
63
+ * What a single field is, as far as the inference port needs to know: enough to ask
64
+ * a model for a value and to reject one that does not fit.
65
+ *
66
+ * `kind` is the wire's rendering hint, reused here so the description a model is
67
+ * given and the control a reviewer sees cannot drift apart.
68
+ */
69
+ export interface FieldSchemaEntry {
70
+ /** The field's name on the target entity. The key everything else is keyed by. */
71
+ readonly name: string;
72
+ /** What sort of value this is. */
73
+ readonly kind: "text" | "number" | "date" | "enum";
74
+ /** What the field means, for the model and for the reviewer. `null` when the name says it. */
75
+ readonly description: string | null;
76
+ /** Whether the target entity requires the field. */
77
+ readonly required: boolean;
78
+ /** The closed set a value must come from when {@link FieldSchemaEntry.kind} is `"enum"`; `null` otherwise. */
79
+ readonly allowedValues: readonly string[] | null;
80
+ /**
81
+ * The regular expression a reviewer surface constrains the amendment input with,
82
+ * or `null` for no constraint.
83
+ *
84
+ * The wire Affidavit carries a `pattern` per field and `@affiant/evidence-card`
85
+ * sets it as the amendment input's `pattern` attribute, so without a way for a
86
+ * host to say what the pattern is the slot could never be filled by anything the
87
+ * gate produced. It is a presentation constraint, not sworn substance: the gate
88
+ * carries it onto the card and never validates a value against it.
89
+ */
90
+ readonly pattern: string | null;
91
+ }
92
+ /** The fields one inference call is asked to fill, and the entity they belong to. */
93
+ export interface FieldSchema {
94
+ /** The kind of domain entity being written. */
95
+ readonly entityType: string;
96
+ /** The fields to extract, in the order the host declared them. */
97
+ readonly fields: readonly FieldSchemaEntry[];
98
+ }
99
+ /** Where in the utterance a value was found, as character offsets into {@link Turn.utterance}. */
100
+ export interface UtteranceSpan {
101
+ /** Inclusive start offset. */
102
+ readonly start: number;
103
+ /** Exclusive end offset. */
104
+ readonly end: number;
105
+ }
106
+ /** One field an inference port filled in. */
107
+ export interface StructuredField {
108
+ /** The extracted value. Any JSON value, including `null`. */
109
+ readonly value: JsonValue;
110
+ /**
111
+ * How confident the port is, `0.0` to `1.0`. The pipeline clamps whatever
112
+ * arrives into that range rather than trusting it (PV-1).
113
+ */
114
+ readonly confidence: number;
115
+ /**
116
+ * Whether the value is literally present in the utterance (`"literal"`, tagged
117
+ * `Conversation`) or was reasoned to (`"inferred"`, tagged `Inferred`). The
118
+ * distinction is provenance, not confidence: a reviewer reads them differently.
119
+ */
120
+ readonly presence: "literal" | "inferred";
121
+ /**
122
+ * Where in the utterance the value was found, when the port can say. `null` when
123
+ * it cannot — the pipeline then records the tag without an `utterance-span`
124
+ * binding rather than inventing offsets.
125
+ */
126
+ readonly utteranceSpan: UtteranceSpan | null;
127
+ }
128
+ /** What one inference call returns: the fields it could fill, keyed by name. */
129
+ export interface StructuredResult {
130
+ /** The filled fields. A field the port could not fill is absent, not `null`. */
131
+ readonly fields: {
132
+ readonly [fieldName: string]: StructuredField;
133
+ };
134
+ }
135
+ /**
136
+ * One tool-free structured extraction over the unmodified turn.
137
+ *
138
+ * "Tool-free" is the point: the gate asks the model for *values*, never for an
139
+ * action, so nothing the model returns can execute. The host owns the model
140
+ * client, the prompt and the cost.
141
+ */
142
+ export interface InferencePort {
143
+ /**
144
+ * Extract `schema`'s fields from `turn`, verbatim as the host received it.
145
+ *
146
+ * @param turn The turn, unmodified — same object as `ctx.turn`.
147
+ * @param schema The fields to fill.
148
+ */
149
+ infer(turn: Turn, schema: FieldSchema): Promise<StructuredResult>;
150
+ }
151
+ /**
152
+ * What the target entity holds *now*, so the Affidavit can swear to what a write
153
+ * would replace rather than only to what it would set.
154
+ *
155
+ * The gate never reads the host's database itself; a card that shows "was £40,
156
+ * becomes £4,000" only exists because the host answered this.
157
+ */
158
+ export interface ProjectionPort {
159
+ /**
160
+ * The current values of `op.fields` on the entity `op` names.
161
+ *
162
+ * @returns A map keyed by field name, or `null` when there is nothing to project
163
+ * — a create, or an entity that no longer exists. A field the host
164
+ * cannot supply is absent from the map, which is not the same as `null`
165
+ * under its key (`null` means "the field is currently empty").
166
+ */
167
+ previousValues(op: Operation, ctx: TurnContext): Promise<Record<string, JsonValue> | null>;
168
+ }
169
+ /**
170
+ * Whether this principal may decide this entry. The host's answer, and the gate
171
+ * fails closed on it (AZ-2).
172
+ *
173
+ * The gate has already refused an unresolved principal and a cross-tenant entry
174
+ * before it asks; this port answers the host's own question — role, ownership,
175
+ * separation of duties. A port that throws is a refusal, never an approval.
176
+ */
177
+ export interface AuthorizationPort {
178
+ /** Whether `principal` may decide `entry`. */
179
+ mayDecide(principal: Principal, entry: DocketEntry): Promise<boolean>;
180
+ }
181
+ /**
182
+ * How risky this write is, on the host's own scale.
183
+ *
184
+ * There is no default formula, deliberately: a number the framework invented would
185
+ * be compared against a threshold the operator chose, and the operator would have
186
+ * no way to know what they had agreed to. A policy that declares a threshold with
187
+ * no scorer wired is a wire-up failure (`wireup-invalid`, CV-1), not a policy that
188
+ * quietly never fires.
189
+ */
190
+ export interface RiskScorer {
191
+ /** Score `affidavit`. The scale is the host's; the policy's threshold is on the same scale (GT-5). */
192
+ score(affidavit: Affidavit, ctx: TurnContext): Promise<number>;
193
+ }
194
+ /**
195
+ * Where "now" comes from.
196
+ *
197
+ * A port rather than a call to `Date.now()` inside the gate, for two reasons: a
198
+ * fixture has to be able to pin an expiry to the millisecond, and the core owns no
199
+ * timer of its own (DK-3) — expiry is state the host sweeps, not a callback the
200
+ * gate schedules.
201
+ */
202
+ export interface Clock {
203
+ /** The current instant, as an ISO 8601 string in UTC. */
204
+ now(): string;
205
+ }
206
+ /**
207
+ * The clock used when a host supplies none: the Web-standard `Date`, formatted as
208
+ * an ISO 8601 instant in UTC.
209
+ *
210
+ * `Date` and `toISOString` are ECMAScript, present on Node, Bun and workerd alike
211
+ * (RT-1). No Node API, no timer, no interval — one reading, on demand.
212
+ */
213
+ export declare const defaultClock: Clock;
214
+ /**
215
+ * The binding that makes a deterministic value checkable: which external record or
216
+ * computation the value came from.
217
+ *
218
+ * PV-4 is why it is mandatory on an {@link InterceptedField} rather than optional:
219
+ * a Standing Order — an approval with no person present — is honoured only if every
220
+ * provenance input the policy declares carries a binding. An `External` value with
221
+ * no binding is a claim nobody can re-derive, so a policy that would auto-approve
222
+ * on it falls back to asking a person.
223
+ *
224
+ * {@link InterceptorBinding} is the two-kind restriction of the model's `Binding`
225
+ * union: `external-ref` (a system of record) and `computation-ref` (a named,
226
+ * re-runnable rule). The other three kinds all point at something a *person* did,
227
+ * and PV-3 forbids a machine from minting those.
228
+ */
229
+ /** One field a {@link FieldInterceptor} resolved. */
230
+ export interface InterceptedField {
231
+ /** The resolved value. */
232
+ readonly value: JsonValue;
233
+ /**
234
+ * Where it came from. Only these two: **PV-3** forbids an interceptor from
235
+ * minting `UserStated`, because a machine may not put words in a person's mouth.
236
+ */
237
+ readonly source: "External" | "Computed";
238
+ /** How to check the value. Never absent (PV-4). */
239
+ readonly binding: InterceptorBinding;
240
+ /**
241
+ * How confident the interceptor is, `0.0` to `1.0`. A deterministic resolver
242
+ * normally says `1`; the merge step clamps whatever arrives (PV-1).
243
+ */
244
+ readonly confidence: number;
245
+ /** A human-readable line for the reviewer, or `null`. */
246
+ readonly evidence: string | null;
247
+ }
248
+ /** The fields one interceptor resolved, keyed by field name. */
249
+ export type InterceptedFields = {
250
+ readonly [fieldName: string]: InterceptedField;
251
+ };
252
+ /**
253
+ * A host-supplied resolver that fills fields deterministically, before any model is
254
+ * asked (GT-1 step 2).
255
+ *
256
+ * Interceptors run first because a value read from a system of record beats a value
257
+ * a model guessed, and running them first means the model is never asked for
258
+ * something the host already knows.
259
+ */
260
+ export interface FieldInterceptor {
261
+ /** A name for the record and for telemetry. */
262
+ readonly name: string;
263
+ /**
264
+ * Resolve whichever of `op.fields` this interceptor can. Returning `{}` is normal
265
+ * — an interceptor that has nothing to say says nothing.
266
+ */
267
+ resolve(op: Operation, ctx: TurnContext): Promise<InterceptedFields> | InterceptedFields;
268
+ }
269
+ //# sourceMappingURL=ports.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ports.d.ts","sourceRoot":"","sources":["../src/ports.ts"],"names":[],"mappings":"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"}
package/dist/ports.js ADDED
@@ -0,0 +1,34 @@
1
+ /**
2
+ * The ports a host supplies. Types only — this module has no runtime behaviour
3
+ * beyond {@link defaultClock}.
4
+ *
5
+ * **Rules served: GT-1** (the pipeline runs in protocol order, and every step it
6
+ * cannot do itself is a port), **GT-5** (a Standing Order that declares a risk
7
+ * threshold is compared against a host-supplied scorer), **AZ-2** (decision
8
+ * authorization is the host's answer, and the gate fails closed on it), **CV-1**
9
+ * (a port the gate needs and does not have is a wire-up failure, not a runtime
10
+ * surprise), **GT-2** (every port method that needs to know who is asking is
11
+ * handed the {@link TurnContext}; none of them may go looking).
12
+ *
13
+ * The shape of this file is the framework's central claim: **the core ships no
14
+ * model client, no scoring formula, no executor and no store.** It decides *what
15
+ * must be sworn to and who must agree*, and it asks the host for everything else.
16
+ * That is what lets one gate sit in front of any model, any database and any
17
+ * approval surface — and it is why a host cannot accidentally end up with a gate
18
+ * that scores its own risk or executes its own writes.
19
+ *
20
+ * @packageDocumentation
21
+ */
22
+ /**
23
+ * The clock used when a host supplies none: the Web-standard `Date`, formatted as
24
+ * an ISO 8601 instant in UTC.
25
+ *
26
+ * `Date` and `toISOString` are ECMAScript, present on Node, Bun and workerd alike
27
+ * (RT-1). No Node API, no timer, no interval — one reading, on demand.
28
+ */
29
+ export const defaultClock = {
30
+ now() {
31
+ return new Date().toISOString();
32
+ },
33
+ };
34
+ //# sourceMappingURL=ports.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ports.js","sourceRoot":"","sources":["../src/ports.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAgNH;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,YAAY,GAAU;IACjC,GAAG;QACD,OAAO,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAClC,CAAC;CACF,CAAC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * `@affiant/core/store-memory` — the reference Docket and Session stores, in
3
+ * memory.
4
+ *
5
+ * They are a separate entry point because a host in production imports the gate and
6
+ * a *durable* store, and should never be one careless import away from an approval
7
+ * record that lives only in an isolate that is about to be recycled. Keeping them
8
+ * out of the main entry point makes the choice visible in the import line.
9
+ *
10
+ * The in-memory store is nonetheless the **reference** implementation, not a toy: it
11
+ * is what the store-semantics fixtures are written against, and a production store
12
+ * earns the name by passing the same ones. What it enforces — idempotent filing, the
13
+ * guarded compare-and-set, the deadline applied on every read, opaque paging on every
14
+ * list, the bounded sweep, retention, purge, export, and a tenant partition a query
15
+ * cannot cross — is the DK area of the rulebook, in code.
16
+ *
17
+ * @packageDocumentation
18
+ */
19
+ export { InMemoryDocketStore, InMemorySessionStore } from "./docket/memory.js";
20
+ export type { InMemoryDocketStoreOptions } from "./docket/memory.js";
21
+ //# sourceMappingURL=store-memory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store-memory.d.ts","sourceRoot":"","sources":["../src/store-memory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC/E,YAAY,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * `@affiant/core/store-memory` — the reference Docket and Session stores, in
3
+ * memory.
4
+ *
5
+ * They are a separate entry point because a host in production imports the gate and
6
+ * a *durable* store, and should never be one careless import away from an approval
7
+ * record that lives only in an isolate that is about to be recycled. Keeping them
8
+ * out of the main entry point makes the choice visible in the import line.
9
+ *
10
+ * The in-memory store is nonetheless the **reference** implementation, not a toy: it
11
+ * is what the store-semantics fixtures are written against, and a production store
12
+ * earns the name by passing the same ones. What it enforces — idempotent filing, the
13
+ * guarded compare-and-set, the deadline applied on every read, opaque paging on every
14
+ * list, the bounded sweep, retention, purge, export, and a tenant partition a query
15
+ * cannot cross — is the DK area of the rulebook, in code.
16
+ *
17
+ * @packageDocumentation
18
+ */
19
+ export { InMemoryDocketStore, InMemorySessionStore } from "./docket/memory.js";
20
+ //# sourceMappingURL=store-memory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store-memory.js","sourceRoot":"","sources":["../src/store-memory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC"}