@zanii/status-feed 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -98,6 +98,7 @@ if (verifyFeed(entries, { signers: [regulatorDid] }).ok) {
98
98
 
99
99
  ## Changelog
100
100
 
101
+ - **0.4.0**: `appendEventAsync(feed, event, signer)` takes a raw key or a remote signer (HSM, KMS). Entries are byte-identical to `appendEvent`. Requires `@zanii/core` 0.5.7. Additive.
101
102
  - **0.3.0** (unreleased): supervision events. New kinds `supervision.suspended` and
102
103
  `supervision.lifted`, with `supervisionEvent`, `supervisionScopeReasons`, `activeSuspensions` and
103
104
  `suspensionFor`. Two distinct approval hashes and a reason are required. Additive: entries of the
package/dist/index.d.ts CHANGED
@@ -10,7 +10,7 @@
10
10
  * a Ledger receipt (`anchorFeedHead`) fixes the feed's history in the transparency log so
11
11
  * the operator cannot rewrite it unseen.
12
12
  */
13
- import { type RevocationRecord, type SignedObject } from '@zanii/core';
13
+ import { type RemoteSigner, type RevocationRecord, type SignedObject } from '@zanii/core';
14
14
  export declare const FEED_TYPE: "zanii.status_feed";
15
15
  export declare const EVENT_KINDS: readonly ["delegation.revoked", "certificate.suspended", "certificate.revoked", "certificate.reinstated", "incident.opened", "incident.closed", "jurisdiction.issued", "jurisdiction.expired", "threat.signature", "threat.retracted", "supervision.suspended", "supervision.lifted"];
16
16
  export type EventKind = (typeof EVENT_KINDS)[number];
@@ -131,14 +131,15 @@ export declare function matchThreat(signatures: ThreatSignature[], action: {
131
131
  }): ThreatSignature | null;
132
132
  /** The last entry's position, or null for an empty feed. */
133
133
  export declare function feedHead(entries: FeedEntry[]): FeedHead | null;
134
- /**
135
- * Sign the next entry of `feed` and return it with the new head. Pure: the caller appends
136
- * `entry` to its stored feed. Refuses a malformed event and an event dated before the head.
137
- */
138
134
  export declare function appendEvent(feed: Feed, event: StatusEvent, signerKey: Uint8Array): {
139
135
  entry: FeedEntry;
140
136
  head: FeedHead;
141
137
  };
138
+ /** `appendEvent` with a raw key or a remote signer (HSM, KMS): the key need not enter this process. */
139
+ export declare function appendEventAsync(feed: Feed, event: StatusEvent, signer: Uint8Array | RemoteSigner): Promise<{
140
+ entry: FeedEntry;
141
+ head: FeedHead;
142
+ }>;
142
143
  export interface VerifyFeedOptions {
143
144
  /** The DIDs allowed to sign entries (key rotation: list old and new). */
144
145
  signers: string[];
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -10,7 +10,7 @@
10
10
  * a Ledger receipt (`anchorFeedHead`) fixes the feed's history in the transparency log so
11
11
  * the operator cannot rewrite it unseen.
12
12
  */
13
- import { canonicalBytes, certHash, jcsHash, scopeCovers, verifyRevocation, signObject, verifySignedObject } from '@zanii/core';
13
+ import { canonicalBytes, certHash, jcsHash, scopeCovers, verifyRevocation, signObject, signObjectAsync, verifySignedObject } from '@zanii/core';
14
14
  export const FEED_TYPE = 'zanii.status_feed';
15
15
  export const EVENT_KINDS = [
16
16
  'delegation.revoked',
@@ -219,7 +219,7 @@ export function feedHead(entries) {
219
219
  * Sign the next entry of `feed` and return it with the new head. Pure: the caller appends
220
220
  * `entry` to its stored feed. Refuses a malformed event and an event dated before the head.
221
221
  */
222
- export function appendEvent(feed, event, signerKey) {
222
+ function unsignedEntry(feed, event) {
223
223
  if (typeof feed?.jurisdiction !== 'string' || !feed.jurisdiction)
224
224
  throw new Error('status-feed: feed.jurisdiction is required');
225
225
  const ev = normalize(event);
@@ -231,10 +231,15 @@ export function appendEvent(feed, event, signerKey) {
231
231
  throw new Error('status-feed: the feed holds another jurisdiction');
232
232
  if (last && ms(ev.ts) < ms(last.event.ts))
233
233
  throw new Error('status-feed: event is dated before the feed head');
234
- const entry = signObject({
235
- v: 1, type: FEED_TYPE, jurisdiction: feed.jurisdiction,
236
- seq: last ? last.seq + 1 : 1, prev: last ? entryHash(last) : null, event: ev,
237
- }, signerKey);
234
+ return { v: 1, type: FEED_TYPE, jurisdiction: feed.jurisdiction, seq: last ? last.seq + 1 : 1, prev: last ? entryHash(last) : null, event: ev };
235
+ }
236
+ export function appendEvent(feed, event, signerKey) {
237
+ const entry = signObject(unsignedEntry(feed, event), signerKey);
238
+ return { entry, head: { seq: entry.seq, hash: entryHash(entry) } };
239
+ }
240
+ /** `appendEvent` with a raw key or a remote signer (HSM, KMS): the key need not enter this process. */
241
+ export async function appendEventAsync(feed, event, signer) {
242
+ const entry = await signObjectAsync(unsignedEntry(feed, event), signer);
238
243
  return { entry, head: { seq: entry.seq, hash: entryHash(entry) } };
239
244
  }
240
245
  /** Chain continuity, sequence without gaps, signatures by allowed signers, non-decreasing time, well-formed events. */
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zanii/status-feed",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "One signed, append-only, hash-chained status feed per jurisdiction: delegation revocations, Certify certificate suspensions, revocations and reinstatements, incident references and jurisdiction bindings, each with evidence hashes. Append, verify (chain, signatures, time, gaps), read since a sequence number, render as Atom or JSON Feed, and anchor the head as a Ledger receipt payload.",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://ledger.zanii.agency",
@@ -26,7 +26,7 @@
26
26
  "node": ">=18"
27
27
  },
28
28
  "dependencies": {
29
- "@zanii/core": "^0.5.6"
29
+ "@zanii/core": "^0.5.7"
30
30
  },
31
31
  "devDependencies": {
32
32
  "@noble/curves": "^1.8.1",
package/src/index.ts CHANGED
@@ -1,403 +1,410 @@
1
- /**
2
- * @zanii/status-feed: one signed, append-only, hash-chained feed of status events per
3
- * jurisdiction. Each entry names the previous entry's hash and its sequence number, is
4
- * signed by the feed operator (a regulator or the Ledger operator) and carries the hashes
5
- * of the evidence behind the event: a delegation revocation, a Certify status document,
6
- * an incident report, a jurisdiction binding.
7
- *
8
- * The feed says that its signer published these events in this order. It does not make
9
- * the events true: a verifier checks the evidence the hashes name. Anchoring the head as
10
- * a Ledger receipt (`anchorFeedHead`) fixes the feed's history in the transparency log so
11
- * the operator cannot rewrite it unseen.
12
- */
13
- import { canonicalBytes, certHash, jcsHash, scopeCovers, verifyRevocation, signObject, verifySignedObject, type RevocationRecord, type SignedObject } from '@zanii/core';
14
-
15
- export const FEED_TYPE = 'zanii.status_feed' as const;
16
-
17
- export const EVENT_KINDS = [
18
- 'delegation.revoked',
19
- 'certificate.suspended',
20
- 'certificate.revoked',
21
- 'certificate.reinstated',
22
- 'incident.opened',
23
- 'incident.closed',
24
- 'jurisdiction.issued',
25
- 'jurisdiction.expired',
26
- 'threat.signature',
27
- 'threat.retracted',
28
- 'supervision.suspended',
29
- 'supervision.lifted',
30
- ] as const;
31
- export type EventKind = (typeof EVENT_KINDS)[number];
32
-
33
- /** Certify status reason codes, versions 1 to 3 (Certify spec/status.md sections 2, 6, 7). */
34
- export const CERTIFY_REASONS = [
35
- 'FINGERPRINT_MISMATCH', 'RETEST_OVERDUE', 'RETEST_FAILED', 'INCIDENT', 'APPLICANT_REQUEST',
36
- 'ISSUER_ERROR', 'LICENCE_WITHDRAWN', 'AUDIT_EXPIRED', 'MARK_MISUSE', 'FALSE_DECLARATION', 'EVIDENCE_LAPSED',
37
- ] as const;
38
-
39
- export interface StatusEvent {
40
- kind: EventKind;
41
- /** The did:key the event is about (usually the agent). */
42
- subject: string;
43
- /** What the event names: a delegation cert hash, a certificate hash, an incident id, a binding hash. */
44
- ref: string;
45
- ts: string;
46
- /** Certify reason code for certificate suspend and revoke; null for reinstate; free text or null otherwise. */
47
- reason: string | null;
48
- /** `sha256:` hashes of the evidence; sorted and distinct in the entry. */
49
- evidence: string[];
50
- }
51
-
52
- export type FeedEntry = SignedObject<{
53
- v: 1;
54
- type: typeof FEED_TYPE;
55
- jurisdiction: string;
56
- seq: number;
57
- prev: string | null;
58
- event: StatusEvent;
59
- }>;
60
-
61
- export interface FeedHead { seq: number; hash: string }
62
- export interface Feed { jurisdiction: string; entries: FeedEntry[] }
63
-
64
- const HASH = /^sha256:[0-9a-f]{64}$/;
65
- const ISO = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.(\d{1,9}))?(Z|[+-]\d{2}:\d{2})$/;
66
-
67
- /** Epoch ms of a strict ISO 8601 UTC-or-offset timestamp, or NaN. */
68
- function ms(ts: unknown): number {
69
- return typeof ts === 'string' && ISO.test(ts) ? Date.parse(ts) : NaN;
70
- }
71
-
72
- const canonicalJson = (x: unknown): string => new TextDecoder().decode(canonicalBytes(x));
73
-
74
- /** The hash later entries chain to: `jcsHash` of the whole signed entry. */
75
- export function entryHash(entry: FeedEntry): string {
76
- return jcsHash(entry);
77
- }
78
-
79
- /** Why an event is malformed; empty when it is well formed. */
80
- export function eventReasons(e: unknown): string[] {
81
- if (!e || typeof e !== 'object' || Array.isArray(e)) return ['event is not an object'];
82
- const ev = e as Record<string, unknown>;
83
- const out: string[] = [];
84
- const keys = Object.keys(ev).sort().join(',');
85
- if (keys !== 'evidence,kind,reason,ref,subject,ts') out.push('event has unexpected or missing fields');
86
- if (!(EVENT_KINDS as readonly unknown[]).includes(ev.kind)) out.push('unknown event kind');
87
- if (typeof ev.subject !== 'string' || !ev.subject.startsWith('did:')) out.push('event subject is not a DID');
88
- if (typeof ev.ref !== 'string' || !ev.ref) out.push('event ref is empty');
89
- if (Number.isNaN(ms(ev.ts))) out.push('event ts is not an ISO timestamp');
90
- const ok = Array.isArray(ev.evidence) && ev.evidence.length > 0 && ev.evidence.every((h) => typeof h === 'string' && HASH.test(h));
91
- if (!ok) out.push('event evidence must be a non-empty list of sha256 hashes');
92
- else if (new Set(ev.evidence as string[]).size !== (ev.evidence as string[]).length || [...(ev.evidence as string[])].sort().join() !== (ev.evidence as string[]).join()) out.push('event evidence is not sorted and distinct');
93
- if (ev.kind === 'certificate.suspended' || ev.kind === 'certificate.revoked') {
94
- if (!(CERTIFY_REASONS as readonly unknown[]).includes(ev.reason)) out.push('certificate suspend or revoke needs a Certify reason code');
95
- } else if (ev.kind === 'certificate.reinstated') {
96
- if (ev.reason !== null) out.push('certificate reinstatement carries no reason');
97
- } else if (ev.reason !== null && (typeof ev.reason !== 'string' || !ev.reason)) out.push('event reason must be null or a non-empty string');
98
- if (ev.kind === 'threat.signature' || ev.kind === 'threat.retracted') out.push(...threatRefReasons(ev.ref));
99
- if (ev.kind === 'threat.signature' && (typeof ev.reason !== 'string' || !ev.reason)) out.push('a threat signature needs a label in reason');
100
- if (ev.kind === 'supervision.suspended' || ev.kind === 'supervision.lifted') {
101
- out.push(...supervisionScopeReasons(ev.ref));
102
- if (typeof ev.reason !== 'string' || !ev.reason) out.push('a supervision event needs a reason');
103
- if (Array.isArray(ev.evidence) && new Set(ev.evidence).size < 2) out.push('a supervision event needs at least two evidence hashes (the two approvals)');
104
- }
105
- return out;
106
- }
107
-
108
- // ---------------------------------------------------------------------------------- //
109
- // Supervision: a regulator suspends or lifts an agent, every agent of an owner, or a system
110
- // ---------------------------------------------------------------------------------- //
111
-
112
- const SYSTEM_KEY = /^[A-Za-z0-9._-]{1,128}$/;
113
-
114
- /**
115
- * Why a supervision `ref` (the scope) is malformed. `agent` covers the subject agent DID,
116
- * `owner` covers every agent the subject owner DID delegated to, `system:<key>` covers the
117
- * agents of that registered AI system of the subject owner.
118
- */
119
- export function supervisionScopeReasons(ref: unknown): string[] {
120
- if (ref === 'agent' || ref === 'owner') return [];
121
- const m = typeof ref === 'string' ? /^system:(.*)$/s.exec(ref) : null;
122
- if (!m) return ['supervision scope must be agent, owner or system:<key>'];
123
- return SYSTEM_KEY.test(m[1]!) ? [] : ['supervision system key is invalid'];
124
- }
125
-
126
- export type SupervisionScope = 'agent' | 'owner' | { system: string };
127
-
128
- /**
129
- * Suspend or lift. `approvals` are the hashes of the two (or more) signed approval records, so
130
- * the feed shows that more than one person decided. No personal data in `reason`: the feed is public.
131
- */
132
- export function supervisionEvent(s: {
133
- action: 'suspend' | 'lift'; subject: string; scope: SupervisionScope; reason: string; ts: string;
134
- approvals: string[]; evidence?: string[];
135
- }): StatusEvent {
136
- if (s.action !== 'suspend' && s.action !== 'lift') throw new Error('status-feed: action must be suspend or lift');
137
- if (!Array.isArray(s.approvals) || new Set(s.approvals).size < 2) throw new Error('status-feed: a supervision event needs two distinct approvals');
138
- const ref = typeof s.scope === 'string' ? s.scope : `system:${s.scope?.system}`;
139
- const kind = s.action === 'suspend' ? 'supervision.suspended' : 'supervision.lifted';
140
- return normalize({ kind, subject: s.subject, ref, ts: s.ts, reason: s.reason, evidence: [...s.approvals, ...(s.evidence ?? [])] });
141
- }
142
-
143
- export interface Suspension { subject: string; ref: string; reason: string; ts: string; seq: number }
144
-
145
- /**
146
- * Suspensions in force after replaying the feed in order: the latest event per subject and
147
- * scope wins. Verify the feed first (`verifyFeed`); this does not check signatures.
148
- */
149
- export function activeSuspensions(entries: FeedEntry[]): Suspension[] {
150
- const state = new Map<string, Suspension | null>();
151
- for (const e of entries) {
152
- const ev = e.event;
153
- if (ev.kind !== 'supervision.suspended' && ev.kind !== 'supervision.lifted') continue;
154
- if (supervisionScopeReasons(ev.ref).length) continue;
155
- const key = `${ev.subject} ${ev.ref}`;
156
- state.set(key, ev.kind === 'supervision.suspended' ? { subject: ev.subject, ref: ev.ref, reason: ev.reason ?? '', ts: ev.ts, seq: e.seq } : null);
157
- }
158
- return [...state.values()].filter((x): x is Suspension => x !== null).sort((a, b) => a.seq - b.seq);
159
- }
160
-
161
- /** The first suspension covering an agent (by its own DID, its owner, or its system), or null. */
162
- export function suspensionFor(suspensions: Suspension[], who: { agent: string; owner?: string; system?: string }): Suspension | null {
163
- for (const s of suspensions) {
164
- if (s.ref === 'agent' && s.subject === who.agent) return s;
165
- if (s.ref === 'owner' && who.owner && s.subject === who.owner) return s;
166
- if (who.owner && who.system && s.subject === who.owner && s.ref === `system:${who.system}`) return s;
167
- }
168
- return null;
169
- }
170
-
171
- // ---------------------------------------------------------------------------------- //
172
- // Threat signatures: a threat one member blocked, shared so every member blocks it too
173
- // ---------------------------------------------------------------------------------- //
174
-
175
- const THREAT_TARGET = /^[A-Za-z0-9._:*-]{1,128}$/;
176
- const THREAT_TEXT = /^[\x21-\x7e][\x20-\x7e]{2,198}[\x21-\x7e]$/;
177
-
178
- /**
179
- * Why a threat `ref` is malformed. `target:<pattern>` blocks actions whose target the scope
180
- * pattern covers; `contains:<text>` blocks actions whose arguments contain the text, ignoring
181
- * ASCII case. The text is 4 to 200 printable ASCII characters with no surrounding spaces: plain
182
- * text, never a regular expression, so a feed entry cannot make a member's matcher slow.
183
- */
184
- export function threatRefReasons(ref: unknown): string[] {
185
- const m = typeof ref === 'string' ? /^(target|contains):(.*)$/s.exec(ref) : null;
186
- if (!m) return ['threat ref must be target:<pattern> or contains:<text>'];
187
- if (m[1] === 'target' && !THREAT_TARGET.test(m[2]!)) return ['threat target pattern is invalid'];
188
- if (m[1] === 'contains' && !THREAT_TEXT.test(m[2]!)) return ['threat text must be 4 to 200 printable ASCII characters without surrounding spaces'];
189
- return [];
190
- }
191
-
192
- /** A new threat signature, citing the evidence behind it (for example the blocking guard decision receipt). */
193
- export function threatSignatureEvent(t: { match: 'target' | 'contains'; value: string; reporter: string; label: string; ts: string; evidence: string[] }): StatusEvent {
194
- if (t.match !== 'target' && t.match !== 'contains') throw new Error('status-feed: match must be target or contains');
195
- return normalize({ kind: 'threat.signature', subject: t.reporter, ref: `${t.match}:${t.value}`, ts: t.ts, reason: t.label, evidence: t.evidence });
196
- }
197
-
198
- /** Withdraw a signature (for example a false positive). A later `threat.signature` with the same ref restores it. */
199
- export function threatRetractionEvent(t: { ref: string; reporter: string; ts: string; evidence: string[]; reason?: string | null }): StatusEvent {
200
- return normalize({ kind: 'threat.retracted', subject: t.reporter, ref: t.ref, ts: t.ts, reason: t.reason ?? null, evidence: t.evidence });
201
- }
202
-
203
- export interface ThreatSignature { ref: string; match: 'target' | 'contains'; value: string; label: string; seq: number }
204
-
205
- /**
206
- * The signatures in force after replaying the feed in order: the latest event per ref wins.
207
- * Verify the feed first (`verifyFeed`); this does not check signatures.
208
- */
209
- export function activeThreatSignatures(entries: FeedEntry[]): ThreatSignature[] {
210
- const state = new Map<string, ThreatSignature | null>();
211
- for (const e of entries) {
212
- const ev = e.event;
213
- if (ev.kind === 'threat.signature' && threatRefReasons(ev.ref).length === 0) {
214
- const i = ev.ref.indexOf(':');
215
- state.set(ev.ref, { ref: ev.ref, match: ev.ref.slice(0, i) as 'target' | 'contains', value: ev.ref.slice(i + 1), label: ev.reason ?? '', seq: e.seq });
216
- } else if (ev.kind === 'threat.retracted') state.set(ev.ref, null);
217
- }
218
- return [...state.values()].filter((x): x is ThreatSignature => x !== null).sort((a, b) => a.seq - b.seq);
219
- }
220
-
221
- const asciiLower = (s: string) => s.replace(/[A-Z]/g, (c) => String.fromCharCode(c.charCodeAt(0) + 32));
222
-
223
- /** The first signature that matches an action, or null. `text` is the action's arguments as text. */
224
- export function matchThreat(signatures: ThreatSignature[], action: { target: string; text?: string }): ThreatSignature | null {
225
- const text = asciiLower(action.text ?? '');
226
- for (const sig of signatures) {
227
- if (sig.match === 'target' ? scopeCovers(sig.value, action.target) : text.includes(asciiLower(sig.value))) return sig;
228
- }
229
- return null;
230
- }
231
-
232
- function normalize(e: StatusEvent): StatusEvent {
233
- return {
234
- kind: e.kind, subject: e.subject, ref: e.ref, ts: e.ts, reason: e.reason ?? null,
235
- evidence: Array.isArray(e.evidence) ? [...new Set(e.evidence)].sort() : e.evidence,
236
- };
237
- }
238
-
239
- /** The last entry's position, or null for an empty feed. */
240
- export function feedHead(entries: FeedEntry[]): FeedHead | null {
241
- const last = entries[entries.length - 1];
242
- return last ? { seq: last.seq, hash: entryHash(last) } : null;
243
- }
244
-
245
- /**
246
- * Sign the next entry of `feed` and return it with the new head. Pure: the caller appends
247
- * `entry` to its stored feed. Refuses a malformed event and an event dated before the head.
248
- */
249
- export function appendEvent(feed: Feed, event: StatusEvent, signerKey: Uint8Array): { entry: FeedEntry; head: FeedHead } {
250
- if (typeof feed?.jurisdiction !== 'string' || !feed.jurisdiction) throw new Error('status-feed: feed.jurisdiction is required');
251
- const ev = normalize(event);
252
- const reasons = eventReasons(ev);
253
- if (reasons.length) throw new Error(`status-feed: ${reasons.join('; ')}`);
254
- const last = feed.entries[feed.entries.length - 1];
255
- if (last && last.jurisdiction !== feed.jurisdiction) throw new Error('status-feed: the feed holds another jurisdiction');
256
- if (last && ms(ev.ts) < ms(last.event.ts)) throw new Error('status-feed: event is dated before the feed head');
257
- const entry = signObject({
258
- v: 1 as const, type: FEED_TYPE, jurisdiction: feed.jurisdiction,
259
- seq: last ? last.seq + 1 : 1, prev: last ? entryHash(last) : null, event: ev,
260
- }, signerKey);
261
- return { entry, head: { seq: entry.seq, hash: entryHash(entry) } };
262
- }
263
-
264
- export interface VerifyFeedOptions {
265
- /** The DIDs allowed to sign entries (key rotation: list old and new). */
266
- signers: string[];
267
- /** Expected jurisdiction; defaults to the first entry's. */
268
- jurisdiction?: string;
269
- /** A trusted earlier head, to verify a suffix such as `feedSince(entries, after.seq)`. */
270
- after?: FeedHead;
271
- }
272
-
273
- export interface VerifyFeedResult { ok: boolean; reasons: string[]; head: FeedHead | null }
274
-
275
- /** Chain continuity, sequence without gaps, signatures by allowed signers, non-decreasing time, well-formed events. */
276
- export function verifyFeed(entries: FeedEntry[], opts: VerifyFeedOptions): VerifyFeedResult {
277
- const reasons: string[] = [];
278
- if (!Array.isArray(entries)) return { ok: false, reasons: ['feed is not a list'], head: null };
279
- if (!Array.isArray(opts?.signers) || !opts.signers.length) reasons.push('no signers supplied: signer NOT checked');
280
- const jurisdiction = opts?.jurisdiction ?? (entries[0] as FeedEntry | undefined)?.jurisdiction;
281
- let prevHash: string | null = opts?.after?.hash ?? null;
282
- let prevSeq = opts?.after?.seq ?? 0;
283
- let prevTs = NaN;
284
- entries.forEach((e, i) => {
285
- const r = (m: string) => reasons.push(`entry ${i}: ${m}`);
286
- if (!e || typeof e !== 'object' || e.v !== 1 || e.type !== FEED_TYPE) { r('not a status feed entry (v1)'); prevHash = null; return; }
287
- const keys = Object.keys(e).sort().join(',');
288
- if (keys !== 'event,jurisdiction,prev,seq,sig,signer,type,v') r('entry has unexpected or missing fields');
289
- if (!verifySignedObject(e)) r('bad signature');
290
- else if (opts?.signers?.length && !opts.signers.includes(e.signer)) r('signed by a key that is not an allowed feed signer');
291
- if (e.jurisdiction !== jurisdiction) r('entry is for another jurisdiction');
292
- if (e.seq !== prevSeq + 1) r(`sequence gap: expected ${prevSeq + 1}, got ${String(e.seq)}`);
293
- if (e.prev !== prevHash) r('chain break: prev does not match the previous entry');
294
- for (const m of eventReasons(e.event)) r(m);
295
- const t = ms(e.event?.ts);
296
- if (t < prevTs) r('time goes backwards');
297
- if (!Number.isNaN(t)) prevTs = t;
298
- prevSeq = typeof e.seq === 'number' ? e.seq : prevSeq + 1;
299
- prevHash = entryHash(e);
300
- });
301
- const head = entries.length ? feedHead(entries) : opts?.after ?? null;
302
- return { ok: reasons.length === 0, reasons, head };
303
- }
304
-
305
- /** Entries after sequence number `seq` (0 = all), for a reader catching up. */
306
- export function feedSince(entries: FeedEntry[], seq: number): FeedEntry[] {
307
- return entries.filter((e) => e.seq > seq);
308
- }
309
-
310
- // ---------------------------------------------------------------------------------- //
311
- // Event builders: each derives `ref` and `evidence` from the record it reports
312
- // ---------------------------------------------------------------------------------- //
313
-
314
- /** A Ledger delegation revocation (`createRevocation` / `submitRevocation`). The record must verify. */
315
- export function revocationEvent(record: RevocationRecord, opts: { reason?: string | null } = {}): StatusEvent {
316
- if (!verifyRevocation(record)) throw new Error('status-feed: the revocation record does not verify');
317
- return normalize({ kind: 'delegation.revoked', subject: record.cert.subject, ref: certHash(record.cert), ts: record.ts, reason: opts.reason ?? null, evidence: [jcsHash(record)] });
318
- }
319
-
320
- const hashOf = (x: string | object): string => (typeof x === 'string' ? x : jcsHash(x));
321
-
322
- /** A Certify status change. `statusDocument` is the signed `certify.status` document (or its hash) that carries it. */
323
- export function certificateStatusEvent(c: {
324
- certificate: string; holder: string; action: 'suspend' | 'revoke' | 'reinstate';
325
- reason: string | null; since: string; statusDocument: string | object;
326
- }): StatusEvent {
327
- const kind = ({ suspend: 'certificate.suspended', revoke: 'certificate.revoked', reinstate: 'certificate.reinstated' } as const)[c.action];
328
- if (!kind) throw new Error('status-feed: action must be suspend, revoke or reinstate');
329
- return normalize({ kind, subject: c.holder, ref: c.certificate, ts: c.since, reason: c.reason, evidence: [hashOf(c.statusDocument)] });
330
- }
331
-
332
- /** An incident opened or closed, citing the incident report (or its hash). */
333
- export function incidentEvent(i: { action: 'opened' | 'closed'; incident: string; subject: string; report: string | object; ts: string; reason?: string | null }): StatusEvent {
334
- if (i.action !== 'opened' && i.action !== 'closed') throw new Error('status-feed: action must be opened or closed');
335
- return normalize({ kind: `incident.${i.action}`, subject: i.subject, ref: i.incident, ts: i.ts, reason: i.reason ?? null, evidence: [hashOf(i.report)] });
336
- }
337
-
338
- /** A `zanii.jurisdiction` binding issued or expired; `ts` defaults to its `issued_at` / `expires_at`. */
339
- export function jurisdictionEvent(binding: { subject: string; issued_at: string; expires_at: string }, action: 'issued' | 'expired', ts?: string): StatusEvent {
340
- if (action !== 'issued' && action !== 'expired') throw new Error('status-feed: action must be issued or expired');
341
- const h = jcsHash(binding);
342
- return normalize({ kind: `jurisdiction.${action}`, subject: binding.subject, ref: h, ts: ts ?? (action === 'issued' ? binding.issued_at : binding.expires_at), reason: null, evidence: [h] });
343
- }
344
-
345
- // ---------------------------------------------------------------------------------- //
346
- // Publishing
347
- // ---------------------------------------------------------------------------------- //
348
-
349
- export interface RenderOptions { title?: string; id?: string; link?: string; updated?: string }
350
-
351
- const xml = (s: string) => s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&apos;');
352
- const feedId = (j: string) => `urn:zanii:status-feed:${encodeURIComponent(j)}`;
353
- const titleOf = (e: FeedEntry) => `${e.event.kind} ${e.event.subject}`;
354
-
355
- /** Atom 1.0 (RFC 4287). Each entry's content is its canonical JSON, so a reader can verify it. */
356
- export function toAtom(entries: FeedEntry[], opts: RenderOptions = {}): string {
357
- const j = entries[0]?.jurisdiction ?? '';
358
- const id = opts.id ?? feedId(j);
359
- const updated = opts.updated ?? entries[entries.length - 1]?.event.ts ?? '1970-01-01T00:00:00Z';
360
- const lines = [
361
- '<?xml version="1.0" encoding="utf-8"?>',
362
- '<feed xmlns="http://www.w3.org/2005/Atom">',
363
- ` <id>${xml(id)}</id>`,
364
- ` <title>${xml(opts.title ?? `Zanii status feed ${j}`)}</title>`,
365
- ` <updated>${xml(updated)}</updated>`,
366
- ];
367
- if (opts.link) lines.push(` <link rel="self" href="${xml(opts.link)}"/>`);
368
- for (const e of entries) {
369
- lines.push(
370
- ' <entry>',
371
- ` <id>${xml(`${feedId(e.jurisdiction)}:${e.seq}`)}</id>`,
372
- ` <title>${xml(titleOf(e))}</title>`,
373
- ` <updated>${xml(e.event.ts)}</updated>`,
374
- ` <author><name>${xml(e.signer)}</name></author>`,
375
- ` <content type="application/json">${xml(canonicalJson(e))}</content>`,
376
- ' </entry>',
377
- );
378
- }
379
- lines.push('</feed>', '');
380
- return lines.join('\n');
381
- }
382
-
383
- /** JSON Feed 1.1. `_zanii_status_feed` carries the signed entry unchanged. */
384
- export function toJsonFeed(entries: FeedEntry[], opts: RenderOptions = {}): Record<string, unknown> {
385
- const j = entries[0]?.jurisdiction ?? '';
386
- const out: Record<string, unknown> = { version: 'https://jsonfeed.org/version/1.1', title: opts.title ?? `Zanii status feed ${j}` };
387
- if (opts.link) out.feed_url = opts.link;
388
- out.items = entries.map((e) => ({
389
- id: `${feedId(e.jurisdiction)}:${e.seq}`, title: titleOf(e), date_published: e.event.ts,
390
- content_text: canonicalJson(e), _zanii_status_feed: e,
391
- }));
392
- return out;
393
- }
394
-
395
- /**
396
- * The feed head as a Ledger receipt: pass to `agent.record({ target, payload })` (`@zanii/sdk`).
397
- * The receipt's payload hash then commits to the head, and the log's inclusion proof dates it.
398
- */
399
- export function anchorFeedHead(entries: FeedEntry[]): { target: string; payload: Record<string, unknown> } {
400
- const head = feedHead(entries);
401
- if (!head) throw new Error('status-feed: an empty feed has no head to anchor');
402
- return { target: 'regulator.status_feed.head', payload: { _zr_kind: 'status_feed', v: 1, jurisdiction: entries[0]!.jurisdiction, seq: head.seq, head: head.hash } };
403
- }
1
+ /**
2
+ * @zanii/status-feed: one signed, append-only, hash-chained feed of status events per
3
+ * jurisdiction. Each entry names the previous entry's hash and its sequence number, is
4
+ * signed by the feed operator (a regulator or the Ledger operator) and carries the hashes
5
+ * of the evidence behind the event: a delegation revocation, a Certify status document,
6
+ * an incident report, a jurisdiction binding.
7
+ *
8
+ * The feed says that its signer published these events in this order. It does not make
9
+ * the events true: a verifier checks the evidence the hashes name. Anchoring the head as
10
+ * a Ledger receipt (`anchorFeedHead`) fixes the feed's history in the transparency log so
11
+ * the operator cannot rewrite it unseen.
12
+ */
13
+ import { canonicalBytes, certHash, jcsHash, scopeCovers, verifyRevocation, signObject, signObjectAsync, verifySignedObject, type RemoteSigner, type RevocationRecord, type SignedObject } from '@zanii/core';
14
+
15
+ export const FEED_TYPE = 'zanii.status_feed' as const;
16
+
17
+ export const EVENT_KINDS = [
18
+ 'delegation.revoked',
19
+ 'certificate.suspended',
20
+ 'certificate.revoked',
21
+ 'certificate.reinstated',
22
+ 'incident.opened',
23
+ 'incident.closed',
24
+ 'jurisdiction.issued',
25
+ 'jurisdiction.expired',
26
+ 'threat.signature',
27
+ 'threat.retracted',
28
+ 'supervision.suspended',
29
+ 'supervision.lifted',
30
+ ] as const;
31
+ export type EventKind = (typeof EVENT_KINDS)[number];
32
+
33
+ /** Certify status reason codes, versions 1 to 3 (Certify spec/status.md sections 2, 6, 7). */
34
+ export const CERTIFY_REASONS = [
35
+ 'FINGERPRINT_MISMATCH', 'RETEST_OVERDUE', 'RETEST_FAILED', 'INCIDENT', 'APPLICANT_REQUEST',
36
+ 'ISSUER_ERROR', 'LICENCE_WITHDRAWN', 'AUDIT_EXPIRED', 'MARK_MISUSE', 'FALSE_DECLARATION', 'EVIDENCE_LAPSED',
37
+ ] as const;
38
+
39
+ export interface StatusEvent {
40
+ kind: EventKind;
41
+ /** The did:key the event is about (usually the agent). */
42
+ subject: string;
43
+ /** What the event names: a delegation cert hash, a certificate hash, an incident id, a binding hash. */
44
+ ref: string;
45
+ ts: string;
46
+ /** Certify reason code for certificate suspend and revoke; null for reinstate; free text or null otherwise. */
47
+ reason: string | null;
48
+ /** `sha256:` hashes of the evidence; sorted and distinct in the entry. */
49
+ evidence: string[];
50
+ }
51
+
52
+ export type FeedEntry = SignedObject<{
53
+ v: 1;
54
+ type: typeof FEED_TYPE;
55
+ jurisdiction: string;
56
+ seq: number;
57
+ prev: string | null;
58
+ event: StatusEvent;
59
+ }>;
60
+
61
+ export interface FeedHead { seq: number; hash: string }
62
+ export interface Feed { jurisdiction: string; entries: FeedEntry[] }
63
+
64
+ const HASH = /^sha256:[0-9a-f]{64}$/;
65
+ const ISO = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.(\d{1,9}))?(Z|[+-]\d{2}:\d{2})$/;
66
+
67
+ /** Epoch ms of a strict ISO 8601 UTC-or-offset timestamp, or NaN. */
68
+ function ms(ts: unknown): number {
69
+ return typeof ts === 'string' && ISO.test(ts) ? Date.parse(ts) : NaN;
70
+ }
71
+
72
+ const canonicalJson = (x: unknown): string => new TextDecoder().decode(canonicalBytes(x));
73
+
74
+ /** The hash later entries chain to: `jcsHash` of the whole signed entry. */
75
+ export function entryHash(entry: FeedEntry): string {
76
+ return jcsHash(entry);
77
+ }
78
+
79
+ /** Why an event is malformed; empty when it is well formed. */
80
+ export function eventReasons(e: unknown): string[] {
81
+ if (!e || typeof e !== 'object' || Array.isArray(e)) return ['event is not an object'];
82
+ const ev = e as Record<string, unknown>;
83
+ const out: string[] = [];
84
+ const keys = Object.keys(ev).sort().join(',');
85
+ if (keys !== 'evidence,kind,reason,ref,subject,ts') out.push('event has unexpected or missing fields');
86
+ if (!(EVENT_KINDS as readonly unknown[]).includes(ev.kind)) out.push('unknown event kind');
87
+ if (typeof ev.subject !== 'string' || !ev.subject.startsWith('did:')) out.push('event subject is not a DID');
88
+ if (typeof ev.ref !== 'string' || !ev.ref) out.push('event ref is empty');
89
+ if (Number.isNaN(ms(ev.ts))) out.push('event ts is not an ISO timestamp');
90
+ const ok = Array.isArray(ev.evidence) && ev.evidence.length > 0 && ev.evidence.every((h) => typeof h === 'string' && HASH.test(h));
91
+ if (!ok) out.push('event evidence must be a non-empty list of sha256 hashes');
92
+ else if (new Set(ev.evidence as string[]).size !== (ev.evidence as string[]).length || [...(ev.evidence as string[])].sort().join() !== (ev.evidence as string[]).join()) out.push('event evidence is not sorted and distinct');
93
+ if (ev.kind === 'certificate.suspended' || ev.kind === 'certificate.revoked') {
94
+ if (!(CERTIFY_REASONS as readonly unknown[]).includes(ev.reason)) out.push('certificate suspend or revoke needs a Certify reason code');
95
+ } else if (ev.kind === 'certificate.reinstated') {
96
+ if (ev.reason !== null) out.push('certificate reinstatement carries no reason');
97
+ } else if (ev.reason !== null && (typeof ev.reason !== 'string' || !ev.reason)) out.push('event reason must be null or a non-empty string');
98
+ if (ev.kind === 'threat.signature' || ev.kind === 'threat.retracted') out.push(...threatRefReasons(ev.ref));
99
+ if (ev.kind === 'threat.signature' && (typeof ev.reason !== 'string' || !ev.reason)) out.push('a threat signature needs a label in reason');
100
+ if (ev.kind === 'supervision.suspended' || ev.kind === 'supervision.lifted') {
101
+ out.push(...supervisionScopeReasons(ev.ref));
102
+ if (typeof ev.reason !== 'string' || !ev.reason) out.push('a supervision event needs a reason');
103
+ if (Array.isArray(ev.evidence) && new Set(ev.evidence).size < 2) out.push('a supervision event needs at least two evidence hashes (the two approvals)');
104
+ }
105
+ return out;
106
+ }
107
+
108
+ // ---------------------------------------------------------------------------------- //
109
+ // Supervision: a regulator suspends or lifts an agent, every agent of an owner, or a system
110
+ // ---------------------------------------------------------------------------------- //
111
+
112
+ const SYSTEM_KEY = /^[A-Za-z0-9._-]{1,128}$/;
113
+
114
+ /**
115
+ * Why a supervision `ref` (the scope) is malformed. `agent` covers the subject agent DID,
116
+ * `owner` covers every agent the subject owner DID delegated to, `system:<key>` covers the
117
+ * agents of that registered AI system of the subject owner.
118
+ */
119
+ export function supervisionScopeReasons(ref: unknown): string[] {
120
+ if (ref === 'agent' || ref === 'owner') return [];
121
+ const m = typeof ref === 'string' ? /^system:(.*)$/s.exec(ref) : null;
122
+ if (!m) return ['supervision scope must be agent, owner or system:<key>'];
123
+ return SYSTEM_KEY.test(m[1]!) ? [] : ['supervision system key is invalid'];
124
+ }
125
+
126
+ export type SupervisionScope = 'agent' | 'owner' | { system: string };
127
+
128
+ /**
129
+ * Suspend or lift. `approvals` are the hashes of the two (or more) signed approval records, so
130
+ * the feed shows that more than one person decided. No personal data in `reason`: the feed is public.
131
+ */
132
+ export function supervisionEvent(s: {
133
+ action: 'suspend' | 'lift'; subject: string; scope: SupervisionScope; reason: string; ts: string;
134
+ approvals: string[]; evidence?: string[];
135
+ }): StatusEvent {
136
+ if (s.action !== 'suspend' && s.action !== 'lift') throw new Error('status-feed: action must be suspend or lift');
137
+ if (!Array.isArray(s.approvals) || new Set(s.approvals).size < 2) throw new Error('status-feed: a supervision event needs two distinct approvals');
138
+ const ref = typeof s.scope === 'string' ? s.scope : `system:${s.scope?.system}`;
139
+ const kind = s.action === 'suspend' ? 'supervision.suspended' : 'supervision.lifted';
140
+ return normalize({ kind, subject: s.subject, ref, ts: s.ts, reason: s.reason, evidence: [...s.approvals, ...(s.evidence ?? [])] });
141
+ }
142
+
143
+ export interface Suspension { subject: string; ref: string; reason: string; ts: string; seq: number }
144
+
145
+ /**
146
+ * Suspensions in force after replaying the feed in order: the latest event per subject and
147
+ * scope wins. Verify the feed first (`verifyFeed`); this does not check signatures.
148
+ */
149
+ export function activeSuspensions(entries: FeedEntry[]): Suspension[] {
150
+ const state = new Map<string, Suspension | null>();
151
+ for (const e of entries) {
152
+ const ev = e.event;
153
+ if (ev.kind !== 'supervision.suspended' && ev.kind !== 'supervision.lifted') continue;
154
+ if (supervisionScopeReasons(ev.ref).length) continue;
155
+ const key = `${ev.subject} ${ev.ref}`;
156
+ state.set(key, ev.kind === 'supervision.suspended' ? { subject: ev.subject, ref: ev.ref, reason: ev.reason ?? '', ts: ev.ts, seq: e.seq } : null);
157
+ }
158
+ return [...state.values()].filter((x): x is Suspension => x !== null).sort((a, b) => a.seq - b.seq);
159
+ }
160
+
161
+ /** The first suspension covering an agent (by its own DID, its owner, or its system), or null. */
162
+ export function suspensionFor(suspensions: Suspension[], who: { agent: string; owner?: string; system?: string }): Suspension | null {
163
+ for (const s of suspensions) {
164
+ if (s.ref === 'agent' && s.subject === who.agent) return s;
165
+ if (s.ref === 'owner' && who.owner && s.subject === who.owner) return s;
166
+ if (who.owner && who.system && s.subject === who.owner && s.ref === `system:${who.system}`) return s;
167
+ }
168
+ return null;
169
+ }
170
+
171
+ // ---------------------------------------------------------------------------------- //
172
+ // Threat signatures: a threat one member blocked, shared so every member blocks it too
173
+ // ---------------------------------------------------------------------------------- //
174
+
175
+ const THREAT_TARGET = /^[A-Za-z0-9._:*-]{1,128}$/;
176
+ const THREAT_TEXT = /^[\x21-\x7e][\x20-\x7e]{2,198}[\x21-\x7e]$/;
177
+
178
+ /**
179
+ * Why a threat `ref` is malformed. `target:<pattern>` blocks actions whose target the scope
180
+ * pattern covers; `contains:<text>` blocks actions whose arguments contain the text, ignoring
181
+ * ASCII case. The text is 4 to 200 printable ASCII characters with no surrounding spaces: plain
182
+ * text, never a regular expression, so a feed entry cannot make a member's matcher slow.
183
+ */
184
+ export function threatRefReasons(ref: unknown): string[] {
185
+ const m = typeof ref === 'string' ? /^(target|contains):(.*)$/s.exec(ref) : null;
186
+ if (!m) return ['threat ref must be target:<pattern> or contains:<text>'];
187
+ if (m[1] === 'target' && !THREAT_TARGET.test(m[2]!)) return ['threat target pattern is invalid'];
188
+ if (m[1] === 'contains' && !THREAT_TEXT.test(m[2]!)) return ['threat text must be 4 to 200 printable ASCII characters without surrounding spaces'];
189
+ return [];
190
+ }
191
+
192
+ /** A new threat signature, citing the evidence behind it (for example the blocking guard decision receipt). */
193
+ export function threatSignatureEvent(t: { match: 'target' | 'contains'; value: string; reporter: string; label: string; ts: string; evidence: string[] }): StatusEvent {
194
+ if (t.match !== 'target' && t.match !== 'contains') throw new Error('status-feed: match must be target or contains');
195
+ return normalize({ kind: 'threat.signature', subject: t.reporter, ref: `${t.match}:${t.value}`, ts: t.ts, reason: t.label, evidence: t.evidence });
196
+ }
197
+
198
+ /** Withdraw a signature (for example a false positive). A later `threat.signature` with the same ref restores it. */
199
+ export function threatRetractionEvent(t: { ref: string; reporter: string; ts: string; evidence: string[]; reason?: string | null }): StatusEvent {
200
+ return normalize({ kind: 'threat.retracted', subject: t.reporter, ref: t.ref, ts: t.ts, reason: t.reason ?? null, evidence: t.evidence });
201
+ }
202
+
203
+ export interface ThreatSignature { ref: string; match: 'target' | 'contains'; value: string; label: string; seq: number }
204
+
205
+ /**
206
+ * The signatures in force after replaying the feed in order: the latest event per ref wins.
207
+ * Verify the feed first (`verifyFeed`); this does not check signatures.
208
+ */
209
+ export function activeThreatSignatures(entries: FeedEntry[]): ThreatSignature[] {
210
+ const state = new Map<string, ThreatSignature | null>();
211
+ for (const e of entries) {
212
+ const ev = e.event;
213
+ if (ev.kind === 'threat.signature' && threatRefReasons(ev.ref).length === 0) {
214
+ const i = ev.ref.indexOf(':');
215
+ state.set(ev.ref, { ref: ev.ref, match: ev.ref.slice(0, i) as 'target' | 'contains', value: ev.ref.slice(i + 1), label: ev.reason ?? '', seq: e.seq });
216
+ } else if (ev.kind === 'threat.retracted') state.set(ev.ref, null);
217
+ }
218
+ return [...state.values()].filter((x): x is ThreatSignature => x !== null).sort((a, b) => a.seq - b.seq);
219
+ }
220
+
221
+ const asciiLower = (s: string) => s.replace(/[A-Z]/g, (c) => String.fromCharCode(c.charCodeAt(0) + 32));
222
+
223
+ /** The first signature that matches an action, or null. `text` is the action's arguments as text. */
224
+ export function matchThreat(signatures: ThreatSignature[], action: { target: string; text?: string }): ThreatSignature | null {
225
+ const text = asciiLower(action.text ?? '');
226
+ for (const sig of signatures) {
227
+ if (sig.match === 'target' ? scopeCovers(sig.value, action.target) : text.includes(asciiLower(sig.value))) return sig;
228
+ }
229
+ return null;
230
+ }
231
+
232
+ function normalize(e: StatusEvent): StatusEvent {
233
+ return {
234
+ kind: e.kind, subject: e.subject, ref: e.ref, ts: e.ts, reason: e.reason ?? null,
235
+ evidence: Array.isArray(e.evidence) ? [...new Set(e.evidence)].sort() : e.evidence,
236
+ };
237
+ }
238
+
239
+ /** The last entry's position, or null for an empty feed. */
240
+ export function feedHead(entries: FeedEntry[]): FeedHead | null {
241
+ const last = entries[entries.length - 1];
242
+ return last ? { seq: last.seq, hash: entryHash(last) } : null;
243
+ }
244
+
245
+ /**
246
+ * Sign the next entry of `feed` and return it with the new head. Pure: the caller appends
247
+ * `entry` to its stored feed. Refuses a malformed event and an event dated before the head.
248
+ */
249
+ function unsignedEntry(feed: Feed, event: StatusEvent) {
250
+ if (typeof feed?.jurisdiction !== 'string' || !feed.jurisdiction) throw new Error('status-feed: feed.jurisdiction is required');
251
+ const ev = normalize(event);
252
+ const reasons = eventReasons(ev);
253
+ if (reasons.length) throw new Error(`status-feed: ${reasons.join('; ')}`);
254
+ const last = feed.entries[feed.entries.length - 1];
255
+ if (last && last.jurisdiction !== feed.jurisdiction) throw new Error('status-feed: the feed holds another jurisdiction');
256
+ if (last && ms(ev.ts) < ms(last.event.ts)) throw new Error('status-feed: event is dated before the feed head');
257
+ return { v: 1 as const, type: FEED_TYPE, jurisdiction: feed.jurisdiction, seq: last ? last.seq + 1 : 1, prev: last ? entryHash(last) : null, event: ev };
258
+ }
259
+
260
+ export function appendEvent(feed: Feed, event: StatusEvent, signerKey: Uint8Array): { entry: FeedEntry; head: FeedHead } {
261
+ const entry = signObject(unsignedEntry(feed, event), signerKey);
262
+ return { entry, head: { seq: entry.seq, hash: entryHash(entry) } };
263
+ }
264
+
265
+ /** `appendEvent` with a raw key or a remote signer (HSM, KMS): the key need not enter this process. */
266
+ export async function appendEventAsync(feed: Feed, event: StatusEvent, signer: Uint8Array | RemoteSigner): Promise<{ entry: FeedEntry; head: FeedHead }> {
267
+ const entry = await signObjectAsync(unsignedEntry(feed, event), signer);
268
+ return { entry, head: { seq: entry.seq, hash: entryHash(entry) } };
269
+ }
270
+
271
+ export interface VerifyFeedOptions {
272
+ /** The DIDs allowed to sign entries (key rotation: list old and new). */
273
+ signers: string[];
274
+ /** Expected jurisdiction; defaults to the first entry's. */
275
+ jurisdiction?: string;
276
+ /** A trusted earlier head, to verify a suffix such as `feedSince(entries, after.seq)`. */
277
+ after?: FeedHead;
278
+ }
279
+
280
+ export interface VerifyFeedResult { ok: boolean; reasons: string[]; head: FeedHead | null }
281
+
282
+ /** Chain continuity, sequence without gaps, signatures by allowed signers, non-decreasing time, well-formed events. */
283
+ export function verifyFeed(entries: FeedEntry[], opts: VerifyFeedOptions): VerifyFeedResult {
284
+ const reasons: string[] = [];
285
+ if (!Array.isArray(entries)) return { ok: false, reasons: ['feed is not a list'], head: null };
286
+ if (!Array.isArray(opts?.signers) || !opts.signers.length) reasons.push('no signers supplied: signer NOT checked');
287
+ const jurisdiction = opts?.jurisdiction ?? (entries[0] as FeedEntry | undefined)?.jurisdiction;
288
+ let prevHash: string | null = opts?.after?.hash ?? null;
289
+ let prevSeq = opts?.after?.seq ?? 0;
290
+ let prevTs = NaN;
291
+ entries.forEach((e, i) => {
292
+ const r = (m: string) => reasons.push(`entry ${i}: ${m}`);
293
+ if (!e || typeof e !== 'object' || e.v !== 1 || e.type !== FEED_TYPE) { r('not a status feed entry (v1)'); prevHash = null; return; }
294
+ const keys = Object.keys(e).sort().join(',');
295
+ if (keys !== 'event,jurisdiction,prev,seq,sig,signer,type,v') r('entry has unexpected or missing fields');
296
+ if (!verifySignedObject(e)) r('bad signature');
297
+ else if (opts?.signers?.length && !opts.signers.includes(e.signer)) r('signed by a key that is not an allowed feed signer');
298
+ if (e.jurisdiction !== jurisdiction) r('entry is for another jurisdiction');
299
+ if (e.seq !== prevSeq + 1) r(`sequence gap: expected ${prevSeq + 1}, got ${String(e.seq)}`);
300
+ if (e.prev !== prevHash) r('chain break: prev does not match the previous entry');
301
+ for (const m of eventReasons(e.event)) r(m);
302
+ const t = ms(e.event?.ts);
303
+ if (t < prevTs) r('time goes backwards');
304
+ if (!Number.isNaN(t)) prevTs = t;
305
+ prevSeq = typeof e.seq === 'number' ? e.seq : prevSeq + 1;
306
+ prevHash = entryHash(e);
307
+ });
308
+ const head = entries.length ? feedHead(entries) : opts?.after ?? null;
309
+ return { ok: reasons.length === 0, reasons, head };
310
+ }
311
+
312
+ /** Entries after sequence number `seq` (0 = all), for a reader catching up. */
313
+ export function feedSince(entries: FeedEntry[], seq: number): FeedEntry[] {
314
+ return entries.filter((e) => e.seq > seq);
315
+ }
316
+
317
+ // ---------------------------------------------------------------------------------- //
318
+ // Event builders: each derives `ref` and `evidence` from the record it reports
319
+ // ---------------------------------------------------------------------------------- //
320
+
321
+ /** A Ledger delegation revocation (`createRevocation` / `submitRevocation`). The record must verify. */
322
+ export function revocationEvent(record: RevocationRecord, opts: { reason?: string | null } = {}): StatusEvent {
323
+ if (!verifyRevocation(record)) throw new Error('status-feed: the revocation record does not verify');
324
+ return normalize({ kind: 'delegation.revoked', subject: record.cert.subject, ref: certHash(record.cert), ts: record.ts, reason: opts.reason ?? null, evidence: [jcsHash(record)] });
325
+ }
326
+
327
+ const hashOf = (x: string | object): string => (typeof x === 'string' ? x : jcsHash(x));
328
+
329
+ /** A Certify status change. `statusDocument` is the signed `certify.status` document (or its hash) that carries it. */
330
+ export function certificateStatusEvent(c: {
331
+ certificate: string; holder: string; action: 'suspend' | 'revoke' | 'reinstate';
332
+ reason: string | null; since: string; statusDocument: string | object;
333
+ }): StatusEvent {
334
+ const kind = ({ suspend: 'certificate.suspended', revoke: 'certificate.revoked', reinstate: 'certificate.reinstated' } as const)[c.action];
335
+ if (!kind) throw new Error('status-feed: action must be suspend, revoke or reinstate');
336
+ return normalize({ kind, subject: c.holder, ref: c.certificate, ts: c.since, reason: c.reason, evidence: [hashOf(c.statusDocument)] });
337
+ }
338
+
339
+ /** An incident opened or closed, citing the incident report (or its hash). */
340
+ export function incidentEvent(i: { action: 'opened' | 'closed'; incident: string; subject: string; report: string | object; ts: string; reason?: string | null }): StatusEvent {
341
+ if (i.action !== 'opened' && i.action !== 'closed') throw new Error('status-feed: action must be opened or closed');
342
+ return normalize({ kind: `incident.${i.action}`, subject: i.subject, ref: i.incident, ts: i.ts, reason: i.reason ?? null, evidence: [hashOf(i.report)] });
343
+ }
344
+
345
+ /** A `zanii.jurisdiction` binding issued or expired; `ts` defaults to its `issued_at` / `expires_at`. */
346
+ export function jurisdictionEvent(binding: { subject: string; issued_at: string; expires_at: string }, action: 'issued' | 'expired', ts?: string): StatusEvent {
347
+ if (action !== 'issued' && action !== 'expired') throw new Error('status-feed: action must be issued or expired');
348
+ const h = jcsHash(binding);
349
+ return normalize({ kind: `jurisdiction.${action}`, subject: binding.subject, ref: h, ts: ts ?? (action === 'issued' ? binding.issued_at : binding.expires_at), reason: null, evidence: [h] });
350
+ }
351
+
352
+ // ---------------------------------------------------------------------------------- //
353
+ // Publishing
354
+ // ---------------------------------------------------------------------------------- //
355
+
356
+ export interface RenderOptions { title?: string; id?: string; link?: string; updated?: string }
357
+
358
+ const xml = (s: string) => s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&apos;');
359
+ const feedId = (j: string) => `urn:zanii:status-feed:${encodeURIComponent(j)}`;
360
+ const titleOf = (e: FeedEntry) => `${e.event.kind} ${e.event.subject}`;
361
+
362
+ /** Atom 1.0 (RFC 4287). Each entry's content is its canonical JSON, so a reader can verify it. */
363
+ export function toAtom(entries: FeedEntry[], opts: RenderOptions = {}): string {
364
+ const j = entries[0]?.jurisdiction ?? '';
365
+ const id = opts.id ?? feedId(j);
366
+ const updated = opts.updated ?? entries[entries.length - 1]?.event.ts ?? '1970-01-01T00:00:00Z';
367
+ const lines = [
368
+ '<?xml version="1.0" encoding="utf-8"?>',
369
+ '<feed xmlns="http://www.w3.org/2005/Atom">',
370
+ ` <id>${xml(id)}</id>`,
371
+ ` <title>${xml(opts.title ?? `Zanii status feed ${j}`)}</title>`,
372
+ ` <updated>${xml(updated)}</updated>`,
373
+ ];
374
+ if (opts.link) lines.push(` <link rel="self" href="${xml(opts.link)}"/>`);
375
+ for (const e of entries) {
376
+ lines.push(
377
+ ' <entry>',
378
+ ` <id>${xml(`${feedId(e.jurisdiction)}:${e.seq}`)}</id>`,
379
+ ` <title>${xml(titleOf(e))}</title>`,
380
+ ` <updated>${xml(e.event.ts)}</updated>`,
381
+ ` <author><name>${xml(e.signer)}</name></author>`,
382
+ ` <content type="application/json">${xml(canonicalJson(e))}</content>`,
383
+ ' </entry>',
384
+ );
385
+ }
386
+ lines.push('</feed>', '');
387
+ return lines.join('\n');
388
+ }
389
+
390
+ /** JSON Feed 1.1. `_zanii_status_feed` carries the signed entry unchanged. */
391
+ export function toJsonFeed(entries: FeedEntry[], opts: RenderOptions = {}): Record<string, unknown> {
392
+ const j = entries[0]?.jurisdiction ?? '';
393
+ const out: Record<string, unknown> = { version: 'https://jsonfeed.org/version/1.1', title: opts.title ?? `Zanii status feed ${j}` };
394
+ if (opts.link) out.feed_url = opts.link;
395
+ out.items = entries.map((e) => ({
396
+ id: `${feedId(e.jurisdiction)}:${e.seq}`, title: titleOf(e), date_published: e.event.ts,
397
+ content_text: canonicalJson(e), _zanii_status_feed: e,
398
+ }));
399
+ return out;
400
+ }
401
+
402
+ /**
403
+ * The feed head as a Ledger receipt: pass to `agent.record({ target, payload })` (`@zanii/sdk`).
404
+ * The receipt's payload hash then commits to the head, and the log's inclusion proof dates it.
405
+ */
406
+ export function anchorFeedHead(entries: FeedEntry[]): { target: string; payload: Record<string, unknown> } {
407
+ const head = feedHead(entries);
408
+ if (!head) throw new Error('status-feed: an empty feed has no head to anchor');
409
+ return { target: 'regulator.status_feed.head', payload: { _zr_kind: 'status_feed', v: 1, jurisdiction: entries[0]!.jurisdiction, seq: head.seq, head: head.hash } };
410
+ }