@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,136 @@
1
+ /**
2
+ * Turn context — the object every gate entry point takes as a parameter.
3
+ *
4
+ * **Rules served: GT-2** (the conversation-scope contract), **AZ-3** (a relay may
5
+ * never attest as the person it speaks for).
6
+ *
7
+ * GT-2 in one sentence: *turn context is explicit and passed, never ambient.*
8
+ * Every entry point on the gate takes a {@link TurnContext} — conversation id,
9
+ * tenant, channel, the principal if one is resolved, and the unmodified turn —
10
+ * supplied by the host or the adapter at the call site. Nothing in this package
11
+ * reads a process-global, a thread-ambient store or a container default; there is
12
+ * no module-level mutable state here for two interleaved conversations to collide
13
+ * in, and no accessor a caller could reach for instead of passing the context. An
14
+ * adapter that cannot obtain a context at its seam refuses (CV-2) rather than
15
+ * falling back to a shared default.
16
+ *
17
+ * Why the rule exists: in the shipped .NET wiring the tool-invocation seam resolves
18
+ * its scoped context store from the application's root provider, so one
19
+ * process-global instance is shared by every conversation — field provenance is
20
+ * overwritten across conversations, and where the host supplies no conversation id
21
+ * the second and later conversations skip write-tool inference silently.
22
+ *
23
+ * Every property below is `readonly`. A context is a value the host hands in, not a
24
+ * scratchpad the gate writes back to; freezing the shape in the type is how "never
25
+ * ambient" stays true after the pipeline lands.
26
+ *
27
+ * @packageDocumentation
28
+ */
29
+ /**
30
+ * How a person is addressed on the channel a relay speaks for — a workspace member
31
+ * id, a phone number, an address, whatever the relay's own directory uses. Opaque
32
+ * to the gate: it is carried onto the record and compared for equality, never
33
+ * parsed.
34
+ *
35
+ * It is a `string` on the wire and in every signature; the alias exists so the
36
+ * concept has one name across the packages.
37
+ */
38
+ export type ChannelIdentity = string;
39
+ /**
40
+ * What a relay asserts about the message it is carrying: which identity on its
41
+ * channel the message came from, and the id of the message itself.
42
+ *
43
+ * A relay is a trusted machine caller that *asserts* a person's identity rather
44
+ * than authenticating them. Both fields are carried onto the Affidavit's
45
+ * `external-ref` binding and onto the attestation of any decision made through the
46
+ * relay, so a reader of the record can name the message a write came from.
47
+ */
48
+ export interface RelayAssertion {
49
+ /** The identity, on the relay's own channel, the message came from. */
50
+ readonly channelIdentity: ChannelIdentity;
51
+ /** The relay's id for the message that carried the request. */
52
+ readonly messageId: string;
53
+ }
54
+ /**
55
+ * Who is acting on this turn.
56
+ *
57
+ * `member` is a human-verified session: the host authenticated the person itself.
58
+ * `service` is a machine caller — an MCP relay, a queue consumer, a scheduled job.
59
+ * A `service` principal may name the person it is speaking for
60
+ * ({@link Principal.assertedMember}) and the message it is carrying
61
+ * ({@link Principal.relay}), but **AZ-3** holds regardless: a `service` principal
62
+ * can never produce a `member` attestation. The strongest attestation a relayed
63
+ * decision can carry is `member-via-relay`, which names both the person and the
64
+ * relay.
65
+ *
66
+ * `null` in {@link TurnContext.principal} means *unresolved*, which is not the same
67
+ * as anonymous: a decision on an unresolved principal is refused
68
+ * (`decision-unauthorized`) before the store is touched (AZ-2).
69
+ */
70
+ export type Principal = {
71
+ /** A human-verified session. */
72
+ readonly kind: "member";
73
+ /** The host's id for the person. */
74
+ readonly id: string;
75
+ } | {
76
+ /** A machine caller: a relay, a queue consumer, a scheduled job. */
77
+ readonly kind: "service";
78
+ /** The host's id for the calling service. */
79
+ readonly id: string;
80
+ /**
81
+ * The message this service is carrying, when it is a relay. Absent when the
82
+ * service is acting on its own behalf.
83
+ */
84
+ readonly relay?: RelayAssertion;
85
+ /**
86
+ * The person this service says it is speaking for. An assertion, not an
87
+ * authentication — it never upgrades the principal to `member` (AZ-3).
88
+ */
89
+ readonly assertedMember?: string;
90
+ };
91
+ /**
92
+ * The turn as the host received it, unmodified.
93
+ *
94
+ * The gate hands exactly this to the host's inference port: one tool-free
95
+ * structured inference runs against the untouched utterance, so what the Affidavit
96
+ * swears to is traceable to what the person actually wrote.
97
+ *
98
+ * Structurally identical to `TurnContext["turn"]`; the alias exists so ports can
99
+ * name it.
100
+ */
101
+ export interface Turn {
102
+ /** What the person wrote or said, verbatim. */
103
+ readonly utterance: string;
104
+ /** The host's id for this message. */
105
+ readonly messageId: string;
106
+ /** When the turn arrived, as an ISO 8601 instant in UTC. */
107
+ readonly at: string;
108
+ }
109
+ /**
110
+ * Everything the gate is allowed to know about who is asking and where they are
111
+ * asking from — passed at the call site, never resolved from ambient state (GT-2).
112
+ *
113
+ * Two contexts constructed in the same process describe two different
114
+ * conversations and share nothing: there is no registry keyed by conversation id
115
+ * in this package, and no default context to fall back to.
116
+ */
117
+ export interface TurnContext {
118
+ /** The host's id for the conversation this turn belongs to. */
119
+ readonly conversationId: string;
120
+ /**
121
+ * The tenant every record written for this turn is scoped to. A decision whose
122
+ * context tenant differs from the entry's tenant is refused (AZ-2).
123
+ */
124
+ readonly tenantId: string;
125
+ /**
126
+ * Where the turn arrived from. The three named values are the ones the v0.1
127
+ * sequences use; the `(string & {})` arm keeps the union open to a host's own
128
+ * channel name without losing completion on the three.
129
+ */
130
+ readonly channel: "chat" | "mcp" | "api" | (string & {});
131
+ /** Who is acting, or `null` when the host has not resolved an identity. */
132
+ readonly principal: Principal | null;
133
+ /** The turn itself, unmodified. */
134
+ readonly turn: Turn;
135
+ }
136
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH;;;;;;;;GAQG;AACH,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC;AAErC;;;;;;;;GAQG;AACH,MAAM,WAAW,cAAc;IAC7B,uEAAuE;IACvE,QAAQ,CAAC,eAAe,EAAE,eAAe,CAAC;IAC1C,+DAA+D;IAC/D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,SAAS,GACjB;IACE,gCAAgC;IAChC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,oCAAoC;IACpC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACrB,GACD;IACE,oEAAoE;IACpE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,cAAc,CAAC;IAChC;;;OAGG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;CAClC,CAAC;AAEN;;;;;;;;;GASG;AACH,MAAM,WAAW,IAAI;IACnB,+CAA+C;IAC/C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,sCAAsC;IACtC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,WAAW;IAC1B,+DAA+D;IAC/D,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,KAAK,GAAG,KAAK,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;IACzD,2EAA2E;IAC3E,QAAQ,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC;IACrC,mCAAmC;IACnC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;CACrB"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Turn context — the object every gate entry point takes as a parameter.
3
+ *
4
+ * **Rules served: GT-2** (the conversation-scope contract), **AZ-3** (a relay may
5
+ * never attest as the person it speaks for).
6
+ *
7
+ * GT-2 in one sentence: *turn context is explicit and passed, never ambient.*
8
+ * Every entry point on the gate takes a {@link TurnContext} — conversation id,
9
+ * tenant, channel, the principal if one is resolved, and the unmodified turn —
10
+ * supplied by the host or the adapter at the call site. Nothing in this package
11
+ * reads a process-global, a thread-ambient store or a container default; there is
12
+ * no module-level mutable state here for two interleaved conversations to collide
13
+ * in, and no accessor a caller could reach for instead of passing the context. An
14
+ * adapter that cannot obtain a context at its seam refuses (CV-2) rather than
15
+ * falling back to a shared default.
16
+ *
17
+ * Why the rule exists: in the shipped .NET wiring the tool-invocation seam resolves
18
+ * its scoped context store from the application's root provider, so one
19
+ * process-global instance is shared by every conversation — field provenance is
20
+ * overwritten across conversations, and where the host supplies no conversation id
21
+ * the second and later conversations skip write-tool inference silently.
22
+ *
23
+ * Every property below is `readonly`. A context is a value the host hands in, not a
24
+ * scratchpad the gate writes back to; freezing the shape in the type is how "never
25
+ * ambient" stays true after the pipeline lands.
26
+ *
27
+ * @packageDocumentation
28
+ */
29
+ export {};
30
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG"}
@@ -0,0 +1,421 @@
1
+ /**
2
+ * The Docket entry — the row every proposed write becomes, and the only record of
3
+ * approval authority the framework recognises.
4
+ *
5
+ * **Rules served: DK-1** (the review-outcome state machine, expiry as queryable
6
+ * state, lineage), **AZ-1** (the attestation record and its three attestor kinds),
7
+ * **AZ-4** (requirement levels and the `blocked` marker), **DK-4** (a row reads
8
+ * forward: later facts are appended, a recorded decision is never edited).
9
+ *
10
+ * DK-1 in one sentence: *`pending` goes to exactly one of `approved`, `rejected`
11
+ * or `expired`; an `approved` row carries an execution outcome so an
12
+ * approved-but-failed write is distinguishable from an approved-and-committed one;
13
+ * every transition out of `pending` is a guarded compare-and-set; and an entry past
14
+ * its expiry reads `expired` whether or not any sweep has run.*
15
+ *
16
+ * The last clause is why {@link readStatus} exists and why nothing in this package
17
+ * schedules a timer. Expiry is **state**, not an event: a host that never runs a
18
+ * sweep still cannot decide an expired entry, because every read applies the
19
+ * deadline. The sweep ({@link DocketStore.expireDue}) exists to make the state
20
+ * durable and to drive notifications, not to make it true.
21
+ *
22
+ * @packageDocumentation
23
+ */
24
+ import type { Affidavit } from "../model/affidavit.js";
25
+ import type { AmendmentMap } from "../model/amendments.js";
26
+ import type { ChannelIdentity, TurnContext } from "../context.js";
27
+ /**
28
+ * Where an entry stands. `pending` is the only non-terminal state, and it goes to
29
+ * exactly one of the other three (DK-1).
30
+ *
31
+ * `deferred` and the referral outcome — an entry handed to another reviewer — are
32
+ * **reserved** by the rulebook and deliberately absent: no implementation has run
33
+ * those transitions, so naming them here would invite a host to depend on
34
+ * semantics nobody has fixed.
35
+ */
36
+ export type DocketStatus = "pending" | "approved" | "rejected" | "expired";
37
+ /** Every {@link DocketStatus}, pinned as data so a runtime check and a fixture read the same list. */
38
+ export declare const DOCKET_STATUSES: readonly ["pending", "approved", "rejected", "expired"];
39
+ /**
40
+ * What became of an approved write, once the host's executor reported.
41
+ *
42
+ * The reason this is a separate axis rather than two more statuses: an
43
+ * approved-but-failed write and an approved-and-committed one differ in what the
44
+ * *host* must do next, not in whether the approval happened. Collapsing them into
45
+ * `status` loses the approval, and DK-1 requires the two be distinguishable on the
46
+ * row.
47
+ */
48
+ export type ExecutionOutcome = "unexecuted" | "executed" | "failed";
49
+ /** Every {@link ExecutionOutcome}, in the order a row moves through them. */
50
+ export declare const EXECUTION_OUTCOMES: readonly ["unexecuted", "executed", "failed"];
51
+ /**
52
+ * Whether `status` is terminal — everything except `pending`.
53
+ *
54
+ * `approved` counts as terminal for the *review*, which is what this predicate is
55
+ * about; whether the write has been executed is {@link DocketEntry.execution}, a
56
+ * separate question with a separate answer.
57
+ */
58
+ export declare function isTerminal(status: DocketStatus): boolean;
59
+ /**
60
+ * How much agreement a write needs before it may execute — the policy chain's
61
+ * verdict kind, recorded verbatim on the entry.
62
+ *
63
+ * `StandingOrder` approves with no person present. `ReviewerConfirmation` asks one
64
+ * person. `ReferralRequired` hands the entry to a different reviewer, and
65
+ * `MultiParty` requires several — **neither of which v0.1 runs**. AZ-4 is emphatic
66
+ * about what an implementation does with a level it does not run: it records the
67
+ * level verbatim, files the entry `pending` with a {@link BlockedMarker}, refuses
68
+ * every decision on it, and **never degrades it to a weaker requirement**. A joint
69
+ * requirement quietly satisfied by one approval is the failure this rule exists to
70
+ * prevent.
71
+ */
72
+ export type RequirementKind = "StandingOrder" | "ReviewerConfirmation" | "ReferralRequired" | "MultiParty";
73
+ /** Every {@link RequirementKind}, in the rulebook's order. */
74
+ export declare const REQUIREMENT_KINDS: readonly ["StandingOrder", "ReviewerConfirmation", "ReferralRequired", "MultiParty"];
75
+ /**
76
+ * Why an entry cannot be decided even though it sits in `pending`.
77
+ *
78
+ * Both codes are **provisional** until the protocol's `ErrorCode` registry is
79
+ * authored with the v0.1 schemas; they match {@link ErrorCode} member for member so
80
+ * that a refusal thrown by the gate and the marker left on the row spell the same
81
+ * reason.
82
+ */
83
+ export type BlockedCode = "requirement-not-implemented" | "coverage-refused";
84
+ /** Every {@link BlockedCode}. */
85
+ export declare const BLOCKED_CODES: readonly ["requirement-not-implemented", "coverage-refused"];
86
+ /**
87
+ * A requirement level this version recognises but does not run reached the
88
+ * pipeline — `ReferralRequired` or `MultiParty`, whose semantics are reserved. The
89
+ * level is recorded verbatim and never degraded to a weaker one (AZ-4).
90
+ */
91
+ export interface RequirementNotImplementedMarker {
92
+ readonly code: "requirement-not-implemented";
93
+ /** The requirement level that is not implemented. */
94
+ readonly level: RequirementKind;
95
+ }
96
+ /**
97
+ * A proposal came from a write-capable tool the host declared the gate cannot
98
+ * intercept (CV-4). Its proposals are still recorded — blocked, never silently
99
+ * allowed to write — and the tool name is on the row so coverage can be
100
+ * re-assessed on a resubmission.
101
+ */
102
+ export interface CoverageRefusedMarker {
103
+ readonly code: "coverage-refused";
104
+ /** The category the gate cannot cover. */
105
+ readonly category: "no-execute" | "provider-executed" | "hosted-mcp";
106
+ /** The tool the uncovered proposal came from. */
107
+ readonly toolName: string;
108
+ }
109
+ /**
110
+ * The marker AZ-4 requires on an entry the implementation will not decide.
111
+ *
112
+ * Discriminated on its `code`, and each arm carries exactly the context that code
113
+ * makes meaningful — a `coverage-refused` marker has no requirement level to
114
+ * report, and a reader narrows on the code rather than sniffing for a property
115
+ * (AF-5).
116
+ */
117
+ export type BlockedMarker = RequirementNotImplementedMarker | CoverageRefusedMarker;
118
+ /** What a relay asserted, as it is written onto an attestation. */
119
+ export interface AttestationRelay {
120
+ /** The host's id for the relay service that carried the decision. */
121
+ readonly principal: string;
122
+ /** The identity, on the relay's own channel, the decision came from. */
123
+ readonly channelIdentity: ChannelIdentity;
124
+ /** The relay's id for the message that carried the decision. */
125
+ readonly messageId: string;
126
+ }
127
+ /**
128
+ * Who agreed to the write. The *mode* is the `kind`; there is no separate mode
129
+ * field for it to drift from (AZ-1).
130
+ *
131
+ * AZ-3 is what the three arms encode. A human-verified session attests `member`. A
132
+ * machine caller may **never** attest `member`: a decision a person makes through a
133
+ * relay attests `member-via-relay`, naming both the person and the relay, and a
134
+ * capture a policy auto-approves attests `standing-order`, naming the policy and
135
+ * the version of it that fired. Making the strongest available claim explicit in
136
+ * the type is how an implementation avoids the shortcut where a relay's assertion
137
+ * is quietly promoted to a person's signature.
138
+ */
139
+ export type Attestor = {
140
+ /** A human-verified session decided this entry. */
141
+ readonly kind: "member";
142
+ /** The host's id for the person. */
143
+ readonly id: string;
144
+ } | {
145
+ /** A person decided this entry through a trusted relay. */
146
+ readonly kind: "member-via-relay";
147
+ /** The host's id for the person the relay named. */
148
+ readonly memberId: string;
149
+ /** The relay, and the message the decision arrived on. */
150
+ readonly relay: AttestationRelay;
151
+ } | {
152
+ /** A policy approved this entry with no person present. */
153
+ readonly kind: "standing-order";
154
+ /** The host's id for the policy that fired. */
155
+ readonly policyId: string;
156
+ /** The version of that policy, so a later reader can tell what it said at the time. */
157
+ readonly version: string;
158
+ };
159
+ /**
160
+ * The attestation record AZ-1 requires on every write that reaches an executor: who
161
+ * agreed, when, and to which entry.
162
+ *
163
+ * `entryId` is repeated here rather than left implicit because the attestation is
164
+ * the fragment a host exports, signs or ships to an audit sink; a record that
165
+ * cannot name its own subject is not evidence.
166
+ */
167
+ export interface Attestation {
168
+ /** Who agreed. */
169
+ readonly by: Attestor;
170
+ /** When, as an ISO 8601 instant in UTC. */
171
+ readonly at: string;
172
+ /** The entry this attests to. */
173
+ readonly entryId: string;
174
+ }
175
+ /**
176
+ * What a reviewer decided, as it is recorded on the row.
177
+ *
178
+ * Separate from {@link Attestation} because they answer different questions: the
179
+ * attestation says *who may be held to this*, the decision says *what they chose
180
+ * and why*. A Standing Order produces an attestation and no decision record — no
181
+ * person chose anything.
182
+ */
183
+ export interface DecisionRecord {
184
+ /** Approve or reject. Amending is approving with an {@link DocketEntry.amendments} map. */
185
+ readonly kind: "approve" | "reject";
186
+ /** The reviewer's stated reason, or `null` when they gave none. */
187
+ readonly reason: string | null;
188
+ /** When the decision was made, as an ISO 8601 instant in UTC. */
189
+ readonly at: string;
190
+ }
191
+ /**
192
+ * How this entry relates to the entries it replaces or is replaced by (DK-1).
193
+ *
194
+ * A resubmission is a **new** entry, never a reopened one: the superseded entry
195
+ * keeps its terminal state and records its successor, so the history reads forward
196
+ * (DK-4) and nothing that was once decided is quietly edited.
197
+ */
198
+ export interface Lineage {
199
+ /** The entry this one resubmits, or `null` for a first filing. */
200
+ readonly supersedes: string | null;
201
+ /** The entry that resubmitted this one, or `null` while none has. */
202
+ readonly supersededBy: string | null;
203
+ }
204
+ /**
205
+ * The amendments a decision carried after the entry had already expired, with the
206
+ * act that carried them (DK-1).
207
+ *
208
+ * The instant and the principal are here, and not merely implied, because a
209
+ * resubmission prefills these values as **a person's own correction**: each
210
+ * prefilled field is tagged `UserStated` with a `reviewer-act` binding, and PV-2
211
+ * says that binding names the decision the correction was made on. Without the
212
+ * instant the binding would have to point at the row's deadline — the moment the
213
+ * gate refused, not the moment the person typed — and without the principal the
214
+ * record could not say whose correction it is.
215
+ */
216
+ export interface PreservedAmendments {
217
+ /** The map the refused decision carried. DK-2 holds inside it. */
218
+ readonly amendments: AmendmentMap;
219
+ /** When the refused decision was made, as an ISO 8601 instant in UTC. */
220
+ readonly at: string;
221
+ /** Who made it, as the host identifies them. */
222
+ readonly by: string;
223
+ }
224
+ /**
225
+ * One filed proposal: the Affidavit, what it needs before it may execute, where it
226
+ * stands, and who agreed.
227
+ *
228
+ * Every property is `readonly`. A store never mutates a row in place — a
229
+ * transition, a preserved amendment map, an execution outcome and a supersession
230
+ * each produce a *new* entry value that replaces the old one under the same id.
231
+ * That is DK-4's read-forward property expressed in the type rather than in a
232
+ * comment nobody runs.
233
+ *
234
+ * Three correlations the flat shape cannot express, enforced by {@link newEntry}
235
+ * and by the store's transition instead:
236
+ *
237
+ * 1. `execution` is non-`null` **exactly when** `status` is `"approved"`.
238
+ * 2. `decidedAt` is non-`null` on every terminal row and `null` while `pending`.
239
+ * 3. `status` is what the row *says*; what it *reads* is {@link readStatus}, which
240
+ * applies the expiry deadline. Every query path goes through the latter.
241
+ */
242
+ export interface DocketEntry {
243
+ /** The entry's id. Stable for its whole lifetime; a resubmission gets a new one. */
244
+ readonly entryId: string;
245
+ /**
246
+ * The tenant this entry is scoped to. Compared against `ctx.tenantId` before any
247
+ * transition (AZ-2), and the partition every store operation is keyed by: an
248
+ * entry id is unique within a tenant, never across them.
249
+ */
250
+ readonly tenantId: string;
251
+ /** The conversation the proposal came from (GT-2). */
252
+ readonly conversationId: string;
253
+ /** Where the turn arrived from — `"chat"` for Sequence A, `"mcp"` for Sequence C. */
254
+ readonly channel: TurnContext["channel"];
255
+ /**
256
+ * The tool or capture source the proposal came from.
257
+ *
258
+ * On the row because two later questions need it and neither can be answered
259
+ * from the Affidavit: a resubmission re-runs the coverage lookup against the
260
+ * original tool (CV-4), and an audit of a filed write has to be able to say
261
+ * which tool proposed it.
262
+ */
263
+ readonly toolName: string;
264
+ /**
265
+ * The sworn evidence record **as the agent proposed it**. Never edited (DK-4).
266
+ *
267
+ * An accepted amendment does not rewrite this; it writes
268
+ * {@link DocketEntry.amendedAffidavit} beside it. A row that overwrote its
269
+ * proposal could not show what the agent originally said, which is the fact an
270
+ * auditor is reading the row for.
271
+ */
272
+ readonly affidavit: Affidavit;
273
+ /**
274
+ * The state a reviewer's accepted amendments produced, or `null` while no
275
+ * amendment has been accepted (AF-4, DK-4).
276
+ *
277
+ * The form a host's execution grant binds to is
278
+ * `canonicalize(amendedAffidavit ?? affidavit)` — see `canonicalizeEntry` — which
279
+ * is what SR-1's "the Affidavit and its accepted amendments" means on a row.
280
+ */
281
+ readonly amendedAffidavit: Affidavit | null;
282
+ /** What the policy chain decided this write needs before it may execute (AZ-4). */
283
+ readonly requirement: RequirementKind;
284
+ /** What the row says. What it *reads* is {@link readStatus}. */
285
+ readonly status: DocketStatus;
286
+ /** What became of the write. Non-`null` exactly when `status` is `"approved"`. */
287
+ readonly execution: ExecutionOutcome | null;
288
+ /** Why this entry cannot be decided, or `null` when it can (AZ-4). */
289
+ readonly blocked: BlockedMarker | null;
290
+ /**
291
+ * The composite approval this entry is one constituent of, or `null`.
292
+ *
293
+ * Until `MultiParty` is protocol v0.2, a host composes multi-party approval
294
+ * *above* the gate: one entry per approver, all naming the same composite, and
295
+ * no constituent's approval alone reaching the executor (AZ-4).
296
+ */
297
+ readonly compositeRef: string | null;
298
+ /** Who agreed, or `null` while nobody has (AZ-1). */
299
+ readonly attestation: Attestation | null;
300
+ /**
301
+ * The amendments a reviewer's approval **accepted**, or `null` when the approval
302
+ * carried none.
303
+ *
304
+ * Within a map, DK-2 holds: a key whose value is `null` was **cleared** by the
305
+ * reviewer, and an absent key was left untouched. The two are never conflated.
306
+ *
307
+ * A map a *refused* late decision carried is a different fact and lives under
308
+ * {@link DocketEntry.preservedAmendments}: nobody accepted it, and conflating the
309
+ * two would let a resubmission present a refused caller's corrections as an
310
+ * approval's.
311
+ */
312
+ readonly amendments: AmendmentMap | null;
313
+ /**
314
+ * The amendments a decision carried after the deadline had passed, with the act
315
+ * that carried them, or `null` (DK-1).
316
+ *
317
+ * An appended later fact on an expired row, written by the store's
318
+ * `preserveAmendments` and read by `resubmit` to prefill the new proposal.
319
+ */
320
+ readonly preservedAmendments: PreservedAmendments | null;
321
+ /** What a reviewer chose, or `null` for a pending row or a Standing Order. */
322
+ readonly decision: DecisionRecord | null;
323
+ /** What this entry replaces and what replaced it (DK-1). */
324
+ readonly lineage: Lineage;
325
+ /** When the entry was filed, as an ISO 8601 instant in UTC. Fixes the filing order. */
326
+ readonly filedAt: string;
327
+ /**
328
+ * The deadline, as an ISO 8601 instant in UTC. Set from the policy verdict's TTL
329
+ * after the policy chain has run (GT-4), and **never refreshed by a re-file**.
330
+ */
331
+ readonly expiresAt: string;
332
+ /** When the row left `pending`, or `null` while it has not. */
333
+ readonly decidedAt: string | null;
334
+ /** What the executor reported, or `null` when it has not reported or had nothing to say. */
335
+ readonly executionDetail: string | null;
336
+ /** The protocol tag the entry's wire shapes are pinned to. */
337
+ readonly protocolVersion: string;
338
+ }
339
+ /**
340
+ * What {@link newEntry} needs, and the few defaults a caller may override.
341
+ *
342
+ * The overridable set is deliberately small: everything else on a
343
+ * {@link DocketEntry} is a *later fact* — a decision, a preserved amendment map, an
344
+ * execution outcome, a supersession — and later facts are appended by the store, not
345
+ * supplied at filing. The exceptions are the ones the pipeline genuinely writes in
346
+ * the same operation as the filing: a Standing Order verdict files `approved`,
347
+ * `unexecuted` and its attestation in one write (GT-1 step 9, AZ-1), and an
348
+ * unimplemented requirement files `pending` with a blocked marker (AZ-4).
349
+ */
350
+ export interface NewEntryInit {
351
+ /** The entry's id. Unique within the tenant. */
352
+ readonly entryId: string;
353
+ /** The tenant the entry is scoped to. */
354
+ readonly tenantId: string;
355
+ /** The conversation the proposal came from. */
356
+ readonly conversationId: string;
357
+ /** Where the turn arrived from. */
358
+ readonly channel: TurnContext["channel"];
359
+ /** The tool or capture source the proposal came from (CV-4). */
360
+ readonly toolName: string;
361
+ /** The sworn evidence record, as proposed. */
362
+ readonly affidavit: Affidavit;
363
+ /** What the policy chain decided this write needs. */
364
+ readonly requirement: RequirementKind;
365
+ /** When the entry is being filed, as an ISO 8601 instant in UTC. */
366
+ readonly filedAt: string;
367
+ /** The deadline, as an ISO 8601 instant in UTC (GT-4). */
368
+ readonly expiresAt: string;
369
+ /** The protocol tag. Defaults to the tag `@affiant/contract` is pinned to. */
370
+ readonly protocolVersion?: string;
371
+ /** Defaults to `"pending"`. A Standing Order files `"approved"`. */
372
+ readonly status?: DocketStatus;
373
+ /**
374
+ * Defaults to `"unexecuted"` when `status` is `"approved"` and `null` otherwise.
375
+ * Supplying a value that contradicts the status is a `RangeError`.
376
+ */
377
+ readonly execution?: ExecutionOutcome | null;
378
+ /** The AZ-4 marker, when the entry is filed blocked. */
379
+ readonly blocked?: BlockedMarker | null;
380
+ /** The composite approval this entry is a constituent of. */
381
+ readonly compositeRef?: string | null;
382
+ /** The attestation a Standing Order writes in the same operation as the filing (AZ-1). */
383
+ readonly attestation?: Attestation | null;
384
+ /** The entry this one resubmits (DK-1). The successor link is written on the *other* row. */
385
+ readonly supersedes?: string | null;
386
+ /**
387
+ * When the row left `pending`, for an entry filed already terminal. Defaults to
388
+ * `filedAt` in that case, and is `null` for a `pending` filing.
389
+ */
390
+ readonly decidedAt?: string | null;
391
+ }
392
+ /**
393
+ * A new Docket entry, with the defaults DK-1 fixes and the correlations it requires
394
+ * checked.
395
+ *
396
+ * Refusals are `RangeError`, not `AffiantError`: the {@link ErrorCode} registry
397
+ * names the reasons *the gate refuses a request*, and a caller who hands this
398
+ * factory a status and an execution outcome that contradict each other has made a
399
+ * programming error, not a request. Keeping the two apart is what stops a host from
400
+ * catching a wiring bug as though it were a reviewer's rejection.
401
+ *
402
+ * @throws RangeError when an identifier is blank, an instant is unreadable, the
403
+ * requirement is not one of the four, or `execution` contradicts `status`.
404
+ */
405
+ export declare function newEntry(init: NewEntryInit): DocketEntry;
406
+ /**
407
+ * What `entry` reads as at `now` — the status every query path reports.
408
+ *
409
+ * A `pending` entry past its `expiresAt` reads `expired` **whether or not any sweep
410
+ * has run**. That is the whole of DK-1's expiry clause, and it is a pure function of
411
+ * the row and the instant precisely so that no code path can forget it: there is no
412
+ * background job to be down, no alarm to be dropped, and no window in which an entry
413
+ * is decidable because nobody swept it yet.
414
+ *
415
+ * Any other status is returned unchanged. Expiry only ever consumes `pending`; a row
416
+ * that was approved before its deadline stays approved forever after it.
417
+ *
418
+ * @throws RangeError when `now` or the entry's `expiresAt` is not a readable instant.
419
+ */
420
+ export declare function readStatus(entry: Pick<DocketEntry, "status" | "expiresAt">, now: string): DocketStatus;
421
+ //# sourceMappingURL=entry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entry.d.ts","sourceRoot":"","sources":["../../src/docket/entry.ts"],"names":[],"mappings":"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"}