@zanii/status-feed 0.2.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 +30 -0
- package/dist/index.d.ts +47 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +79 -6
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/index.ts +410 -333
package/README.md
CHANGED
|
@@ -74,8 +74,38 @@ if (verifyFeed(entries, { signers: [operatorDid] }).ok) {
|
|
|
74
74
|
`threatRetractionEvent` withdraws a signature (a false positive); a later `threat.signature` with the
|
|
75
75
|
same ref restores it. `activeThreatSignatures` replays the feed in order, latest event per ref wins.
|
|
76
76
|
|
|
77
|
+
## Supervision
|
|
78
|
+
|
|
79
|
+
A regulator suspends or lifts an agent (`agent`), every agent of an owner (`owner`), or the agents of
|
|
80
|
+
one registered AI system (`system:<key>`). Each event carries a reason code and at least two evidence
|
|
81
|
+
hashes: the signed approval records of the two people who decided. The feed is public, so the reason
|
|
82
|
+
must never contain personal data.
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
import { activeSuspensions, supervisionEvent, suspensionFor, verifyFeed } from '@zanii/status-feed';
|
|
86
|
+
|
|
87
|
+
appendEvent(feed, supervisionEvent({ action: 'suspend', subject: agentDid, scope: 'agent',
|
|
88
|
+
reason: 'UNAUTHORISED_PAYMENTS', ts, approvals: [proposalHash, approvalHash] }), regulatorKey);
|
|
89
|
+
|
|
90
|
+
// An agent or counterparty: verify the feed, then check before acting.
|
|
91
|
+
if (verifyFeed(entries, { signers: [regulatorDid] }).ok) {
|
|
92
|
+
const hit = suspensionFor(activeSuspensions(entries), { agent, owner, system });
|
|
93
|
+
if (hit) throw new Error(`suspended: ${hit.reason}`);
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
`activeSuspensions` replays the feed in order; the latest event per subject and scope wins.
|
|
98
|
+
|
|
77
99
|
## Changelog
|
|
78
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.
|
|
102
|
+
- **0.3.0** (unreleased): supervision events. New kinds `supervision.suspended` and
|
|
103
|
+
`supervision.lifted`, with `supervisionEvent`, `supervisionScopeReasons`, `activeSuspensions` and
|
|
104
|
+
`suspensionFor`. Two distinct approval hashes and a reason are required. Additive: entries of the
|
|
105
|
+
earlier kinds are byte-identical. A 0.2.0 verifier rejects a feed that contains the new kinds
|
|
106
|
+
(unknown event kind), so publish supervision events on a feed whose readers run 0.3.0.
|
|
107
|
+
|
|
108
|
+
|
|
79
109
|
- **0.2.0**: threat signatures. New event kinds `threat.signature` and `threat.retracted`, with
|
|
80
110
|
`threatSignatureEvent`, `threatRetractionEvent`, `threatRefReasons`, `activeThreatSignatures` and
|
|
81
111
|
`matchThreat`. Additive: entries of the 0.1.0 kinds are byte-identical. A 0.1.0 verifier rejects a
|
package/dist/index.d.ts
CHANGED
|
@@ -10,9 +10,9 @@
|
|
|
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
|
-
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"];
|
|
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];
|
|
17
17
|
/** Certify status reason codes, versions 1 to 3 (Certify spec/status.md sections 2, 6, 7). */
|
|
18
18
|
export declare const CERTIFY_REASONS: readonly ["FINGERPRINT_MISMATCH", "RETEST_OVERDUE", "RETEST_FAILED", "INCIDENT", "APPLICANT_REQUEST", "ISSUER_ERROR", "LICENCE_WITHDRAWN", "AUDIT_EXPIRED", "MARK_MISUSE", "FALSE_DECLARATION", "EVIDENCE_LAPSED"];
|
|
@@ -48,6 +48,46 @@ export interface Feed {
|
|
|
48
48
|
export declare function entryHash(entry: FeedEntry): string;
|
|
49
49
|
/** Why an event is malformed; empty when it is well formed. */
|
|
50
50
|
export declare function eventReasons(e: unknown): string[];
|
|
51
|
+
/**
|
|
52
|
+
* Why a supervision `ref` (the scope) is malformed. `agent` covers the subject agent DID,
|
|
53
|
+
* `owner` covers every agent the subject owner DID delegated to, `system:<key>` covers the
|
|
54
|
+
* agents of that registered AI system of the subject owner.
|
|
55
|
+
*/
|
|
56
|
+
export declare function supervisionScopeReasons(ref: unknown): string[];
|
|
57
|
+
export type SupervisionScope = 'agent' | 'owner' | {
|
|
58
|
+
system: string;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Suspend or lift. `approvals` are the hashes of the two (or more) signed approval records, so
|
|
62
|
+
* the feed shows that more than one person decided. No personal data in `reason`: the feed is public.
|
|
63
|
+
*/
|
|
64
|
+
export declare function supervisionEvent(s: {
|
|
65
|
+
action: 'suspend' | 'lift';
|
|
66
|
+
subject: string;
|
|
67
|
+
scope: SupervisionScope;
|
|
68
|
+
reason: string;
|
|
69
|
+
ts: string;
|
|
70
|
+
approvals: string[];
|
|
71
|
+
evidence?: string[];
|
|
72
|
+
}): StatusEvent;
|
|
73
|
+
export interface Suspension {
|
|
74
|
+
subject: string;
|
|
75
|
+
ref: string;
|
|
76
|
+
reason: string;
|
|
77
|
+
ts: string;
|
|
78
|
+
seq: number;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Suspensions in force after replaying the feed in order: the latest event per subject and
|
|
82
|
+
* scope wins. Verify the feed first (`verifyFeed`); this does not check signatures.
|
|
83
|
+
*/
|
|
84
|
+
export declare function activeSuspensions(entries: FeedEntry[]): Suspension[];
|
|
85
|
+
/** The first suspension covering an agent (by its own DID, its owner, or its system), or null. */
|
|
86
|
+
export declare function suspensionFor(suspensions: Suspension[], who: {
|
|
87
|
+
agent: string;
|
|
88
|
+
owner?: string;
|
|
89
|
+
system?: string;
|
|
90
|
+
}): Suspension | null;
|
|
51
91
|
/**
|
|
52
92
|
* Why a threat `ref` is malformed. `target:<pattern>` blocks actions whose target the scope
|
|
53
93
|
* pattern covers; `contains:<text>` blocks actions whose arguments contain the text, ignoring
|
|
@@ -91,14 +131,15 @@ export declare function matchThreat(signatures: ThreatSignature[], action: {
|
|
|
91
131
|
}): ThreatSignature | null;
|
|
92
132
|
/** The last entry's position, or null for an empty feed. */
|
|
93
133
|
export declare function feedHead(entries: FeedEntry[]): FeedHead | null;
|
|
94
|
-
/**
|
|
95
|
-
* Sign the next entry of `feed` and return it with the new head. Pure: the caller appends
|
|
96
|
-
* `entry` to its stored feed. Refuses a malformed event and an event dated before the head.
|
|
97
|
-
*/
|
|
98
134
|
export declare function appendEvent(feed: Feed, event: StatusEvent, signerKey: Uint8Array): {
|
|
99
135
|
entry: FeedEntry;
|
|
100
136
|
head: FeedHead;
|
|
101
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
|
+
}>;
|
|
102
143
|
export interface VerifyFeedOptions {
|
|
103
144
|
/** The DIDs allowed to sign entries (key rotation: list old and new). */
|
|
104
145
|
signers: string[];
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,
|
|
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',
|
|
@@ -23,6 +23,8 @@ export const EVENT_KINDS = [
|
|
|
23
23
|
'jurisdiction.expired',
|
|
24
24
|
'threat.signature',
|
|
25
25
|
'threat.retracted',
|
|
26
|
+
'supervision.suspended',
|
|
27
|
+
'supervision.lifted',
|
|
26
28
|
];
|
|
27
29
|
/** Certify status reason codes, versions 1 to 3 (Certify spec/status.md sections 2, 6, 7). */
|
|
28
30
|
export const CERTIFY_REASONS = [
|
|
@@ -76,9 +78,75 @@ export function eventReasons(e) {
|
|
|
76
78
|
out.push(...threatRefReasons(ev.ref));
|
|
77
79
|
if (ev.kind === 'threat.signature' && (typeof ev.reason !== 'string' || !ev.reason))
|
|
78
80
|
out.push('a threat signature needs a label in reason');
|
|
81
|
+
if (ev.kind === 'supervision.suspended' || ev.kind === 'supervision.lifted') {
|
|
82
|
+
out.push(...supervisionScopeReasons(ev.ref));
|
|
83
|
+
if (typeof ev.reason !== 'string' || !ev.reason)
|
|
84
|
+
out.push('a supervision event needs a reason');
|
|
85
|
+
if (Array.isArray(ev.evidence) && new Set(ev.evidence).size < 2)
|
|
86
|
+
out.push('a supervision event needs at least two evidence hashes (the two approvals)');
|
|
87
|
+
}
|
|
79
88
|
return out;
|
|
80
89
|
}
|
|
81
90
|
// ---------------------------------------------------------------------------------- //
|
|
91
|
+
// Supervision: a regulator suspends or lifts an agent, every agent of an owner, or a system
|
|
92
|
+
// ---------------------------------------------------------------------------------- //
|
|
93
|
+
const SYSTEM_KEY = /^[A-Za-z0-9._-]{1,128}$/;
|
|
94
|
+
/**
|
|
95
|
+
* Why a supervision `ref` (the scope) is malformed. `agent` covers the subject agent DID,
|
|
96
|
+
* `owner` covers every agent the subject owner DID delegated to, `system:<key>` covers the
|
|
97
|
+
* agents of that registered AI system of the subject owner.
|
|
98
|
+
*/
|
|
99
|
+
export function supervisionScopeReasons(ref) {
|
|
100
|
+
if (ref === 'agent' || ref === 'owner')
|
|
101
|
+
return [];
|
|
102
|
+
const m = typeof ref === 'string' ? /^system:(.*)$/s.exec(ref) : null;
|
|
103
|
+
if (!m)
|
|
104
|
+
return ['supervision scope must be agent, owner or system:<key>'];
|
|
105
|
+
return SYSTEM_KEY.test(m[1]) ? [] : ['supervision system key is invalid'];
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Suspend or lift. `approvals` are the hashes of the two (or more) signed approval records, so
|
|
109
|
+
* the feed shows that more than one person decided. No personal data in `reason`: the feed is public.
|
|
110
|
+
*/
|
|
111
|
+
export function supervisionEvent(s) {
|
|
112
|
+
if (s.action !== 'suspend' && s.action !== 'lift')
|
|
113
|
+
throw new Error('status-feed: action must be suspend or lift');
|
|
114
|
+
if (!Array.isArray(s.approvals) || new Set(s.approvals).size < 2)
|
|
115
|
+
throw new Error('status-feed: a supervision event needs two distinct approvals');
|
|
116
|
+
const ref = typeof s.scope === 'string' ? s.scope : `system:${s.scope?.system}`;
|
|
117
|
+
const kind = s.action === 'suspend' ? 'supervision.suspended' : 'supervision.lifted';
|
|
118
|
+
return normalize({ kind, subject: s.subject, ref, ts: s.ts, reason: s.reason, evidence: [...s.approvals, ...(s.evidence ?? [])] });
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Suspensions in force after replaying the feed in order: the latest event per subject and
|
|
122
|
+
* scope wins. Verify the feed first (`verifyFeed`); this does not check signatures.
|
|
123
|
+
*/
|
|
124
|
+
export function activeSuspensions(entries) {
|
|
125
|
+
const state = new Map();
|
|
126
|
+
for (const e of entries) {
|
|
127
|
+
const ev = e.event;
|
|
128
|
+
if (ev.kind !== 'supervision.suspended' && ev.kind !== 'supervision.lifted')
|
|
129
|
+
continue;
|
|
130
|
+
if (supervisionScopeReasons(ev.ref).length)
|
|
131
|
+
continue;
|
|
132
|
+
const key = `${ev.subject} ${ev.ref}`;
|
|
133
|
+
state.set(key, ev.kind === 'supervision.suspended' ? { subject: ev.subject, ref: ev.ref, reason: ev.reason ?? '', ts: ev.ts, seq: e.seq } : null);
|
|
134
|
+
}
|
|
135
|
+
return [...state.values()].filter((x) => x !== null).sort((a, b) => a.seq - b.seq);
|
|
136
|
+
}
|
|
137
|
+
/** The first suspension covering an agent (by its own DID, its owner, or its system), or null. */
|
|
138
|
+
export function suspensionFor(suspensions, who) {
|
|
139
|
+
for (const s of suspensions) {
|
|
140
|
+
if (s.ref === 'agent' && s.subject === who.agent)
|
|
141
|
+
return s;
|
|
142
|
+
if (s.ref === 'owner' && who.owner && s.subject === who.owner)
|
|
143
|
+
return s;
|
|
144
|
+
if (who.owner && who.system && s.subject === who.owner && s.ref === `system:${who.system}`)
|
|
145
|
+
return s;
|
|
146
|
+
}
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
// ---------------------------------------------------------------------------------- //
|
|
82
150
|
// Threat signatures: a threat one member blocked, shared so every member blocks it too
|
|
83
151
|
// ---------------------------------------------------------------------------------- //
|
|
84
152
|
const THREAT_TARGET = /^[A-Za-z0-9._:*-]{1,128}$/;
|
|
@@ -151,7 +219,7 @@ export function feedHead(entries) {
|
|
|
151
219
|
* Sign the next entry of `feed` and return it with the new head. Pure: the caller appends
|
|
152
220
|
* `entry` to its stored feed. Refuses a malformed event and an event dated before the head.
|
|
153
221
|
*/
|
|
154
|
-
|
|
222
|
+
function unsignedEntry(feed, event) {
|
|
155
223
|
if (typeof feed?.jurisdiction !== 'string' || !feed.jurisdiction)
|
|
156
224
|
throw new Error('status-feed: feed.jurisdiction is required');
|
|
157
225
|
const ev = normalize(event);
|
|
@@ -163,10 +231,15 @@ export function appendEvent(feed, event, signerKey) {
|
|
|
163
231
|
throw new Error('status-feed: the feed holds another jurisdiction');
|
|
164
232
|
if (last && ms(ev.ts) < ms(last.event.ts))
|
|
165
233
|
throw new Error('status-feed: event is dated before the feed head');
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
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);
|
|
170
243
|
return { entry, head: { seq: entry.seq, hash: entryHash(entry) } };
|
|
171
244
|
}
|
|
172
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
|
+
"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.
|
|
29
|
+
"@zanii/core": "^0.5.7"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"@noble/curves": "^1.8.1",
|
package/src/index.ts
CHANGED
|
@@ -1,333 +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
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
if (
|
|
86
|
-
if (
|
|
87
|
-
if (
|
|
88
|
-
|
|
89
|
-
if (
|
|
90
|
-
|
|
91
|
-
if (
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
if (ev.reason
|
|
95
|
-
} else if (ev.
|
|
96
|
-
|
|
97
|
-
if (ev.
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
function
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
if (
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
export interface
|
|
204
|
-
|
|
205
|
-
/**
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
const
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
if (
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
if (
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
const
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
}
|
|
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, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, ''');
|
|
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
|
+
}
|