@hesohq/sdk 0.1.2-dev.21
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/dist/adapters/ai-sdk.d.ts +43 -0
- package/dist/adapters/ai-sdk.d.ts.map +1 -0
- package/dist/adapters/ai-sdk.js +86 -0
- package/dist/adapters/ai-sdk.js.map +1 -0
- package/dist/adapters/mastra.d.ts +34 -0
- package/dist/adapters/mastra.d.ts.map +1 -0
- package/dist/adapters/mastra.js +84 -0
- package/dist/adapters/mastra.js.map +1 -0
- package/dist/capture.d.ts +230 -0
- package/dist/capture.d.ts.map +1 -0
- package/dist/capture.js +591 -0
- package/dist/capture.js.map +1 -0
- package/dist/cloud.d.ts +188 -0
- package/dist/cloud.d.ts.map +1 -0
- package/dist/cloud.js +196 -0
- package/dist/cloud.js.map +1 -0
- package/dist/config.d.ts +7 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +16 -0
- package/dist/config.js.map +1 -0
- package/dist/delegation.d.ts +68 -0
- package/dist/delegation.d.ts.map +1 -0
- package/dist/delegation.js +139 -0
- package/dist/delegation.js.map +1 -0
- package/dist/gating.d.ts +33 -0
- package/dist/gating.d.ts.map +1 -0
- package/dist/gating.js +96 -0
- package/dist/gating.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +87 -0
- package/dist/index.js.map +1 -0
- package/dist/proxy.d.ts +30 -0
- package/dist/proxy.d.ts.map +1 -0
- package/dist/proxy.js +59 -0
- package/dist/proxy.js.map +1 -0
- package/dist/runtime.d.ts +30 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +70 -0
- package/dist/runtime.js.map +1 -0
- package/dist/types.d.ts +259 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/package.json +38 -0
package/dist/capture.js
ADDED
|
@@ -0,0 +1,591 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// The shared capture core every Node framework adapter is built on — the JS twin
|
|
3
|
+
// of the Python SDK's `heso._capture`. A framework adapter's only job is to find
|
|
4
|
+
// the tool/model/payment call at its native interception point and translate it
|
|
5
|
+
// into a heso action; everything after (classify, policy, redact, SIGN, audit
|
|
6
|
+
// chain) is the Rust engine's, reached through two entry points here:
|
|
7
|
+
//
|
|
8
|
+
// • gate() — capture + drive + ENFORCE. Throws BlockedError / SuspendedError
|
|
9
|
+
// on a refusal (blocking mode), so the wrapped call never fires
|
|
10
|
+
// ungated. Use where the framework treats a thrown tool error as
|
|
11
|
+
// an abort (Vercel AI SDK, Mastra — a throwing `execute`).
|
|
12
|
+
// • evaluate() — capture + drive WITHOUT enforcing; returns { outcome, action }
|
|
13
|
+
// so an adapter can map the decision onto its own verdict shape.
|
|
14
|
+
//
|
|
15
|
+
// recordResult() binds a finished call's result to a follow-up receipt.
|
|
16
|
+
//
|
|
17
|
+
// Zero crypto in TS: minting is delegated to the native @hesohq/node addon
|
|
18
|
+
// (signing, native-only). In this Node SDK, verification likewise binds to the
|
|
19
|
+
// native addon via @hesohq/core (whose main entry re-exports @hesohq/node). The
|
|
20
|
+
// addon is loaded LAZILY here so importing the capture core does not pull in the
|
|
21
|
+
// native binary until a gated action actually mints.
|
|
22
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
+
exports.OperatorKeyMismatchError = exports.ApprovalRejectedError = exports.SuspendedError = exports.BlockedError = exports.BridgeError = void 0;
|
|
24
|
+
exports.normalizeFields = normalizeFields;
|
|
25
|
+
exports.buildAction = buildAction;
|
|
26
|
+
exports.evaluate = evaluate;
|
|
27
|
+
exports.gate = gate;
|
|
28
|
+
exports.recordResult = recordResult;
|
|
29
|
+
exports.isEnforcing = isEnforcing;
|
|
30
|
+
exports.finalizeL1 = finalizeL1;
|
|
31
|
+
exports.finalizeQuorum = finalizeQuorum;
|
|
32
|
+
const runtime_js_1 = require("./runtime.js");
|
|
33
|
+
const cloud_js_1 = require("./cloud.js");
|
|
34
|
+
let _native = null;
|
|
35
|
+
function native() {
|
|
36
|
+
if (_native !== null)
|
|
37
|
+
return _native;
|
|
38
|
+
let mod;
|
|
39
|
+
try {
|
|
40
|
+
// Lazy require defers loading the native, Node-only addon until minting is
|
|
41
|
+
// actually used (it is an optional dependency of this package).
|
|
42
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
43
|
+
mod = require('@hesohq/node');
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
throw new BridgeError('@hesohq/sdk: minting requires the native @hesohq/node addon (a Node-only optional dependency). ' +
|
|
47
|
+
`Install it to use the gating adapters. Underlying error: ${err.message}`);
|
|
48
|
+
}
|
|
49
|
+
if (typeof mod.processAction !== 'function') {
|
|
50
|
+
throw new BridgeError('@hesohq/sdk: @hesohq/node was built without the `process` feature (no processAction export); ' +
|
|
51
|
+
'rebuild it with `napi build --features process`');
|
|
52
|
+
}
|
|
53
|
+
_native = mod;
|
|
54
|
+
return _native;
|
|
55
|
+
}
|
|
56
|
+
// ── errors ──────────────────────────────────────────────────────────────────
|
|
57
|
+
/** The native engine could not run or its output could not be parsed (fail closed). */
|
|
58
|
+
class BridgeError extends Error {
|
|
59
|
+
constructor(message) {
|
|
60
|
+
super(message);
|
|
61
|
+
this.name = 'BridgeError';
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
exports.BridgeError = BridgeError;
|
|
65
|
+
/** A captured action was refused by policy. Thrown so the wrapped call never fires. */
|
|
66
|
+
class BlockedError extends Error {
|
|
67
|
+
constructor(toolName, ruleId, reason) {
|
|
68
|
+
super(`heso blocked \`${toolName}\` (rule ${ruleId ?? '?'}): ${reason ?? 'refused by policy'}`);
|
|
69
|
+
this.toolName = toolName;
|
|
70
|
+
this.ruleId = ruleId;
|
|
71
|
+
this.reason = reason;
|
|
72
|
+
this.name = 'BlockedError';
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
exports.BlockedError = BlockedError;
|
|
76
|
+
/** A captured action was gated to a human and awaits approval. Thrown so it never fires. */
|
|
77
|
+
class SuspendedError extends Error {
|
|
78
|
+
constructor(toolName, actionHash) {
|
|
79
|
+
super(`heso suspended \`${toolName}\` pending approval (action_hash ${actionHash ?? '?'})`);
|
|
80
|
+
this.toolName = toolName;
|
|
81
|
+
this.actionHash = actionHash;
|
|
82
|
+
this.name = 'SuspendedError';
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
exports.SuspendedError = SuspendedError;
|
|
86
|
+
/**
|
|
87
|
+
* A human resolved an approval as anything other than ``approved``
|
|
88
|
+
* (``rejected``/``escalated``). Thrown by {@link finalizeL1} BEFORE any assemble —
|
|
89
|
+
* a non-approval NEVER mints an L1 (M3). Carries the resolved decision so a caller
|
|
90
|
+
* can branch (e.g. surface the rejection reason).
|
|
91
|
+
*/
|
|
92
|
+
class ApprovalRejectedError extends Error {
|
|
93
|
+
constructor(actionHash, decision) {
|
|
94
|
+
super(`heso approval ${actionHash} resolved \`${decision}\` (not approved) — no L1 minted`);
|
|
95
|
+
this.actionHash = actionHash;
|
|
96
|
+
this.decision = decision;
|
|
97
|
+
this.name = 'ApprovalRejectedError';
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
exports.ApprovalRejectedError = ApprovalRejectedError;
|
|
101
|
+
/**
|
|
102
|
+
* Read the ``decision`` field off a relayed approver record WITHOUT mutating it.
|
|
103
|
+
*
|
|
104
|
+
* The cloud relays the record as the EXACT verbatim JSON TEXT the approver signed (M2);
|
|
105
|
+
* the byte-faithfulness moat means that string must reach the native assemble UNTOUCHED.
|
|
106
|
+
* This parses it READ-ONLY for the M3 decision gate (``finalizeL1``/``finalizeQuorum`` throw
|
|
107
|
+
* {@link ApprovalRejectedError} on a non-approval BEFORE any keystore touch); the
|
|
108
|
+
* verbatim string itself — never a reserialize of this parse — is what feeds the
|
|
109
|
+
* assemble. A record that is not parseable JSON / carries no string ``decision`` is a
|
|
110
|
+
* fail-closed {@link BridgeError} (a malformed relay never silently assembles).
|
|
111
|
+
*/
|
|
112
|
+
function decisionFromRecord(record) {
|
|
113
|
+
let parsed;
|
|
114
|
+
try {
|
|
115
|
+
parsed = JSON.parse(record);
|
|
116
|
+
}
|
|
117
|
+
catch (err) {
|
|
118
|
+
throw new BridgeError(`@hesohq/sdk: relayed approver record is not valid JSON: ${err.message}`);
|
|
119
|
+
}
|
|
120
|
+
if (typeof parsed !== 'object' ||
|
|
121
|
+
parsed === null ||
|
|
122
|
+
typeof parsed.decision !== 'string') {
|
|
123
|
+
throw new BridgeError('@hesohq/sdk: relayed approver record has no string `decision` field');
|
|
124
|
+
}
|
|
125
|
+
return parsed.decision;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* The operator key loaded from the project keystore does NOT match the suspended
|
|
129
|
+
* body's ``agent_identity`` (MANDATORY-1). The action was suspended under a now-
|
|
130
|
+
* rotated key, so the in-core assemble fails closed rather than minting a receipt
|
|
131
|
+
* the verifier would reject. A DISTINCT typed signal so {@link finalizeL1} /
|
|
132
|
+
* {@link finalizeQuorum} can drive key-rotation auto-recovery (re-suspend under the new
|
|
133
|
+
* key) instead of surfacing an opaque {@link BridgeError}. Carries the
|
|
134
|
+
* ``agent_identity`` the suspended content expects so the caller can branch.
|
|
135
|
+
*/
|
|
136
|
+
class OperatorKeyMismatchError extends Error {
|
|
137
|
+
constructor(actionHash, expectedAgentIdentity,
|
|
138
|
+
/** The loaded operator pubkey when known (proactive path); ``null`` when the
|
|
139
|
+
* mismatch was only discovered reactively inside the native assemble. */
|
|
140
|
+
loadedPublicKey = null) {
|
|
141
|
+
super(`heso operator key mismatch finalizing ${actionHash}: the suspended content was ` +
|
|
142
|
+
`minted under agent_identity ${expectedAgentIdentity}` +
|
|
143
|
+
(loadedPublicKey !== null ? `, but the loaded operator key is ${loadedPublicKey}` : '') +
|
|
144
|
+
' — the key rotated; re-suspend under the new key (no receipt minted)');
|
|
145
|
+
this.actionHash = actionHash;
|
|
146
|
+
this.expectedAgentIdentity = expectedAgentIdentity;
|
|
147
|
+
this.loadedPublicKey = loadedPublicKey;
|
|
148
|
+
this.name = 'OperatorKeyMismatchError';
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
exports.OperatorKeyMismatchError = OperatorKeyMismatchError;
|
|
152
|
+
/** The napi/wheel surfaces an operator-key mismatch as a ``[OperatorKeyMismatch]``-
|
|
153
|
+
* prefixed error (the discriminable boundary signal). Detect it so the REACTIVE
|
|
154
|
+
* key-rotation catch can promote it to {@link OperatorKeyMismatchError}. */
|
|
155
|
+
function isOperatorKeyMismatch(err) {
|
|
156
|
+
return err instanceof Error && err.message.includes('[OperatorKeyMismatch]');
|
|
157
|
+
}
|
|
158
|
+
// ── core ──────────────────────────────────────────────────────────────────────
|
|
159
|
+
/**
|
|
160
|
+
* Build the action's `fields` from a framework's tool input: an object is used as
|
|
161
|
+
* the structured fields; a JSON-object string is parsed; anything else is recorded
|
|
162
|
+
* verbatim under `input`. Never throws — capture must not crash the agent.
|
|
163
|
+
*/
|
|
164
|
+
function normalizeFields(input) {
|
|
165
|
+
if (input === null || input === undefined)
|
|
166
|
+
return {};
|
|
167
|
+
if (typeof input === 'object' && !Array.isArray(input)) {
|
|
168
|
+
return coerceFields(input);
|
|
169
|
+
}
|
|
170
|
+
if (typeof input === 'string') {
|
|
171
|
+
let parsed;
|
|
172
|
+
try {
|
|
173
|
+
parsed = JSON.parse(input);
|
|
174
|
+
}
|
|
175
|
+
catch {
|
|
176
|
+
return { input };
|
|
177
|
+
}
|
|
178
|
+
if (parsed !== null && typeof parsed === 'object' && !Array.isArray(parsed)) {
|
|
179
|
+
return coerceFields(parsed);
|
|
180
|
+
}
|
|
181
|
+
return { input: jsonable(parsed) };
|
|
182
|
+
}
|
|
183
|
+
return { input: jsonable(input) };
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Coerce a value to a JSON-serializable form, falling back to its string form when
|
|
187
|
+
* it is not (capture must never throw, and a non-serializable arg — a BigInt, a
|
|
188
|
+
* function, a circular object — must not later make `JSON.stringify(fields)` fail
|
|
189
|
+
* closed and abort the call). The JS twin of `_bridge.jsonable` (which `repr`s the
|
|
190
|
+
* value); here `String(v)` plays repr's role (e.g. `5n` -> `"5"`).
|
|
191
|
+
*/
|
|
192
|
+
function jsonable(value) {
|
|
193
|
+
try {
|
|
194
|
+
// JSON.stringify THROWS for BigInt / circular, but returns `undefined` (no throw)
|
|
195
|
+
// for a function / symbol / undefined value — those would be silently dropped from
|
|
196
|
+
// the wire, so the gate never sees the field. Treat both as non-serializable and
|
|
197
|
+
// fall back to the string form (String() handles symbols, where templating throws).
|
|
198
|
+
return JSON.stringify(value) === undefined ? String(value) : value;
|
|
199
|
+
}
|
|
200
|
+
catch {
|
|
201
|
+
return String(value);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
/** Apply {@link jsonable} to every value of a fields map. */
|
|
205
|
+
function coerceFields(obj) {
|
|
206
|
+
const out = {};
|
|
207
|
+
for (const [k, v] of Object.entries(obj))
|
|
208
|
+
out[k] = jsonable(v);
|
|
209
|
+
return out;
|
|
210
|
+
}
|
|
211
|
+
function buildProcessInput(toolName, fields, verb, surface, targetHost, extraSignal, redactFields, redactStrategy, config) {
|
|
212
|
+
const signal = { surface };
|
|
213
|
+
if (extraSignal) {
|
|
214
|
+
for (const [k, v] of Object.entries(extraSignal)) {
|
|
215
|
+
if (v !== undefined && v !== null)
|
|
216
|
+
signal[k] = v;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
const input = {
|
|
220
|
+
verb,
|
|
221
|
+
tool_name: toolName,
|
|
222
|
+
workflow: config.workflow,
|
|
223
|
+
account: config.account,
|
|
224
|
+
fields,
|
|
225
|
+
redact_fields: redactFields,
|
|
226
|
+
redact_strategy: redactStrategy,
|
|
227
|
+
signal,
|
|
228
|
+
};
|
|
229
|
+
if (targetHost !== undefined)
|
|
230
|
+
input.target_host = targetHost;
|
|
231
|
+
if (config.clockOverride !== null)
|
|
232
|
+
input.clock_override = config.clockOverride;
|
|
233
|
+
return input;
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Translate a captured call into an {@link Action}, stamping the active config's
|
|
237
|
+
* workflow/account/clock. The `verb` is an escalate-only hint — the engine
|
|
238
|
+
* classifies the `surface`/`signal` structurally and takes the stricter lane.
|
|
239
|
+
*/
|
|
240
|
+
function buildAction(toolName, fields, opts = {}) {
|
|
241
|
+
const config = (0, runtime_js_1.requireConfig)();
|
|
242
|
+
// Coerce values to JSON-safe forms (mirrors Python build_action) so a direct
|
|
243
|
+
// caller passing raw fields gets the same fail-safe capture as the gate path.
|
|
244
|
+
const coerced = coerceFields(fields);
|
|
245
|
+
const input = buildProcessInput(toolName, coerced, opts.verb ?? 'tool_call', opts.surface ?? 'decorator', opts.targetHost, opts.signal, opts.redact ?? [], opts.redactStrategy ?? 'destructive', config);
|
|
246
|
+
return { verb: input.verb, toolName, fields: coerced, input };
|
|
247
|
+
}
|
|
248
|
+
function drive(input, config) {
|
|
249
|
+
let raw;
|
|
250
|
+
try {
|
|
251
|
+
raw = native().processAction(JSON.stringify(input), config.projectRoot);
|
|
252
|
+
}
|
|
253
|
+
catch (err) {
|
|
254
|
+
throw new BridgeError(`@hesohq/sdk: native processAction failed: ${err.message}`);
|
|
255
|
+
}
|
|
256
|
+
let data;
|
|
257
|
+
try {
|
|
258
|
+
data = JSON.parse(raw.toString('utf-8'));
|
|
259
|
+
}
|
|
260
|
+
catch (err) {
|
|
261
|
+
throw new BridgeError(`@hesohq/sdk: could not parse engine output: ${err.message}`);
|
|
262
|
+
}
|
|
263
|
+
return parseOutcome(data);
|
|
264
|
+
}
|
|
265
|
+
function parseOutcome(data) {
|
|
266
|
+
if (data.status === 'allowed') {
|
|
267
|
+
return {
|
|
268
|
+
kind: 'allowed',
|
|
269
|
+
allowed: true,
|
|
270
|
+
receipt: data.receipt,
|
|
271
|
+
ruleId: null,
|
|
272
|
+
reason: null,
|
|
273
|
+
actionHash: data.receipt.content?.action_hash ?? null,
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
if (data.status === 'blocked') {
|
|
277
|
+
return {
|
|
278
|
+
kind: 'blocked',
|
|
279
|
+
allowed: false,
|
|
280
|
+
receipt: null,
|
|
281
|
+
ruleId: data.rule_id ?? null,
|
|
282
|
+
reason: data.reason ?? null,
|
|
283
|
+
actionHash: null,
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
return {
|
|
287
|
+
kind: 'suspended',
|
|
288
|
+
allowed: false,
|
|
289
|
+
receipt: data.receipt ?? null,
|
|
290
|
+
ruleId: null,
|
|
291
|
+
reason: null,
|
|
292
|
+
actionHash: data.ticket?.action_hash ?? null,
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
function enforce(toolName, outcome, config) {
|
|
296
|
+
if (outcome.allowed)
|
|
297
|
+
return;
|
|
298
|
+
if (!config.blocking)
|
|
299
|
+
return; // observe-only: recorded, not enforced
|
|
300
|
+
if (outcome.kind === 'blocked')
|
|
301
|
+
throw new BlockedError(toolName, outcome.ruleId, outcome.reason);
|
|
302
|
+
throw new SuspendedError(toolName, outcome.actionHash);
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Capture + drive an action WITHOUT enforcing. Returns `{ outcome, action }` so an
|
|
306
|
+
* adapter can map the decision onto a framework verdict (allow/deny) instead of
|
|
307
|
+
* throwing. The returned `action` is what {@link recordResult} binds the result to.
|
|
308
|
+
*/
|
|
309
|
+
function evaluate(toolName, input, opts = {}) {
|
|
310
|
+
const config = (0, runtime_js_1.requireConfig)();
|
|
311
|
+
const action = buildAction(toolName, normalizeFields(input), opts);
|
|
312
|
+
return { outcome: drive(action.input, config), action };
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Capture + drive + ENFORCE an action before its side effect runs. Throws
|
|
316
|
+
* {@link BlockedError} / {@link SuspendedError} on a refusal in blocking mode (so
|
|
317
|
+
* the wrapped call never fires ungated); returns the gated {@link Action} on allow
|
|
318
|
+
* (or in observe-only mode), which {@link recordResult} later binds the result to.
|
|
319
|
+
*/
|
|
320
|
+
function gate(toolName, input, opts = {}) {
|
|
321
|
+
const config = (0, runtime_js_1.requireConfig)();
|
|
322
|
+
const action = buildAction(toolName, normalizeFields(input), opts);
|
|
323
|
+
const outcome = drive(action.input, config);
|
|
324
|
+
mirrorSuspended(outcome);
|
|
325
|
+
enforce(toolName, outcome, config);
|
|
326
|
+
return action;
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* On a suspend, mirror-push the signed suspended L0 receipt the engine now returns
|
|
330
|
+
* so the byte-exact operator-stamped suspended content exists server-side for the
|
|
331
|
+
* later L1 relay (the browser co-signs THAT content; the SDK reassembles the L1 off
|
|
332
|
+
* the identical body). Fire-and-forget + best-effort: a mirror failure must not stop
|
|
333
|
+
* ``gate`` from throwing {@link SuspendedError} and aborting the call. The push is
|
|
334
|
+
* not load-bearing for the refusal — only for the relay that follows.
|
|
335
|
+
*/
|
|
336
|
+
function mirrorSuspended(outcome) {
|
|
337
|
+
if (outcome.kind !== 'suspended' || outcome.receipt === null)
|
|
338
|
+
return;
|
|
339
|
+
void (0, cloud_js_1.pushReceipt)(outcome.receipt).catch(() => {
|
|
340
|
+
// best-effort — the suspended receipt is relay evidence, not the refusal itself
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Bind a finished call's result to a follow-up receipt (evidence of WHAT happened,
|
|
345
|
+
* not only what was allowed). Best-effort: a recording failure is swallowed — the
|
|
346
|
+
* load-bearing decision was the gate on the way in, and recording must never crash
|
|
347
|
+
* the agent.
|
|
348
|
+
*/
|
|
349
|
+
function recordResult(action, output) {
|
|
350
|
+
try {
|
|
351
|
+
const config = (0, runtime_js_1.requireConfig)();
|
|
352
|
+
const repr = typeof output === 'string' ? output : JSON.stringify(output ?? null);
|
|
353
|
+
const input = { ...action.input, result_hash: native().blake3Hex(repr) };
|
|
354
|
+
drive(input, config);
|
|
355
|
+
}
|
|
356
|
+
catch {
|
|
357
|
+
// best-effort — recording is evidence, not enforcement
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* True when the active config enforces refusals (blocking mode), false in
|
|
362
|
+
* observe-only mode. Decision-returning adapters consult this to mirror
|
|
363
|
+
* {@link gate}'s observe-only behavior: in observe-only the verdict is "allow".
|
|
364
|
+
*/
|
|
365
|
+
function isEnforcing() {
|
|
366
|
+
return (0, runtime_js_1.requireConfig)().blocking;
|
|
367
|
+
}
|
|
368
|
+
// ── L1 finalization (phase two of the gate) ─────────────────────────────────
|
|
369
|
+
/**
|
|
370
|
+
* Finalize an approved gate into a signed L1 receipt — the out-of-band SECOND call
|
|
371
|
+
* of the two-phase pattern. Phase one is {@link gate}, which throws
|
|
372
|
+
* {@link SuspendedError} (carrying the ``action_hash``) and cannot block ``execute``
|
|
373
|
+
* waiting for a human. Once the cloud relays the approver parts (poll keyed on that
|
|
374
|
+
* ``action_hash``), this assembles and mirrors the L1.
|
|
375
|
+
*
|
|
376
|
+
* Order is load-bearing:
|
|
377
|
+
* 1. Assert the relayed record is ``approved`` BEFORE touching the keystore (M3) —
|
|
378
|
+
* a ``rejected``/``escalated`` decision throws {@link ApprovalRejectedError} and
|
|
379
|
+
* NEVER assembles an L1.
|
|
380
|
+
* 2. Assemble in-core: the native addon loads the OPERATOR key from the project
|
|
381
|
+
* keystore, runs the MANDATORY-1 operator-key identity check against the
|
|
382
|
+
* suspended content's ``agent_identity``, and verifies Valid(L1) internally —
|
|
383
|
+
* throwing on any bad part. The record is passed as the SAME bytes the cloud
|
|
384
|
+
* stored verbatim (M2): build the L1 over the operator-stamped ``suspendedContent``.
|
|
385
|
+
* 3. Re-verify the assembled receipt locally and REFUSE to push unless it is
|
|
386
|
+
* Valid(L1) — a defense-in-depth gate independent of the addon's internal check.
|
|
387
|
+
* 4. Mirror-push, superseding the suspended L0 entry the L1 was built from (M5).
|
|
388
|
+
*
|
|
389
|
+
* @returns the signed L1 {@link ActionReceipt} that was pushed.
|
|
390
|
+
*/
|
|
391
|
+
async function finalizeL1(suspendedContent, relayedParts, keyPassphrase) {
|
|
392
|
+
const config = (0, runtime_js_1.requireConfig)();
|
|
393
|
+
const actionHash = suspendedContent.action_hash;
|
|
394
|
+
// M3 / REJECT-MINTS-NO-L1: a non-approval never reaches the keystore. The record is
|
|
395
|
+
// the cloud's VERBATIM JSON TEXT — parse it READ-ONLY for the decision gate only
|
|
396
|
+
// (the verbatim string itself is what feeds the native assemble, never a reserialize).
|
|
397
|
+
const decision = decisionFromRecord(relayedParts.record);
|
|
398
|
+
if (decision !== 'approved') {
|
|
399
|
+
throw new ApprovalRejectedError(actionHash, decision);
|
|
400
|
+
}
|
|
401
|
+
// The native addon assembles the L1 in-core off the operator-stamped suspended
|
|
402
|
+
// content and the verbatim approver record (M2 — the cloud's EXACT TEXT is passed
|
|
403
|
+
// straight through, never parse/reserialized here), running MANDATORY-1 and verifying
|
|
404
|
+
// Valid(L1) before it returns. A relayed anchor (opaque, never parsed here) is threaded
|
|
405
|
+
// straight in so the operator signature covers it; absent ⇒ the unchanged anchorless
|
|
406
|
+
// path (the L1 golden never moves).
|
|
407
|
+
let receiptBytes;
|
|
408
|
+
try {
|
|
409
|
+
receiptBytes = native().assembleL1FromParts(JSON.stringify(suspendedContent), relayedParts.record, relayedParts.approverPubkeyB64, relayedParts.coSigB64, config.projectRoot, keyPassphrase, relayedParts.timeAnchor !== undefined ? JSON.stringify(relayedParts.timeAnchor) : undefined);
|
|
410
|
+
}
|
|
411
|
+
catch (err) {
|
|
412
|
+
// MANDATORY-1: a rotated operator key fails closed in-core. Promote the typed
|
|
413
|
+
// boundary signal so a caller can drive key-rotation recovery (re-suspend).
|
|
414
|
+
if (isOperatorKeyMismatch(err)) {
|
|
415
|
+
throw new OperatorKeyMismatchError(actionHash, suspendedContent.agent_identity);
|
|
416
|
+
}
|
|
417
|
+
throw new BridgeError(`@hesohq/sdk: assembleL1FromParts failed: ${err.message}`);
|
|
418
|
+
}
|
|
419
|
+
// Defense in depth: refuse to push anything that is not locally Valid(L1).
|
|
420
|
+
const verdict = native().verify(receiptBytes);
|
|
421
|
+
if (verdict.verdict !== 'Valid' || verdict.trustLevel !== 'L1') {
|
|
422
|
+
throw new BridgeError(`@hesohq/sdk: assembled receipt is not Valid(L1) — verdict=${verdict.verdict} trustLevel=${verdict.trustLevel}; refusing to push`);
|
|
423
|
+
}
|
|
424
|
+
let receipt;
|
|
425
|
+
try {
|
|
426
|
+
receipt = JSON.parse(receiptBytes.toString('utf-8'));
|
|
427
|
+
}
|
|
428
|
+
catch (err) {
|
|
429
|
+
throw new BridgeError(`@hesohq/sdk: could not parse assembled L1 receipt: ${err.message}`);
|
|
430
|
+
}
|
|
431
|
+
// The L1 supersedes the suspended L0 entry it was built from (M5: suspended -> L1).
|
|
432
|
+
await (0, cloud_js_1.pushReceipt)(receipt, actionHash);
|
|
433
|
+
return receipt;
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* Re-drive a suspended action through the engine gate under the CURRENT operator
|
|
437
|
+
* key — the key-rotation auto-recovery path. The original suspended content was
|
|
438
|
+
* minted under a now-rotated key, so its co-signed base is dead; the only safe move
|
|
439
|
+
* is to re-suspend: rebuild the action verbatim from ``suspendedContent.action`` and
|
|
440
|
+
* run it through ``processAction`` again, yielding a FRESH Suspended L0 with a new
|
|
441
|
+
* ``agent_identity`` + ``action_hash``. We mirror-push it so the byte-exact new base
|
|
442
|
+
* exists server-side for the next relay, and hand the new hash back so the caller
|
|
443
|
+
* re-opens the approval against it (the cloud's S11 lifecycle invalidates the stale
|
|
444
|
+
* one). The old human co-sign cannot be replayed against the new base.
|
|
445
|
+
*/
|
|
446
|
+
function reSuspendUnderNewKey(suspendedContent, config) {
|
|
447
|
+
const detail = suspendedContent.action;
|
|
448
|
+
// Rebuild the wire input VERBATIM from the suspended action (the engine re-stamps
|
|
449
|
+
// the current operator identity + a fresh action_hash; the action itself is the
|
|
450
|
+
// same one the human reviewed).
|
|
451
|
+
const input = {
|
|
452
|
+
verb: detail.verb,
|
|
453
|
+
tool_name: detail.tool_name,
|
|
454
|
+
workflow: detail.workflow,
|
|
455
|
+
account: detail.account,
|
|
456
|
+
fields: detail.fields,
|
|
457
|
+
redact_fields: [],
|
|
458
|
+
redact_strategy: 'destructive',
|
|
459
|
+
signal: { surface: 'sdk_wrap' },
|
|
460
|
+
};
|
|
461
|
+
if (detail.target_host !== undefined)
|
|
462
|
+
input.target_host = detail.target_host;
|
|
463
|
+
if (config.clockOverride !== null)
|
|
464
|
+
input.clock_override = config.clockOverride;
|
|
465
|
+
const outcome = drive(input, config);
|
|
466
|
+
if (outcome.kind !== 'suspended' || outcome.receipt === null) {
|
|
467
|
+
throw new BridgeError(`@hesohq/sdk: key-rotation re-suspend expected a fresh Suspended L0 but the engine ` +
|
|
468
|
+
`returned \`${outcome.kind}\` — cannot recover this approval automatically`);
|
|
469
|
+
}
|
|
470
|
+
const freshHash = outcome.receipt.content.action_hash;
|
|
471
|
+
// Mirror the fresh suspended base so the relay that follows has the exact bytes.
|
|
472
|
+
void (0, cloud_js_1.pushReceipt)(outcome.receipt).catch(() => {
|
|
473
|
+
// best-effort — same contract as the gate-path mirror
|
|
474
|
+
});
|
|
475
|
+
return {
|
|
476
|
+
receipt: outcome.receipt,
|
|
477
|
+
actionHash: freshHash,
|
|
478
|
+
agentIdentity: outcome.receipt.content.agent_identity,
|
|
479
|
+
};
|
|
480
|
+
}
|
|
481
|
+
/**
|
|
482
|
+
* Finalize an approved k-of-n gate into a signed QUORUM receipt — the multi-approver
|
|
483
|
+
* sibling of {@link finalizeL1}. Every relayed leg must be ``approved``; the native
|
|
484
|
+
* addon assembles the quorum in-core off the operator-stamped suspended content and the
|
|
485
|
+
* verbatim per-approver records + co-signatures (canonicalization stays the Rust
|
|
486
|
+
* moat), verifying Valid(L1) WITH a ``multi_approval`` block before it returns. A
|
|
487
|
+
* quorum embeds ``trust_level: 'L1'`` WITH that block — it is NOT a higher level than
|
|
488
|
+
* single-approver L1.
|
|
489
|
+
*
|
|
490
|
+
* Order is load-bearing:
|
|
491
|
+
* 1. Assert EVERY leg's ``record.decision`` is ``approved`` BEFORE touching the
|
|
492
|
+
* keystore (M3) — any non-approval throws {@link ApprovalRejectedError} and NEVER
|
|
493
|
+
* assembles a quorum.
|
|
494
|
+
* 2. KEY-ROTATION (proactive): if ``loadedOperatorPubkeyB64`` is supplied and does
|
|
495
|
+
* NOT equal the suspended content's ``agent_identity``, skip the wasted assemble
|
|
496
|
+
* and drive recovery straight away.
|
|
497
|
+
* 3. Assemble in-core (the addon runs MANDATORY-1 + verifies Valid(L1) with a
|
|
498
|
+
* ``multi_approval`` block); a reactive ``[OperatorKeyMismatch]`` is caught and
|
|
499
|
+
* drives the SAME recovery.
|
|
500
|
+
* 4. Re-verify locally and REFUSE to push unless Valid(L1) WITH a ``multi_approval``
|
|
501
|
+
* block (defense in depth).
|
|
502
|
+
* 5. Mirror-push, superseding the suspended L0 entry the quorum was built from (M5:
|
|
503
|
+
* suspended/L0 -> L1; the server rejects an already-decided L1 target).
|
|
504
|
+
*
|
|
505
|
+
* On a key mismatch (proactive or reactive) and a supplied ``onKeyRotation``
|
|
506
|
+
* recovery, this re-suspends under the new key and throws an
|
|
507
|
+
* {@link OperatorKeyMismatchError} carrying the fresh hash via ``cause`` so the
|
|
508
|
+
* caller never mistakes recovery for a successful mint. With no recovery requested
|
|
509
|
+
* it throws the typed mismatch unhandled.
|
|
510
|
+
*
|
|
511
|
+
* @returns the signed QUORUM {@link ActionReceipt} that was pushed (L1 with a
|
|
512
|
+
* ``multi_approval`` block).
|
|
513
|
+
*/
|
|
514
|
+
async function finalizeQuorum(suspendedContent, relayedParts, options = {}) {
|
|
515
|
+
const config = (0, runtime_js_1.requireConfig)();
|
|
516
|
+
const actionHash = suspendedContent.action_hash;
|
|
517
|
+
const { keyPassphrase, loadedOperatorPubkeyB64, onKeyRotation } = options;
|
|
518
|
+
// M3 / REJECT-MINTS-NO-QUORUM: a single non-approval anywhere never reaches the keystore.
|
|
519
|
+
// Each leg's record is the cloud's VERBATIM JSON TEXT — parse READ-ONLY for the
|
|
520
|
+
// decision gate (the verbatim string itself feeds the native assemble below).
|
|
521
|
+
for (const leg of relayedParts.legs) {
|
|
522
|
+
const decision = decisionFromRecord(leg.record);
|
|
523
|
+
if (decision !== 'approved') {
|
|
524
|
+
throw new ApprovalRejectedError(actionHash, decision);
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
// PROACTIVE key-rotation: a known-disagreeing operator pubkey skips the assemble.
|
|
528
|
+
if (loadedOperatorPubkeyB64 !== undefined &&
|
|
529
|
+
loadedOperatorPubkeyB64 !== suspendedContent.agent_identity) {
|
|
530
|
+
return recoverFromKeyRotation(suspendedContent, config, onKeyRotation, loadedOperatorPubkeyB64);
|
|
531
|
+
}
|
|
532
|
+
// The native addon assembles the quorum in-core. parts_json carries each leg as
|
|
533
|
+
// `{ record: <JSON STRING>, approverPubkeyB64, coSigB64 }` (the napi WireQuorumPart is
|
|
534
|
+
// camelCase; `record` stays a JSON STRING on every plane, matching the golden). The
|
|
535
|
+
// cloud already relayed `record` as the EXACT verbatim JSON TEXT, so it is passed
|
|
536
|
+
// STRAIGHT through here (never re-stringified — that would diverge the canonical bytes
|
|
537
|
+
// and fail the in-core per-leg co-sign verify closed).
|
|
538
|
+
const partsJson = JSON.stringify(relayedParts.legs.map((leg) => ({
|
|
539
|
+
record: leg.record,
|
|
540
|
+
approverPubkeyB64: leg.approverPubkeyB64,
|
|
541
|
+
coSigB64: leg.coSigB64,
|
|
542
|
+
})));
|
|
543
|
+
let receiptBytes;
|
|
544
|
+
try {
|
|
545
|
+
receiptBytes = native().assembleQuorumFromParts(JSON.stringify(suspendedContent), relayedParts.threshold, JSON.stringify(relayedParts.roster), partsJson, config.projectRoot, keyPassphrase);
|
|
546
|
+
}
|
|
547
|
+
catch (err) {
|
|
548
|
+
// REACTIVE key-rotation: the in-core MANDATORY-1 check fired.
|
|
549
|
+
if (isOperatorKeyMismatch(err)) {
|
|
550
|
+
return recoverFromKeyRotation(suspendedContent, config, onKeyRotation, null);
|
|
551
|
+
}
|
|
552
|
+
throw new BridgeError(`@hesohq/sdk: assembleQuorumFromParts failed: ${err.message}`);
|
|
553
|
+
}
|
|
554
|
+
let receipt;
|
|
555
|
+
try {
|
|
556
|
+
receipt = JSON.parse(receiptBytes.toString('utf-8'));
|
|
557
|
+
}
|
|
558
|
+
catch (err) {
|
|
559
|
+
throw new BridgeError(`@hesohq/sdk: could not parse assembled quorum receipt: ${err.message}`);
|
|
560
|
+
}
|
|
561
|
+
// Defense in depth: a quorum is L1 WITH a multi_approval block. Refuse to push
|
|
562
|
+
// anything that is not locally Valid(L1) carrying that block (distinguished by the
|
|
563
|
+
// block, never by the level — a plain single-approver L1 has no multi_approval).
|
|
564
|
+
const verdict = native().verify(receiptBytes);
|
|
565
|
+
if (verdict.verdict !== 'Valid' ||
|
|
566
|
+
verdict.trustLevel !== 'L1' ||
|
|
567
|
+
receipt.content.multi_approval === undefined) {
|
|
568
|
+
throw new BridgeError(`@hesohq/sdk: assembled receipt is not a Valid(L1) quorum — verdict=${verdict.verdict} ` +
|
|
569
|
+
`trustLevel=${verdict.trustLevel} multi_approval=${receipt.content.multi_approval !== undefined}; ` +
|
|
570
|
+
`refusing to push`);
|
|
571
|
+
}
|
|
572
|
+
// The quorum supersedes the suspended L0 entry it was built from (M5: suspended -> L1).
|
|
573
|
+
await (0, cloud_js_1.pushReceipt)(receipt, actionHash);
|
|
574
|
+
return receipt;
|
|
575
|
+
}
|
|
576
|
+
/**
|
|
577
|
+
* Drive the key-rotation recovery: re-suspend under the current key, hand the fresh
|
|
578
|
+
* result to ``onKeyRotation`` if supplied, then ALWAYS throw the typed
|
|
579
|
+
* {@link OperatorKeyMismatchError} (never return a receipt) so a key mismatch can
|
|
580
|
+
* never be mistaken for a successful mint. ``cause`` carries the fresh re-suspend
|
|
581
|
+
* result for callers that inspect it.
|
|
582
|
+
*/
|
|
583
|
+
function recoverFromKeyRotation(suspendedContent, config, onKeyRotation, loadedPublicKey) {
|
|
584
|
+
const fresh = reSuspendUnderNewKey(suspendedContent, config);
|
|
585
|
+
if (onKeyRotation !== undefined)
|
|
586
|
+
onKeyRotation(fresh);
|
|
587
|
+
const err = new OperatorKeyMismatchError(suspendedContent.action_hash, suspendedContent.agent_identity, loadedPublicKey);
|
|
588
|
+
err.cause = fresh;
|
|
589
|
+
throw err;
|
|
590
|
+
}
|
|
591
|
+
//# sourceMappingURL=capture.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capture.js","sourceRoot":"","sources":["../src/capture.ts"],"names":[],"mappings":"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"}
|