@substrat-run/engine-protocol 0.1.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/LICENSE +661 -0
- package/README.md +60 -0
- package/dist/index.d.ts +400 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +545 -0
- package/dist/index.js.map +1 -0
- package/package.json +39 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,545 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { dataSubjectId, entityRef, moduleManifest, permissionKey, } from '@substrat-run/contracts';
|
|
3
|
+
import { assertAllowed, ulid, } from '@substrat-run/kernel';
|
|
4
|
+
// ============================================================================
|
|
5
|
+
// The protocol engine (docs/design/engine-protocol.md, extracted at milestone
|
|
6
|
+
// B per decision 27: the second vertical's shape — CykelService's per-bike
|
|
7
|
+
// condition report with a customer counter-signature at pickup — forced the
|
|
8
|
+
// invariants out of ServiceCo's vertical code). The engine owns ONLY the
|
|
9
|
+
// invariants; template CONTENT (which protocols exist, what they contain)
|
|
10
|
+
// is 100% vertical-owned:
|
|
11
|
+
//
|
|
12
|
+
// 1. sign freezes — any write to a signed instance's responses fails
|
|
13
|
+
// 2. content_hash — SHA-256 over template content + latest responses at
|
|
14
|
+
// sign time; verifiable against replayed state
|
|
15
|
+
// 3. counter-sign — an ADDITIONAL signature row on the same frozen
|
|
16
|
+
// content (hash re-verified, never new content);
|
|
17
|
+
// exactly one primary signature per instance
|
|
18
|
+
// 4. append-only — a response edit is a NEW row; history is audit
|
|
19
|
+
// material ("4.2 → 5.1 before signing")
|
|
20
|
+
// 5. version-pinned — templates version immutably; an instance pins
|
|
21
|
+
// (key, version) at instantiation forever
|
|
22
|
+
// 6. void, not delete — a protocol is superseded, never mutated or removed
|
|
23
|
+
//
|
|
24
|
+
// Entity-agnostic: an instance binds to any EntityRef ('workorder' today,
|
|
25
|
+
// anything tomorrow). The vertical declares the `protocol → <parent>` entity
|
|
26
|
+
// relation in ITS manifest — the engine cannot know the vertical's vocabulary.
|
|
27
|
+
// ============================================================================
|
|
28
|
+
export const PROTOCOL_PERM = {
|
|
29
|
+
create: permissionKey.parse('protocol:create'),
|
|
30
|
+
fill: permissionKey.parse('protocol:fill'),
|
|
31
|
+
sign: permissionKey.parse('protocol:sign'),
|
|
32
|
+
countersign: permissionKey.parse('protocol:countersign'),
|
|
33
|
+
read: permissionKey.parse('protocol:read'),
|
|
34
|
+
void: permissionKey.parse('protocol:void'),
|
|
35
|
+
};
|
|
36
|
+
export const protocolManifest = moduleManifest.parse({
|
|
37
|
+
id: '@substrat-run/engine-protocol',
|
|
38
|
+
version: '0.0.1',
|
|
39
|
+
kernelContract: '^0.0.1',
|
|
40
|
+
permissions: [
|
|
41
|
+
{ key: 'protocol:create', description: 'Define protocol templates and start protocol instances on entities' },
|
|
42
|
+
{ key: 'protocol:fill', description: 'Record responses on an open protocol (append-only)' },
|
|
43
|
+
{ key: 'protocol:sign', description: 'Sign a protocol — freezes it forever (separate from fill: the technician fills, the arbetsledare signs)' },
|
|
44
|
+
{ key: 'protocol:countersign', description: 'Counter-sign an already-signed protocol — a second signature on the same frozen content (customer at pickup)' },
|
|
45
|
+
{ key: 'protocol:read', description: 'Read protocol templates, instances, responses and signatures' },
|
|
46
|
+
{ key: 'protocol:void', description: 'Void (supersede) a protocol — never deletes' },
|
|
47
|
+
],
|
|
48
|
+
events: {
|
|
49
|
+
emits: [
|
|
50
|
+
{ type: 'protocol.instantiated', schemaVersion: 1 },
|
|
51
|
+
{ type: 'protocol.response-recorded', schemaVersion: 1 },
|
|
52
|
+
{ type: 'protocol.signed', schemaVersion: 1 },
|
|
53
|
+
{ type: 'protocol.countersigned', schemaVersion: 1 },
|
|
54
|
+
{ type: 'protocol.voided', schemaVersion: 1 },
|
|
55
|
+
],
|
|
56
|
+
consumes: [],
|
|
57
|
+
},
|
|
58
|
+
migrations: { journalDir: './migrations', compatibleFrom: '0.0.1' },
|
|
59
|
+
attachmentTargets: [{ entityType: 'protocol', readPermission: 'protocol:read' }],
|
|
60
|
+
entitlementKey: 'protocol',
|
|
61
|
+
ui: {
|
|
62
|
+
entityViews: [{ entityType: 'protocol', view: './ui/ProtocolPanel' }],
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
export const protocolMigrations = [
|
|
66
|
+
{
|
|
67
|
+
version: '0001-init',
|
|
68
|
+
sql: `
|
|
69
|
+
CREATE TABLE protocol_templates (
|
|
70
|
+
id TEXT PRIMARY KEY,
|
|
71
|
+
key TEXT NOT NULL,
|
|
72
|
+
version INTEGER NOT NULL,
|
|
73
|
+
title TEXT NOT NULL,
|
|
74
|
+
content_json TEXT NOT NULL,
|
|
75
|
+
created_at TEXT NOT NULL,
|
|
76
|
+
UNIQUE (key, version)
|
|
77
|
+
);
|
|
78
|
+
CREATE TABLE protocol_instances (
|
|
79
|
+
id TEXT PRIMARY KEY,
|
|
80
|
+
template_key TEXT NOT NULL,
|
|
81
|
+
template_version INTEGER NOT NULL,
|
|
82
|
+
entity_type TEXT NOT NULL,
|
|
83
|
+
entity_id TEXT NOT NULL,
|
|
84
|
+
status TEXT NOT NULL CHECK (status IN ('open','signed','voided')),
|
|
85
|
+
created_by TEXT NOT NULL,
|
|
86
|
+
created_at TEXT NOT NULL,
|
|
87
|
+
voided_by TEXT,
|
|
88
|
+
voided_reason TEXT,
|
|
89
|
+
voided_at TEXT
|
|
90
|
+
);
|
|
91
|
+
CREATE TABLE protocol_responses (
|
|
92
|
+
id TEXT PRIMARY KEY,
|
|
93
|
+
instance_id TEXT NOT NULL REFERENCES protocol_instances(id),
|
|
94
|
+
item_key TEXT NOT NULL,
|
|
95
|
+
value_json TEXT NOT NULL,
|
|
96
|
+
note TEXT,
|
|
97
|
+
responded_by TEXT NOT NULL,
|
|
98
|
+
responded_at TEXT NOT NULL
|
|
99
|
+
);
|
|
100
|
+
CREATE TABLE protocol_signatures (
|
|
101
|
+
id TEXT PRIMARY KEY,
|
|
102
|
+
instance_id TEXT NOT NULL REFERENCES protocol_instances(id),
|
|
103
|
+
signed_by TEXT NOT NULL,
|
|
104
|
+
kind TEXT NOT NULL CHECK (kind IN ('primary','counter')),
|
|
105
|
+
method TEXT NOT NULL,
|
|
106
|
+
content_hash TEXT NOT NULL,
|
|
107
|
+
evidence_ref TEXT,
|
|
108
|
+
signed_at TEXT NOT NULL
|
|
109
|
+
);
|
|
110
|
+
`,
|
|
111
|
+
},
|
|
112
|
+
];
|
|
113
|
+
// ---------------------------------------------------------------------------
|
|
114
|
+
// Template content SHAPE — engine-owned so fills can be validated against the
|
|
115
|
+
// pinned template. The content VALUES (sections, items, vocabulary,
|
|
116
|
+
// branschprotokoll packs) are written by verticals. v0 item types:
|
|
117
|
+
// check | value (measurement, decimal string) | text.
|
|
118
|
+
// ---------------------------------------------------------------------------
|
|
119
|
+
export const protocolItem = z.object({
|
|
120
|
+
key: z.string().min(1),
|
|
121
|
+
label: z.string().min(1),
|
|
122
|
+
type: z.enum(['check', 'value', 'text']),
|
|
123
|
+
unit: z.string().optional(), // 'MΩ' on measurements
|
|
124
|
+
});
|
|
125
|
+
export const protocolTemplateContent = z.object({
|
|
126
|
+
sections: z
|
|
127
|
+
.array(z.object({ title: z.string().min(1), items: z.array(protocolItem).min(1) }))
|
|
128
|
+
.min(1),
|
|
129
|
+
});
|
|
130
|
+
/** Booleans for checks; strings for measurements/text (decimals stay strings, K-14). */
|
|
131
|
+
const responseValue = z.union([z.boolean(), z.string()]);
|
|
132
|
+
const protocolRef = (id) => ({ entityType: 'protocol', entityId: id });
|
|
133
|
+
function getInstanceRow(ctx, instanceId) {
|
|
134
|
+
const row = ctx.sql.query('SELECT * FROM protocol_instances WHERE id = ?', [instanceId])[0];
|
|
135
|
+
if (!row)
|
|
136
|
+
throw new Error(`protocol instance not found: ${instanceId}`);
|
|
137
|
+
return row;
|
|
138
|
+
}
|
|
139
|
+
function getTemplateRow(ctx, key, version) {
|
|
140
|
+
const row = ctx.sql.query('SELECT * FROM protocol_templates WHERE key = ? AND version = ?', [key, version])[0];
|
|
141
|
+
if (!row)
|
|
142
|
+
throw new Error(`protocol template not found: ${key}@${version}`);
|
|
143
|
+
return row;
|
|
144
|
+
}
|
|
145
|
+
/** Append order is authoritative for "latest wins" — rowid, not ULID (same-ms safe). */
|
|
146
|
+
function getResponseRows(ctx, instanceId) {
|
|
147
|
+
return ctx.sql.query('SELECT * FROM protocol_responses WHERE instance_id = ? ORDER BY rowid', [instanceId]);
|
|
148
|
+
}
|
|
149
|
+
function getSignatureRows(ctx, instanceId) {
|
|
150
|
+
return ctx.sql.query('SELECT * FROM protocol_signatures WHERE instance_id = ? ORDER BY rowid', [instanceId]);
|
|
151
|
+
}
|
|
152
|
+
function latestPerItem(responses) {
|
|
153
|
+
const latest = {};
|
|
154
|
+
for (const r of responses)
|
|
155
|
+
latest[r.item_key] = r; // rowid order → last append wins
|
|
156
|
+
return latest;
|
|
157
|
+
}
|
|
158
|
+
const frozenAnswers = (latest) => Object.fromEntries(Object.entries(latest).map(([k, r]) => [k, JSON.parse(r.value_json)]));
|
|
159
|
+
export async function protocolContentHash(template, latest) {
|
|
160
|
+
const lines = Object.keys(latest)
|
|
161
|
+
.sort()
|
|
162
|
+
.map((k) => `${k}=${latest[k].value_json}\n`)
|
|
163
|
+
.join('');
|
|
164
|
+
const input = `${template.key}@${template.version}\n${template.content_json}\n${lines}`;
|
|
165
|
+
const digest = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(input));
|
|
166
|
+
return Array.from(new Uint8Array(digest), (b) => b.toString(16).padStart(2, '0')).join('');
|
|
167
|
+
}
|
|
168
|
+
// ---------------------------------------------------------------------------
|
|
169
|
+
// THE GUARD PREDICATE (engine-protocol.md §6, kernel-design open question 11):
|
|
170
|
+
// a plain in-scope predicate the vertical composes into its own operations
|
|
171
|
+
// BEFORE calling an engine transition ("obligatorisk för status"). The
|
|
172
|
+
// manifest-declared form is milestone C; until then this call IS the
|
|
173
|
+
// compliance gate — do not remove a call site without a human checkpoint.
|
|
174
|
+
// ---------------------------------------------------------------------------
|
|
175
|
+
export function requireSigned(ctx, entity, templateKey) {
|
|
176
|
+
const signed = ctx.sql.query(`SELECT id FROM protocol_instances
|
|
177
|
+
WHERE entity_type = ? AND entity_id = ? AND template_key = ? AND status = 'signed'
|
|
178
|
+
LIMIT 1`, [entity.entityType, entity.entityId, templateKey])[0];
|
|
179
|
+
if (!signed) {
|
|
180
|
+
throw new Error(`protocol required: '${templateKey}' must be signed before this transition ` +
|
|
181
|
+
`(${entity.entityType} ${entity.entityId})`);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
// ---------------------------------------------------------------------------
|
|
185
|
+
// In-scope functions (K-16) — composable from vertical operations, same
|
|
186
|
+
// transaction. The registered operations below are their default bindings.
|
|
187
|
+
// The CALLER is responsible for the permission check.
|
|
188
|
+
// ---------------------------------------------------------------------------
|
|
189
|
+
export const defineTemplateInput = z.object({
|
|
190
|
+
key: z.string().min(1),
|
|
191
|
+
title: z.string().min(1),
|
|
192
|
+
content: protocolTemplateContent,
|
|
193
|
+
});
|
|
194
|
+
/**
|
|
195
|
+
* Templates version immutably: same key + new content = next version, the
|
|
196
|
+
* old row is never touched. Editing a template never rewrites what a signed
|
|
197
|
+
* document referred to.
|
|
198
|
+
*/
|
|
199
|
+
export function defineTemplate(ctx, rawInput) {
|
|
200
|
+
const input = defineTemplateInput.parse(rawInput);
|
|
201
|
+
const version = ctx.sql.query('SELECT COALESCE(MAX(version), 0) + 1 AS v FROM protocol_templates WHERE key = ?', [input.key])[0]?.v ?? 1;
|
|
202
|
+
const id = ulid();
|
|
203
|
+
ctx.sql.exec(`INSERT INTO protocol_templates (id, key, version, title, content_json, created_at)
|
|
204
|
+
VALUES (?, ?, ?, ?, ?, ?)`, [id, input.key, version, input.title, JSON.stringify(input.content), new Date().toISOString()]);
|
|
205
|
+
return ctx.sql.query('SELECT * FROM protocol_templates WHERE id = ?', [
|
|
206
|
+
id,
|
|
207
|
+
])[0];
|
|
208
|
+
}
|
|
209
|
+
/** Latest version per key — the instantiation picker's list. */
|
|
210
|
+
export function listTemplates(ctx) {
|
|
211
|
+
return ctx.sql.query(`SELECT t.* FROM protocol_templates t
|
|
212
|
+
WHERE t.version = (SELECT MAX(version) FROM protocol_templates WHERE key = t.key)
|
|
213
|
+
ORDER BY t.key`);
|
|
214
|
+
}
|
|
215
|
+
export const instantiateProtocolInput = z.object({
|
|
216
|
+
templateKey: z.string().min(1),
|
|
217
|
+
entity: entityRef,
|
|
218
|
+
});
|
|
219
|
+
/**
|
|
220
|
+
* Pins the latest template version at instantiation — forever (invariant 5).
|
|
221
|
+
* One OPEN instance per (template, entity). Which entity types may carry
|
|
222
|
+
* which protocols, and when, is vertical policy — enforced by the caller.
|
|
223
|
+
*/
|
|
224
|
+
export function instantiateProtocol(ctx, rawInput) {
|
|
225
|
+
const input = instantiateProtocolInput.parse(rawInput);
|
|
226
|
+
const template = ctx.sql.query('SELECT * FROM protocol_templates WHERE key = ? ORDER BY version DESC LIMIT 1', [input.templateKey])[0];
|
|
227
|
+
if (!template)
|
|
228
|
+
throw new Error(`protocol template not found: ${input.templateKey}`);
|
|
229
|
+
const dup = ctx.sql.query(`SELECT id FROM protocol_instances
|
|
230
|
+
WHERE entity_type = ? AND entity_id = ? AND template_key = ? AND status = 'open' LIMIT 1`, [input.entity.entityType, input.entity.entityId, input.templateKey])[0];
|
|
231
|
+
if (dup) {
|
|
232
|
+
throw new Error(`protocol '${input.templateKey}' already open on this ${input.entity.entityType}`);
|
|
233
|
+
}
|
|
234
|
+
const id = ulid();
|
|
235
|
+
ctx.sql.exec(`INSERT INTO protocol_instances
|
|
236
|
+
(id, template_key, template_version, entity_type, entity_id, status, created_by, created_at)
|
|
237
|
+
VALUES (?, ?, ?, ?, ?, 'open', ?, ?)`, [
|
|
238
|
+
id,
|
|
239
|
+
template.key,
|
|
240
|
+
template.version,
|
|
241
|
+
input.entity.entityType,
|
|
242
|
+
input.entity.entityId,
|
|
243
|
+
ctx.principal,
|
|
244
|
+
new Date().toISOString(),
|
|
245
|
+
]);
|
|
246
|
+
// The permission walk (portal counter-sign, per-entity reads) flows along
|
|
247
|
+
// this edge; the vertical declares `protocol → <parent>` in its manifest.
|
|
248
|
+
ctx.link(protocolRef(id), input.entity);
|
|
249
|
+
ctx.emit({
|
|
250
|
+
type: 'protocol.instantiated',
|
|
251
|
+
schemaVersion: 1,
|
|
252
|
+
entity: protocolRef(id),
|
|
253
|
+
piiClass: 'none',
|
|
254
|
+
payload: {
|
|
255
|
+
instanceId: id,
|
|
256
|
+
templateKey: template.key,
|
|
257
|
+
templateVersion: template.version,
|
|
258
|
+
title: template.title,
|
|
259
|
+
entity: input.entity,
|
|
260
|
+
},
|
|
261
|
+
});
|
|
262
|
+
return getInstanceRow(ctx, id);
|
|
263
|
+
}
|
|
264
|
+
export const fillProtocolInput = z.object({
|
|
265
|
+
instanceId: z.string().min(1),
|
|
266
|
+
itemKey: z.string().min(1),
|
|
267
|
+
value: responseValue,
|
|
268
|
+
note: z.string().optional(),
|
|
269
|
+
});
|
|
270
|
+
export function fillProtocol(ctx, rawInput) {
|
|
271
|
+
const input = fillProtocolInput.parse(rawInput);
|
|
272
|
+
const instance = getInstanceRow(ctx, input.instanceId);
|
|
273
|
+
// Invariant 1+4: responses bind to an OPEN instance only, and always append.
|
|
274
|
+
if (instance.status !== 'open') {
|
|
275
|
+
throw new Error(`protocol is ${instance.status}: responses are frozen (append-only history kept)`);
|
|
276
|
+
}
|
|
277
|
+
const template = getTemplateRow(ctx, instance.template_key, instance.template_version);
|
|
278
|
+
const content = protocolTemplateContent.parse(JSON.parse(template.content_json));
|
|
279
|
+
const item = content.sections.flatMap((s) => s.items).find((i) => i.key === input.itemKey);
|
|
280
|
+
if (!item) {
|
|
281
|
+
throw new Error(`unknown item '${input.itemKey}' in template ${instance.template_key}@${instance.template_version}`);
|
|
282
|
+
}
|
|
283
|
+
if (item.type === 'check' && typeof input.value !== 'boolean') {
|
|
284
|
+
throw new Error(`item '${item.key}' is a check: value must be boolean`);
|
|
285
|
+
}
|
|
286
|
+
if (item.type !== 'check' && typeof input.value !== 'string') {
|
|
287
|
+
throw new Error(`item '${item.key}' is a ${item.type}: value must be a string`);
|
|
288
|
+
}
|
|
289
|
+
const id = ulid();
|
|
290
|
+
ctx.sql.exec(`INSERT INTO protocol_responses
|
|
291
|
+
(id, instance_id, item_key, value_json, note, responded_by, responded_at)
|
|
292
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)`, [
|
|
293
|
+
id,
|
|
294
|
+
instance.id,
|
|
295
|
+
input.itemKey,
|
|
296
|
+
JSON.stringify(input.value),
|
|
297
|
+
input.note ?? null,
|
|
298
|
+
ctx.principal,
|
|
299
|
+
new Date().toISOString(),
|
|
300
|
+
]);
|
|
301
|
+
ctx.emit({
|
|
302
|
+
type: 'protocol.response-recorded',
|
|
303
|
+
schemaVersion: 1,
|
|
304
|
+
entity: protocolRef(instance.id),
|
|
305
|
+
piiClass: 'pseudonymous',
|
|
306
|
+
subjectId: dataSubjectId.parse(ctx.principal),
|
|
307
|
+
payload: {
|
|
308
|
+
instanceId: instance.id,
|
|
309
|
+
responseId: id,
|
|
310
|
+
itemKey: input.itemKey,
|
|
311
|
+
value: input.value,
|
|
312
|
+
entity: { entityType: instance.entity_type, entityId: instance.entity_id },
|
|
313
|
+
},
|
|
314
|
+
});
|
|
315
|
+
return ctx.sql.query('SELECT * FROM protocol_responses WHERE id = ?', [
|
|
316
|
+
id,
|
|
317
|
+
])[0];
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* In-app sign (engine-protocol.md §5): the authenticated principal signs;
|
|
321
|
+
* integrity comes from the hash + immutability + the spine event. Connector
|
|
322
|
+
* methods (bankid/scrive) arrive later through the SAME operation shape with
|
|
323
|
+
* upgraded evidence. Exactly ONE primary signature per instance — enforced by
|
|
324
|
+
* the open → signed transition.
|
|
325
|
+
*/
|
|
326
|
+
export async function signProtocol(ctx, input) {
|
|
327
|
+
const instance = getInstanceRow(ctx, z.string().min(1).parse(input.instanceId));
|
|
328
|
+
if (instance.status !== 'open') {
|
|
329
|
+
throw new Error(`protocol is ${instance.status}: only an open protocol can be signed`);
|
|
330
|
+
}
|
|
331
|
+
const template = getTemplateRow(ctx, instance.template_key, instance.template_version);
|
|
332
|
+
const latest = latestPerItem(getResponseRows(ctx, instance.id));
|
|
333
|
+
const contentHash = await protocolContentHash(template, latest);
|
|
334
|
+
const id = ulid();
|
|
335
|
+
ctx.sql.exec(`INSERT INTO protocol_signatures
|
|
336
|
+
(id, instance_id, signed_by, kind, method, content_hash, evidence_ref, signed_at)
|
|
337
|
+
VALUES (?, ?, ?, 'primary', 'in-app', ?, NULL, ?)`, [id, instance.id, ctx.principal, contentHash, new Date().toISOString()]);
|
|
338
|
+
ctx.sql.exec(`UPDATE protocol_instances SET status = 'signed' WHERE id = ?`, [instance.id]);
|
|
339
|
+
ctx.emit({
|
|
340
|
+
type: 'protocol.signed',
|
|
341
|
+
schemaVersion: 1,
|
|
342
|
+
entity: protocolRef(instance.id),
|
|
343
|
+
piiClass: 'pseudonymous',
|
|
344
|
+
subjectId: dataSubjectId.parse(ctx.principal),
|
|
345
|
+
payload: {
|
|
346
|
+
instanceId: instance.id,
|
|
347
|
+
templateKey: instance.template_key,
|
|
348
|
+
templateVersion: instance.template_version,
|
|
349
|
+
entity: { entityType: instance.entity_type, entityId: instance.entity_id },
|
|
350
|
+
signedBy: ctx.principal,
|
|
351
|
+
method: 'in-app',
|
|
352
|
+
contentHash,
|
|
353
|
+
// fat payload: the frozen answers travel with the event
|
|
354
|
+
responses: frozenAnswers(latest),
|
|
355
|
+
},
|
|
356
|
+
});
|
|
357
|
+
return {
|
|
358
|
+
instance: getInstanceRow(ctx, instance.id),
|
|
359
|
+
signature: getSignatureRows(ctx, instance.id).find((s) => s.id === id),
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Counter-sign (invariant 3): a SECOND signature on the SAME frozen content —
|
|
364
|
+
* the customer at pickup. Requires a signed instance; the content hash is
|
|
365
|
+
* recomputed and must equal the primary signature's hash (frozen content,
|
|
366
|
+
* verified, never assumed). One counter-signature per principal; a principal
|
|
367
|
+
* never counter-signs what they primary-signed.
|
|
368
|
+
*/
|
|
369
|
+
export async function countersignProtocol(ctx, input) {
|
|
370
|
+
const instance = getInstanceRow(ctx, z.string().min(1).parse(input.instanceId));
|
|
371
|
+
if (instance.status !== 'signed') {
|
|
372
|
+
throw new Error(`protocol is ${instance.status}: only a signed (frozen) protocol can be counter-signed`);
|
|
373
|
+
}
|
|
374
|
+
const signatures = getSignatureRows(ctx, instance.id);
|
|
375
|
+
const primary = signatures.find((s) => s.kind === 'primary');
|
|
376
|
+
if (!primary)
|
|
377
|
+
throw new Error(`signed protocol has no primary signature: ${instance.id}`); // corrupt state, fail closed
|
|
378
|
+
if (primary.signed_by === ctx.principal) {
|
|
379
|
+
throw new Error('counter-signature must come from a different principal than the signer');
|
|
380
|
+
}
|
|
381
|
+
if (signatures.some((s) => s.kind === 'counter' && s.signed_by === ctx.principal)) {
|
|
382
|
+
throw new Error('already counter-signed by this principal');
|
|
383
|
+
}
|
|
384
|
+
// Re-run the hash recipe against stored state: the counter-signature binds
|
|
385
|
+
// to verified frozen content, not to a trusted column.
|
|
386
|
+
const template = getTemplateRow(ctx, instance.template_key, instance.template_version);
|
|
387
|
+
const latest = latestPerItem(getResponseRows(ctx, instance.id));
|
|
388
|
+
const contentHash = await protocolContentHash(template, latest);
|
|
389
|
+
if (contentHash !== primary.content_hash) {
|
|
390
|
+
throw new Error(`content hash mismatch on counter-sign: stored ${primary.content_hash}, replayed ${contentHash}`);
|
|
391
|
+
}
|
|
392
|
+
const id = ulid();
|
|
393
|
+
ctx.sql.exec(`INSERT INTO protocol_signatures
|
|
394
|
+
(id, instance_id, signed_by, kind, method, content_hash, evidence_ref, signed_at)
|
|
395
|
+
VALUES (?, ?, ?, 'counter', 'in-app', ?, NULL, ?)`, [id, instance.id, ctx.principal, contentHash, new Date().toISOString()]);
|
|
396
|
+
ctx.emit({
|
|
397
|
+
type: 'protocol.countersigned',
|
|
398
|
+
schemaVersion: 1,
|
|
399
|
+
entity: protocolRef(instance.id),
|
|
400
|
+
piiClass: 'pseudonymous',
|
|
401
|
+
subjectId: dataSubjectId.parse(ctx.principal),
|
|
402
|
+
payload: {
|
|
403
|
+
instanceId: instance.id,
|
|
404
|
+
templateKey: instance.template_key,
|
|
405
|
+
templateVersion: instance.template_version,
|
|
406
|
+
entity: { entityType: instance.entity_type, entityId: instance.entity_id },
|
|
407
|
+
signedBy: primary.signed_by,
|
|
408
|
+
countersignedBy: ctx.principal,
|
|
409
|
+
method: 'in-app',
|
|
410
|
+
contentHash,
|
|
411
|
+
responses: frozenAnswers(latest),
|
|
412
|
+
},
|
|
413
|
+
});
|
|
414
|
+
return {
|
|
415
|
+
instance: getInstanceRow(ctx, instance.id),
|
|
416
|
+
signature: getSignatureRows(ctx, instance.id).find((s) => s.id === id),
|
|
417
|
+
};
|
|
418
|
+
}
|
|
419
|
+
/** Voiding, not deleting: a superseded protocol keeps its rows forever. */
|
|
420
|
+
export function voidProtocol(ctx, input) {
|
|
421
|
+
const reason = z.string().min(1).parse(input.reason);
|
|
422
|
+
const instance = getInstanceRow(ctx, z.string().min(1).parse(input.instanceId));
|
|
423
|
+
if (instance.status === 'voided')
|
|
424
|
+
throw new Error('protocol is already voided');
|
|
425
|
+
ctx.sql.exec(`UPDATE protocol_instances
|
|
426
|
+
SET status = 'voided', voided_by = ?, voided_reason = ?, voided_at = ? WHERE id = ?`, [ctx.principal, reason, new Date().toISOString(), instance.id]);
|
|
427
|
+
ctx.emit({
|
|
428
|
+
type: 'protocol.voided',
|
|
429
|
+
schemaVersion: 1,
|
|
430
|
+
entity: protocolRef(instance.id),
|
|
431
|
+
piiClass: 'pseudonymous',
|
|
432
|
+
subjectId: dataSubjectId.parse(ctx.principal),
|
|
433
|
+
payload: {
|
|
434
|
+
instanceId: instance.id,
|
|
435
|
+
entity: { entityType: instance.entity_type, entityId: instance.entity_id },
|
|
436
|
+
previousStatus: instance.status,
|
|
437
|
+
reason,
|
|
438
|
+
},
|
|
439
|
+
});
|
|
440
|
+
return getInstanceRow(ctx, instance.id);
|
|
441
|
+
}
|
|
442
|
+
export function getProtocol(ctx, instanceId) {
|
|
443
|
+
const instance = getInstanceRow(ctx, instanceId);
|
|
444
|
+
const template = getTemplateRow(ctx, instance.template_key, instance.template_version);
|
|
445
|
+
const responses = getResponseRows(ctx, instance.id);
|
|
446
|
+
const signatures = getSignatureRows(ctx, instance.id);
|
|
447
|
+
return {
|
|
448
|
+
instance,
|
|
449
|
+
template: {
|
|
450
|
+
key: template.key,
|
|
451
|
+
version: template.version,
|
|
452
|
+
title: template.title,
|
|
453
|
+
content: protocolTemplateContent.parse(JSON.parse(template.content_json)),
|
|
454
|
+
},
|
|
455
|
+
responses,
|
|
456
|
+
latest: latestPerItem(responses),
|
|
457
|
+
signature: signatures.find((s) => s.kind === 'primary') ?? null,
|
|
458
|
+
signatures,
|
|
459
|
+
};
|
|
460
|
+
}
|
|
461
|
+
export function listProtocolsForEntity(ctx, entity) {
|
|
462
|
+
const instances = ctx.sql.query(`SELECT * FROM protocol_instances
|
|
463
|
+
WHERE entity_type = ? AND entity_id = ? ORDER BY rowid`, [entity.entityType, entity.entityId]);
|
|
464
|
+
return instances.map((instance) => {
|
|
465
|
+
const template = getTemplateRow(ctx, instance.template_key, instance.template_version);
|
|
466
|
+
const content = protocolTemplateContent.parse(JSON.parse(template.content_json));
|
|
467
|
+
const total = content.sections.reduce((n, s) => n + s.items.length, 0);
|
|
468
|
+
const answered = Object.keys(latestPerItem(getResponseRows(ctx, instance.id))).length;
|
|
469
|
+
const signatures = getSignatureRows(ctx, instance.id);
|
|
470
|
+
const primary = signatures.find((s) => s.kind === 'primary');
|
|
471
|
+
const counter = signatures.filter((s) => s.kind === 'counter').at(-1);
|
|
472
|
+
return {
|
|
473
|
+
instance,
|
|
474
|
+
title: template.title,
|
|
475
|
+
answered,
|
|
476
|
+
total,
|
|
477
|
+
signedBy: primary?.signed_by ?? null,
|
|
478
|
+
signedAt: primary?.signed_at ?? null,
|
|
479
|
+
countersignedBy: counter?.signed_by ?? null,
|
|
480
|
+
countersignedAt: counter?.signed_at ?? null,
|
|
481
|
+
};
|
|
482
|
+
});
|
|
483
|
+
}
|
|
484
|
+
// ---------------------------------------------------------------------------
|
|
485
|
+
// Default operation bindings — each starts with the permission check.
|
|
486
|
+
// Reads and per-instance mutations check per-entity (portal-style walks:
|
|
487
|
+
// role checks still pass at the node; entity-narrowed grants resolve along
|
|
488
|
+
// the vertical-declared parent edges).
|
|
489
|
+
// ---------------------------------------------------------------------------
|
|
490
|
+
const defineTemplateOp = async (ctx, input) => {
|
|
491
|
+
assertAllowed(await ctx.check(PROTOCOL_PERM.create));
|
|
492
|
+
return defineTemplate(ctx, input);
|
|
493
|
+
};
|
|
494
|
+
const listTemplatesOp = async (ctx) => {
|
|
495
|
+
assertAllowed(await ctx.check(PROTOCOL_PERM.read));
|
|
496
|
+
return listTemplates(ctx);
|
|
497
|
+
};
|
|
498
|
+
const instantiateOp = async (ctx, input) => {
|
|
499
|
+
assertAllowed(await ctx.check(PROTOCOL_PERM.create));
|
|
500
|
+
return instantiateProtocol(ctx, {
|
|
501
|
+
templateKey: input.templateKey,
|
|
502
|
+
entity: { entityType: input.entityType, entityId: input.entityId },
|
|
503
|
+
});
|
|
504
|
+
};
|
|
505
|
+
const fillOp = async (ctx, input) => {
|
|
506
|
+
assertAllowed(await ctx.check(PROTOCOL_PERM.fill, protocolRef(input.instanceId)));
|
|
507
|
+
return fillProtocol(ctx, input);
|
|
508
|
+
};
|
|
509
|
+
const signOp = async (ctx, input) => {
|
|
510
|
+
assertAllowed(await ctx.check(PROTOCOL_PERM.sign, protocolRef(input.instanceId)));
|
|
511
|
+
return signProtocol(ctx, input);
|
|
512
|
+
};
|
|
513
|
+
const countersignOp = async (ctx, input) => {
|
|
514
|
+
assertAllowed(await ctx.check(PROTOCOL_PERM.countersign, protocolRef(input.instanceId)));
|
|
515
|
+
return countersignProtocol(ctx, input);
|
|
516
|
+
};
|
|
517
|
+
const voidOp = async (ctx, input) => {
|
|
518
|
+
assertAllowed(await ctx.check(PROTOCOL_PERM.void, protocolRef(input.instanceId)));
|
|
519
|
+
return voidProtocol(ctx, input);
|
|
520
|
+
};
|
|
521
|
+
const getOp = async (ctx, input) => {
|
|
522
|
+
assertAllowed(await ctx.check(PROTOCOL_PERM.read, protocolRef(input.instanceId)));
|
|
523
|
+
return getProtocol(ctx, input.instanceId);
|
|
524
|
+
};
|
|
525
|
+
const listForEntityOp = async (ctx, input) => {
|
|
526
|
+
const entity = entityRef.parse(input);
|
|
527
|
+
assertAllowed(await ctx.check(PROTOCOL_PERM.read, entity));
|
|
528
|
+
return listProtocolsForEntity(ctx, entity);
|
|
529
|
+
};
|
|
530
|
+
export const protocolModule = {
|
|
531
|
+
manifest: protocolManifest,
|
|
532
|
+
migrations: protocolMigrations,
|
|
533
|
+
operations: {
|
|
534
|
+
'protocol/define-template': defineTemplateOp,
|
|
535
|
+
'protocol/list-templates': listTemplatesOp,
|
|
536
|
+
'protocol/instantiate': instantiateOp,
|
|
537
|
+
'protocol/fill': fillOp,
|
|
538
|
+
'protocol/sign': signOp,
|
|
539
|
+
'protocol/countersign': countersignOp,
|
|
540
|
+
'protocol/void': voidOp,
|
|
541
|
+
'protocol/get': getOp,
|
|
542
|
+
'protocol/list-for-entity': listForEntityOp,
|
|
543
|
+
},
|
|
544
|
+
};
|
|
545
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@substrat-run/engine-protocol",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Substrat engine: protocols/checklists with the sign → immutable invariant — versioned templates, append-only responses, verifiable content hash, counter-signatures on frozen content",
|
|
5
|
+
"license": "AGPL-3.0-only",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/substrat-run/substrat.git",
|
|
9
|
+
"directory": "engines/protocol"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://github.com/substrat-run/substrat",
|
|
12
|
+
"type": "module",
|
|
13
|
+
"main": "./dist/index.js",
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"exports": {
|
|
16
|
+
".": {
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"default": "./dist/index.js"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"dist"
|
|
23
|
+
],
|
|
24
|
+
"publishConfig": {
|
|
25
|
+
"access": "public"
|
|
26
|
+
},
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"zod": "^3.25.0",
|
|
29
|
+
"@substrat-run/contracts": "^0.1.0",
|
|
30
|
+
"@substrat-run/kernel": "^0.1.0"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"typescript": "^5.6.0"
|
|
34
|
+
},
|
|
35
|
+
"scripts": {
|
|
36
|
+
"build": "tsc -p tsconfig.json",
|
|
37
|
+
"typecheck": "tsc -p tsconfig.json --noEmit"
|
|
38
|
+
}
|
|
39
|
+
}
|