@helmetfire-labs/cartridge-common 0.2.0 → 0.3.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 +1 -0
- package/dist/agent-reducer.d.ts +51 -0
- package/dist/agent-reducer.js +98 -0
- package/dist/agent-reducer.js.map +1 -0
- package/dist/anchor.d.ts +30 -0
- package/dist/anchor.js +70 -0
- package/dist/anchor.js.map +1 -0
- package/dist/disclosure.d.ts +50 -0
- package/dist/disclosure.js +81 -0
- package/dist/disclosure.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/merkle.d.ts +50 -0
- package/dist/merkle.js +99 -0
- package/dist/merkle.js.map +1 -0
- package/dist/operator-reducer.d.ts +50 -0
- package/dist/operator-reducer.js +104 -0
- package/dist/operator-reducer.js.map +1 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent conversation reducer — the behavioral contract for AI agent cartridges.
|
|
3
|
+
*
|
|
4
|
+
* Tracks conversation-level state transitions: messages received, responses
|
|
5
|
+
* sent, sessions reset, errors. This is separate from the container lifecycle
|
|
6
|
+
* reducer (start/stop/crash) — the lifecycle reducer is managed by the
|
|
7
|
+
* supervisor, while the agent reducer is managed by the container itself.
|
|
8
|
+
*
|
|
9
|
+
* State tracks aggregates (turn counts, token totals, cost) rather than
|
|
10
|
+
* message content. Content capture is handled by traffic-mirror; the agent
|
|
11
|
+
* reducer provides the auditable state machine for conversation flow.
|
|
12
|
+
*
|
|
13
|
+
* Patent M: Reducer-Based Auditable Cartridge Runtime
|
|
14
|
+
*/
|
|
15
|
+
import type { DurableReducer } from "./durable-reducer.js";
|
|
16
|
+
import { type ActionSchema } from "./action-schema.js";
|
|
17
|
+
export type AgentStatus = "idle" | "processing" | "error";
|
|
18
|
+
export interface AgentState {
|
|
19
|
+
status: AgentStatus;
|
|
20
|
+
turnCount: number;
|
|
21
|
+
totalInputTokens: number;
|
|
22
|
+
totalOutputTokens: number;
|
|
23
|
+
totalCost: number;
|
|
24
|
+
sessionId: string | null;
|
|
25
|
+
lastMessageAt: number;
|
|
26
|
+
updatedAt: number;
|
|
27
|
+
}
|
|
28
|
+
export type AgentAction = {
|
|
29
|
+
type: "message_received";
|
|
30
|
+
ts: number;
|
|
31
|
+
} | {
|
|
32
|
+
type: "response_sent";
|
|
33
|
+
inputTokens: number;
|
|
34
|
+
outputTokens: number;
|
|
35
|
+
cost: number;
|
|
36
|
+
ts: number;
|
|
37
|
+
} | {
|
|
38
|
+
type: "session_reset";
|
|
39
|
+
reason: string;
|
|
40
|
+
ts: number;
|
|
41
|
+
} | {
|
|
42
|
+
type: "session_updated";
|
|
43
|
+
sessionId: string;
|
|
44
|
+
ts: number;
|
|
45
|
+
} | {
|
|
46
|
+
type: "error";
|
|
47
|
+
code: string;
|
|
48
|
+
ts: number;
|
|
49
|
+
};
|
|
50
|
+
export declare const agentReducer: DurableReducer<AgentState, AgentAction>;
|
|
51
|
+
export declare const agentActionSchema: ActionSchema;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent conversation reducer — the behavioral contract for AI agent cartridges.
|
|
3
|
+
*
|
|
4
|
+
* Tracks conversation-level state transitions: messages received, responses
|
|
5
|
+
* sent, sessions reset, errors. This is separate from the container lifecycle
|
|
6
|
+
* reducer (start/stop/crash) — the lifecycle reducer is managed by the
|
|
7
|
+
* supervisor, while the agent reducer is managed by the container itself.
|
|
8
|
+
*
|
|
9
|
+
* State tracks aggregates (turn counts, token totals, cost) rather than
|
|
10
|
+
* message content. Content capture is handled by traffic-mirror; the agent
|
|
11
|
+
* reducer provides the auditable state machine for conversation flow.
|
|
12
|
+
*
|
|
13
|
+
* Patent M: Reducer-Based Auditable Cartridge Runtime
|
|
14
|
+
*/
|
|
15
|
+
import { defineActionSchema, action } from "./action-schema.js";
|
|
16
|
+
// ── Reducer ─────────────────────────────────────────────────────────────────
|
|
17
|
+
function reduce(state, action) {
|
|
18
|
+
switch (action.type) {
|
|
19
|
+
case "message_received":
|
|
20
|
+
if (state.status === "processing")
|
|
21
|
+
return state; // already processing
|
|
22
|
+
return {
|
|
23
|
+
...state,
|
|
24
|
+
status: "processing",
|
|
25
|
+
turnCount: state.turnCount + 1,
|
|
26
|
+
lastMessageAt: action.ts,
|
|
27
|
+
updatedAt: action.ts,
|
|
28
|
+
};
|
|
29
|
+
case "response_sent":
|
|
30
|
+
if (state.status !== "processing")
|
|
31
|
+
return state;
|
|
32
|
+
return {
|
|
33
|
+
...state,
|
|
34
|
+
status: "idle",
|
|
35
|
+
totalInputTokens: state.totalInputTokens + action.inputTokens,
|
|
36
|
+
totalOutputTokens: state.totalOutputTokens + action.outputTokens,
|
|
37
|
+
totalCost: state.totalCost + action.cost,
|
|
38
|
+
updatedAt: action.ts,
|
|
39
|
+
};
|
|
40
|
+
case "session_reset":
|
|
41
|
+
return {
|
|
42
|
+
...state,
|
|
43
|
+
status: "idle",
|
|
44
|
+
sessionId: null,
|
|
45
|
+
updatedAt: action.ts,
|
|
46
|
+
};
|
|
47
|
+
case "session_updated":
|
|
48
|
+
return {
|
|
49
|
+
...state,
|
|
50
|
+
sessionId: action.sessionId,
|
|
51
|
+
updatedAt: action.ts,
|
|
52
|
+
};
|
|
53
|
+
case "error":
|
|
54
|
+
if (state.status !== "processing")
|
|
55
|
+
return state;
|
|
56
|
+
return {
|
|
57
|
+
...state,
|
|
58
|
+
status: "error",
|
|
59
|
+
updatedAt: action.ts,
|
|
60
|
+
};
|
|
61
|
+
default:
|
|
62
|
+
return state;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// ── DurableReducer implementation ───────────────────────────────────────────
|
|
66
|
+
export const agentReducer = {
|
|
67
|
+
reduce,
|
|
68
|
+
init: () => ({
|
|
69
|
+
status: "idle",
|
|
70
|
+
turnCount: 0,
|
|
71
|
+
totalInputTokens: 0,
|
|
72
|
+
totalOutputTokens: 0,
|
|
73
|
+
totalCost: 0,
|
|
74
|
+
sessionId: null,
|
|
75
|
+
lastMessageAt: 0,
|
|
76
|
+
updatedAt: 0,
|
|
77
|
+
}),
|
|
78
|
+
serialize: (state) => ({ ...state }),
|
|
79
|
+
deserialize: (raw) => ({
|
|
80
|
+
status: raw.status ?? "idle",
|
|
81
|
+
turnCount: raw.turnCount ?? 0,
|
|
82
|
+
totalInputTokens: raw.totalInputTokens ?? 0,
|
|
83
|
+
totalOutputTokens: raw.totalOutputTokens ?? 0,
|
|
84
|
+
totalCost: raw.totalCost ?? 0,
|
|
85
|
+
sessionId: raw.sessionId ?? null,
|
|
86
|
+
lastMessageAt: raw.lastMessageAt ?? 0,
|
|
87
|
+
updatedAt: raw.updatedAt ?? 0,
|
|
88
|
+
}),
|
|
89
|
+
};
|
|
90
|
+
// ── Action schema (runtime-inspectable declaration) ─────────────────────────
|
|
91
|
+
export const agentActionSchema = defineActionSchema("agent", [
|
|
92
|
+
action("message_received", { ts: "number" }, "User message received, begin processing"),
|
|
93
|
+
action("response_sent", { inputTokens: "number", outputTokens: "number", cost: "number", ts: "number" }, "Agent response completed"),
|
|
94
|
+
action("session_reset", { reason: "string", ts: "number" }, "Conversation session reset"),
|
|
95
|
+
action("session_updated", { sessionId: "string", ts: "number" }, "Session ID changed"),
|
|
96
|
+
action("error", { code: "string", ts: "number" }, "Processing error occurred"),
|
|
97
|
+
]);
|
|
98
|
+
//# sourceMappingURL=agent-reducer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-reducer.js","sourceRoot":"","sources":["../src/agent-reducer.ts"],"names":[],"mappings":"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"}
|
package/dist/anchor.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local anchor service — placeholder for public chain anchoring.
|
|
3
|
+
*
|
|
4
|
+
* Implements the AnchorService interface by writing receipts to a local
|
|
5
|
+
* JSON file. The same interface will be backed by a Base L2 contract
|
|
6
|
+
* when public anchoring is ready — swapping the transport without
|
|
7
|
+
* changing the chain structure above or below.
|
|
8
|
+
*
|
|
9
|
+
* Patent N: Hierarchical Anchor Chains for Verifiable Agent Accountability
|
|
10
|
+
*/
|
|
11
|
+
export interface AnchorReceipt {
|
|
12
|
+
merkleRoot: string;
|
|
13
|
+
timestamp: number;
|
|
14
|
+
level: string;
|
|
15
|
+
}
|
|
16
|
+
export interface AnchorService {
|
|
17
|
+
/** Post a Merkle root anchor. Returns the receipt. */
|
|
18
|
+
anchor(merkleRoot: string, level: string): AnchorReceipt;
|
|
19
|
+
/** Look up an anchor by Merkle root. Returns null if not found. */
|
|
20
|
+
verify(merkleRoot: string): AnchorReceipt | null;
|
|
21
|
+
/** List all anchors. */
|
|
22
|
+
list(): AnchorReceipt[];
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Create an AnchorService backed by a local JSON file.
|
|
26
|
+
*
|
|
27
|
+
* The file is a JSON array of AnchorReceipt objects. Each anchor() call
|
|
28
|
+
* appends a receipt and writes the file. verify() scans for a matching root.
|
|
29
|
+
*/
|
|
30
|
+
export declare function createLocalAnchorService(filePath: string): AnchorService;
|
package/dist/anchor.js
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local anchor service — placeholder for public chain anchoring.
|
|
3
|
+
*
|
|
4
|
+
* Implements the AnchorService interface by writing receipts to a local
|
|
5
|
+
* JSON file. The same interface will be backed by a Base L2 contract
|
|
6
|
+
* when public anchoring is ready — swapping the transport without
|
|
7
|
+
* changing the chain structure above or below.
|
|
8
|
+
*
|
|
9
|
+
* Patent N: Hierarchical Anchor Chains for Verifiable Agent Accountability
|
|
10
|
+
*/
|
|
11
|
+
import assert from "node:assert";
|
|
12
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from "node:fs";
|
|
13
|
+
import { dirname } from "node:path";
|
|
14
|
+
// ── Local file implementation ───────────────────────────────────────────────
|
|
15
|
+
/**
|
|
16
|
+
* Create an AnchorService backed by a local JSON file.
|
|
17
|
+
*
|
|
18
|
+
* The file is a JSON array of AnchorReceipt objects. Each anchor() call
|
|
19
|
+
* appends a receipt and writes the file. verify() scans for a matching root.
|
|
20
|
+
*/
|
|
21
|
+
export function createLocalAnchorService(filePath) {
|
|
22
|
+
assert(filePath, "filePath is required — cannot create anchor service without a storage path");
|
|
23
|
+
function ensureDir() {
|
|
24
|
+
const dir = dirname(filePath);
|
|
25
|
+
if (!existsSync(dir)) {
|
|
26
|
+
mkdirSync(dir, { recursive: true });
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function readAnchors() {
|
|
30
|
+
if (!existsSync(filePath))
|
|
31
|
+
return [];
|
|
32
|
+
try {
|
|
33
|
+
const content = readFileSync(filePath, "utf-8");
|
|
34
|
+
const parsed = JSON.parse(content);
|
|
35
|
+
assert(Array.isArray(parsed), "anchors file must contain a JSON array");
|
|
36
|
+
return parsed;
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return [];
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function writeAnchors(anchors) {
|
|
43
|
+
ensureDir();
|
|
44
|
+
writeFileSync(filePath, JSON.stringify(anchors, null, 2), "utf-8");
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
anchor(merkleRoot, level) {
|
|
48
|
+
assert(merkleRoot, "merkleRoot is required");
|
|
49
|
+
assert(level, "level is required");
|
|
50
|
+
const receipt = {
|
|
51
|
+
merkleRoot,
|
|
52
|
+
timestamp: Date.now(),
|
|
53
|
+
level,
|
|
54
|
+
};
|
|
55
|
+
const anchors = readAnchors();
|
|
56
|
+
anchors.push(receipt);
|
|
57
|
+
writeAnchors(anchors);
|
|
58
|
+
return receipt;
|
|
59
|
+
},
|
|
60
|
+
verify(merkleRoot) {
|
|
61
|
+
assert(merkleRoot, "merkleRoot is required");
|
|
62
|
+
const anchors = readAnchors();
|
|
63
|
+
return anchors.find(a => a.merkleRoot === merkleRoot) ?? null;
|
|
64
|
+
},
|
|
65
|
+
list() {
|
|
66
|
+
return readAnchors();
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=anchor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anchor.js","sourceRoot":"","sources":["../src/anchor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAmBpC,+EAA+E;AAE/E;;;;;GAKG;AACH,MAAM,UAAU,wBAAwB,CAAC,QAAgB;IACvD,MAAM,CAAC,QAAQ,EAAE,4EAA4E,CAAC,CAAC;IAE/F,SAAS,SAAS;QAChB,MAAM,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC9B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACrB,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACtC,CAAC;IACH,CAAC;IAED,SAAS,WAAW;QAClB,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;YAAE,OAAO,EAAE,CAAC;QACrC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAChD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACnC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,wCAAwC,CAAC,CAAC;YACxE,OAAO,MAAyB,CAAC;QACnC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAED,SAAS,YAAY,CAAC,OAAwB;QAC5C,SAAS,EAAE,CAAC;QACZ,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IACrE,CAAC;IAED,OAAO;QACL,MAAM,CAAC,UAAkB,EAAE,KAAa;YACtC,MAAM,CAAC,UAAU,EAAE,wBAAwB,CAAC,CAAC;YAC7C,MAAM,CAAC,KAAK,EAAE,mBAAmB,CAAC,CAAC;YAEnC,MAAM,OAAO,GAAkB;gBAC7B,UAAU;gBACV,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;gBACrB,KAAK;aACN,CAAC;YAEF,MAAM,OAAO,GAAG,WAAW,EAAE,CAAC;YAC9B,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACtB,YAAY,CAAC,OAAO,CAAC,CAAC;YAEtB,OAAO,OAAO,CAAC;QACjB,CAAC;QAED,MAAM,CAAC,UAAkB;YACvB,MAAM,CAAC,UAAU,EAAE,wBAAwB,CAAC,CAAC;YAC7C,MAAM,OAAO,GAAG,WAAW,EAAE,CAAC;YAC9B,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,UAAU,CAAC,IAAI,IAAI,CAAC;QAChE,CAAC;QAED,IAAI;YACF,OAAO,WAAW,EAAE,CAAC;QACvB,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Selective disclosure — package and verify a cartridge's behavioral proof.
|
|
3
|
+
*
|
|
4
|
+
* A DisclosurePackage contains everything a verifier needs to confirm that
|
|
5
|
+
* a specific cartridge behaved according to its reducer, and that its chain
|
|
6
|
+
* is anchored in an operator-level Merkle root — without revealing any
|
|
7
|
+
* information about other cartridges in the tree.
|
|
8
|
+
*
|
|
9
|
+
* Patent N: Hierarchical Anchor Chains for Verifiable Agent Accountability
|
|
10
|
+
*/
|
|
11
|
+
import type { DurableReducer } from "./durable-reducer.js";
|
|
12
|
+
import { type MerkleProof } from "./merkle.js";
|
|
13
|
+
export interface DisclosurePackage {
|
|
14
|
+
/** The cartridge's action log entries (JSONL strings) */
|
|
15
|
+
actionLog: string[];
|
|
16
|
+
/** Hash of the reducer / action schema (from static.json or action-schema.json) */
|
|
17
|
+
reducerRef: string;
|
|
18
|
+
/** Genesis state for replay */
|
|
19
|
+
initialState: Record<string, unknown>;
|
|
20
|
+
/** Merkle inclusion proof linking this cartridge's chain head to the operator anchor */
|
|
21
|
+
merkleProof: MerkleProof;
|
|
22
|
+
/** The anchor_batch action.log line containing the Merkle root */
|
|
23
|
+
anchorEntry: string;
|
|
24
|
+
}
|
|
25
|
+
export interface DisclosureResult {
|
|
26
|
+
ok: boolean;
|
|
27
|
+
/** Reducer replay passed — every action produced the recorded state */
|
|
28
|
+
reducerReplayOk: boolean;
|
|
29
|
+
/** Hash chain is intact — no insertions, deletions, or modifications */
|
|
30
|
+
chainIntegrityOk: boolean;
|
|
31
|
+
/** Merkle proof links chain head to the anchor's Merkle root */
|
|
32
|
+
merkleInclusionOk: boolean;
|
|
33
|
+
/** Number of action log entries verified */
|
|
34
|
+
entriesVerified: number;
|
|
35
|
+
/** Description of the first failure, if any */
|
|
36
|
+
failure?: string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Verify a selective disclosure package.
|
|
40
|
+
*
|
|
41
|
+
* Performs three independent checks:
|
|
42
|
+
* 1. Reducer replay — feed actionLog through the reducer, confirm stateHashes match
|
|
43
|
+
* 2. Chain integrity — confirm hash chain links are intact
|
|
44
|
+
* 3. Merkle inclusion — confirm the chain head is anchored in the operator's root
|
|
45
|
+
*
|
|
46
|
+
* All checks run regardless of earlier failures — the result reports each independently.
|
|
47
|
+
*/
|
|
48
|
+
export declare function verifyDisclosure<S, A extends {
|
|
49
|
+
type: string;
|
|
50
|
+
}>(disclosure: DisclosurePackage, reducer: DurableReducer<S, A>): DisclosureResult;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Selective disclosure — package and verify a cartridge's behavioral proof.
|
|
3
|
+
*
|
|
4
|
+
* A DisclosurePackage contains everything a verifier needs to confirm that
|
|
5
|
+
* a specific cartridge behaved according to its reducer, and that its chain
|
|
6
|
+
* is anchored in an operator-level Merkle root — without revealing any
|
|
7
|
+
* information about other cartridges in the tree.
|
|
8
|
+
*
|
|
9
|
+
* Patent N: Hierarchical Anchor Chains for Verifiable Agent Accountability
|
|
10
|
+
*/
|
|
11
|
+
import assert from "node:assert";
|
|
12
|
+
import { hashLine } from "./durable-reducer.js";
|
|
13
|
+
import { verify } from "./verify.js";
|
|
14
|
+
import { verifyProof } from "./merkle.js";
|
|
15
|
+
// ── Verification ────────────────────────────────────────────────────────────
|
|
16
|
+
/**
|
|
17
|
+
* Verify a selective disclosure package.
|
|
18
|
+
*
|
|
19
|
+
* Performs three independent checks:
|
|
20
|
+
* 1. Reducer replay — feed actionLog through the reducer, confirm stateHashes match
|
|
21
|
+
* 2. Chain integrity — confirm hash chain links are intact
|
|
22
|
+
* 3. Merkle inclusion — confirm the chain head is anchored in the operator's root
|
|
23
|
+
*
|
|
24
|
+
* All checks run regardless of earlier failures — the result reports each independently.
|
|
25
|
+
*/
|
|
26
|
+
export function verifyDisclosure(disclosure, reducer) {
|
|
27
|
+
assert(disclosure.actionLog.length > 0, "disclosure must contain at least one action log entry");
|
|
28
|
+
// ── 1 & 2: Reducer replay + chain integrity ──────────────────────────
|
|
29
|
+
const replayResult = verify(disclosure.actionLog, reducer);
|
|
30
|
+
const reducerReplayOk = replayResult.ok;
|
|
31
|
+
const chainIntegrityOk = replayResult.ok || (replayResult.failure?.type !== "chain_broken" &&
|
|
32
|
+
replayResult.failure?.type !== "parse_error");
|
|
33
|
+
// ── 3: Merkle inclusion ──────────────────────────────────────────────
|
|
34
|
+
// The chain head is the hash of the last action log line.
|
|
35
|
+
const lastLine = disclosure.actionLog[disclosure.actionLog.length - 1];
|
|
36
|
+
const chainHead = hashLine(lastLine);
|
|
37
|
+
// The Merkle proof's leaf should be the chain head
|
|
38
|
+
const leafMatchesChainHead = disclosure.merkleProof.leaf === chainHead;
|
|
39
|
+
// Parse the anchor entry to extract the Merkle root
|
|
40
|
+
let anchorMerkleRoot = null;
|
|
41
|
+
try {
|
|
42
|
+
const anchorAction = JSON.parse(disclosure.anchorEntry);
|
|
43
|
+
anchorMerkleRoot = anchorAction.action?.merkleRoot ?? null;
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
// parse failure handled below
|
|
47
|
+
}
|
|
48
|
+
const proofRootMatchesAnchor = anchorMerkleRoot !== null &&
|
|
49
|
+
disclosure.merkleProof.root === anchorMerkleRoot;
|
|
50
|
+
const proofValid = verifyProof(disclosure.merkleProof);
|
|
51
|
+
const merkleInclusionOk = leafMatchesChainHead && proofRootMatchesAnchor && proofValid;
|
|
52
|
+
// ── Build result ─────────────────────────────────────────────────────
|
|
53
|
+
const ok = reducerReplayOk && chainIntegrityOk && merkleInclusionOk;
|
|
54
|
+
let failure;
|
|
55
|
+
if (!ok) {
|
|
56
|
+
if (!reducerReplayOk && replayResult.failure) {
|
|
57
|
+
failure = `reducer replay failed: ${replayResult.failure.type} at line ${"line" in replayResult.failure ? replayResult.failure.line : "?"}`;
|
|
58
|
+
}
|
|
59
|
+
else if (!chainIntegrityOk && replayResult.failure) {
|
|
60
|
+
failure = `chain integrity failed: ${replayResult.failure.type}`;
|
|
61
|
+
}
|
|
62
|
+
else if (!leafMatchesChainHead) {
|
|
63
|
+
failure = "merkle proof leaf does not match action log chain head";
|
|
64
|
+
}
|
|
65
|
+
else if (!proofRootMatchesAnchor) {
|
|
66
|
+
failure = "merkle proof root does not match anchor entry merkleRoot";
|
|
67
|
+
}
|
|
68
|
+
else if (!proofValid) {
|
|
69
|
+
failure = "merkle proof verification failed — sibling path does not reconstruct root";
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return {
|
|
73
|
+
ok,
|
|
74
|
+
reducerReplayOk,
|
|
75
|
+
chainIntegrityOk,
|
|
76
|
+
merkleInclusionOk,
|
|
77
|
+
entriesVerified: replayResult.entriesVerified,
|
|
78
|
+
failure,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=disclosure.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"disclosure.js","sourceRoot":"","sources":["../src/disclosure.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -32,6 +32,12 @@ export type { DispatcherConfig } from './durable-dispatcher.js';
|
|
|
32
32
|
export { verify } from './verify.js';
|
|
33
33
|
export { containerReducer, containerActionSchema } from './container-reducer.js';
|
|
34
34
|
export type { ContainerStatus, ContainerState, ContainerAction, } from './container-reducer.js';
|
|
35
|
+
export { agentReducer, agentActionSchema } from './agent-reducer.js';
|
|
36
|
+
export type { AgentStatus, AgentState, AgentAction, } from './agent-reducer.js';
|
|
37
|
+
export { operatorAnchorReducer, operatorAnchorActionSchema } from './operator-reducer.js';
|
|
38
|
+
export type { OperatorAnchorState, OperatorAnchorAction, AnchorChildEntry, } from './operator-reducer.js';
|
|
39
|
+
export { computeMerkleRoot, generateProof, verifyProof } from './merkle.js';
|
|
40
|
+
export type { MerkleProof } from './merkle.js';
|
|
35
41
|
export { defineActionSchema, action, writeActionSchema, getSchemaHash, validateAction, } from './action-schema.js';
|
|
36
42
|
export type { ActionSchema, ActionVariant, FieldType, } from './action-schema.js';
|
|
37
43
|
export { hashPolicy, writePolicy, readPolicy, verifyPolicy, isNetworkAllowed, isFilesystemAllowed, isSpawnAllowed, DEFAULT_POLICY, INSTALL_POLICY, } from './policy.js';
|
package/dist/index.js
CHANGED
|
@@ -25,6 +25,9 @@ export { sha256, hashState, hashLine } from './durable-reducer.js';
|
|
|
25
25
|
export { DurableDispatcher } from './durable-dispatcher.js';
|
|
26
26
|
export { verify } from './verify.js';
|
|
27
27
|
export { containerReducer, containerActionSchema } from './container-reducer.js';
|
|
28
|
+
export { agentReducer, agentActionSchema } from './agent-reducer.js';
|
|
29
|
+
export { operatorAnchorReducer, operatorAnchorActionSchema } from './operator-reducer.js';
|
|
30
|
+
export { computeMerkleRoot, generateProof, verifyProof } from './merkle.js';
|
|
28
31
|
export { defineActionSchema, action, writeActionSchema, getSchemaHash, validateAction, } from './action-schema.js';
|
|
29
32
|
// ── Process Policy (Patent M §3.11) ─────────────────────────────────────────
|
|
30
33
|
export { hashPolicy, writePolicy, readPolicy, verifyPolicy, isNetworkAllowed, isFilesystemAllowed, isSpawnAllowed, DEFAULT_POLICY, INSTALL_POLICY, } from './policy.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAGvC,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAG7C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGvC,OAAO,EACL,eAAe,EACf,cAAc,EACd,aAAa,EACb,UAAU,EACV,QAAQ,GACT,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,YAAY,GACb,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,gBAAgB,CAAC;AAQxB,+EAA+E;AAE/E,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAQnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAG5D,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAOjF,OAAO,EACL,kBAAkB,EAClB,MAAM,EACN,iBAAiB,EACjB,aAAa,EACb,cAAc,GACf,MAAM,oBAAoB,CAAC;AAO5B,+EAA+E;AAE/E,OAAO,EACL,UAAU,EACV,WAAW,EACX,UAAU,EACV,YAAY,EACZ,gBAAgB,EAChB,mBAAmB,EACnB,cAAc,EACd,cAAc,EACd,cAAc,GACf,MAAM,aAAa,CAAC;AAUrB,+EAA+E;AAE/E,OAAO,EACL,aAAa,EACb,OAAO,EACP,OAAO,GACR,MAAM,kBAAkB,CAAC;AAO1B,+EAA+E;AAE/E,OAAO,EACL,iBAAiB,EACjB,UAAU,EACV,gBAAgB,EAChB,iBAAiB,EACjB,UAAU,EACV,sBAAsB,EACtB,aAAa,EACb,iBAAiB,EACjB,sBAAsB,EACtB,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,YAAY,EACZ,wBAAwB,EACxB,oBAAoB,EACpB,WAAW,GACZ,MAAM,kBAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAGvC,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAG7C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGvC,OAAO,EACL,eAAe,EACf,cAAc,EACd,aAAa,EACb,UAAU,EACV,QAAQ,GACT,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,YAAY,GACb,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,gBAAgB,CAAC;AAQxB,+EAA+E;AAE/E,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAQnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAG5D,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAOjF,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAOrE,OAAO,EAAE,qBAAqB,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC;AAO1F,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG5E,OAAO,EACL,kBAAkB,EAClB,MAAM,EACN,iBAAiB,EACjB,aAAa,EACb,cAAc,GACf,MAAM,oBAAoB,CAAC;AAO5B,+EAA+E;AAE/E,OAAO,EACL,UAAU,EACV,WAAW,EACX,UAAU,EACV,YAAY,EACZ,gBAAgB,EAChB,mBAAmB,EACnB,cAAc,EACd,cAAc,EACd,cAAc,GACf,MAAM,aAAa,CAAC;AAUrB,+EAA+E;AAE/E,OAAO,EACL,aAAa,EACb,OAAO,EACP,OAAO,GACR,MAAM,kBAAkB,CAAC;AAO1B,+EAA+E;AAE/E,OAAO,EACL,iBAAiB,EACjB,UAAU,EACV,gBAAgB,EAChB,iBAAiB,EACjB,UAAU,EACV,sBAAsB,EACtB,aAAa,EACb,iBAAiB,EACjB,sBAAsB,EACtB,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,YAAY,EACZ,wBAAwB,EACxB,oBAAoB,EACpB,WAAW,GACZ,MAAM,kBAAkB,CAAC"}
|
package/dist/merkle.d.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Merkle tree — deterministic binary tree over sorted leaves.
|
|
3
|
+
*
|
|
4
|
+
* Used by the anchor hierarchy (Patent N) to aggregate chain head hashes
|
|
5
|
+
* into a single root. Supports proof generation for selective disclosure:
|
|
6
|
+
* prove one leaf is included in the root without revealing sibling leaves.
|
|
7
|
+
*
|
|
8
|
+
* Construction rules:
|
|
9
|
+
* - Leaves are sorted lexicographically before tree construction
|
|
10
|
+
* - Odd leaf counts: last leaf is duplicated (standard padding)
|
|
11
|
+
* - Pairing: SHA-256(left || right) at each level
|
|
12
|
+
* - Empty input: SHA-256 of empty string
|
|
13
|
+
*
|
|
14
|
+
* Patent N: Hierarchical Anchor Chains for Verifiable Agent Accountability
|
|
15
|
+
*/
|
|
16
|
+
export interface MerkleProof {
|
|
17
|
+
/** The leaf hash being proven */
|
|
18
|
+
leaf: string;
|
|
19
|
+
/** Leaf position in sorted order */
|
|
20
|
+
index: number;
|
|
21
|
+
/** Sibling hashes from leaf to root, with direction */
|
|
22
|
+
siblings: Array<{
|
|
23
|
+
hash: string;
|
|
24
|
+
direction: "left" | "right";
|
|
25
|
+
}>;
|
|
26
|
+
/** The claimed Merkle root */
|
|
27
|
+
root: string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Compute the Merkle root of a set of leaf hashes.
|
|
31
|
+
*
|
|
32
|
+
* Leaves are NOT pre-sorted — the caller provides them in the desired order.
|
|
33
|
+
* For anchor chains, sort by child name before calling.
|
|
34
|
+
*/
|
|
35
|
+
export declare function computeMerkleRoot(leaves: string[]): string;
|
|
36
|
+
/**
|
|
37
|
+
* Generate a Merkle inclusion proof for the leaf at `index`.
|
|
38
|
+
*
|
|
39
|
+
* The proof contains sibling hashes and directions needed to reconstruct
|
|
40
|
+
* the root from the leaf. The verifier learns the tree depth and leaf
|
|
41
|
+
* position but not the content of any sibling leaf.
|
|
42
|
+
*/
|
|
43
|
+
export declare function generateProof(leaves: string[], index: number): MerkleProof;
|
|
44
|
+
/**
|
|
45
|
+
* Verify a Merkle inclusion proof.
|
|
46
|
+
*
|
|
47
|
+
* Reconstructs the root from the leaf and sibling hashes, then compares
|
|
48
|
+
* against the claimed root. Returns true if they match.
|
|
49
|
+
*/
|
|
50
|
+
export declare function verifyProof(proof: MerkleProof): boolean;
|
package/dist/merkle.js
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Merkle tree — deterministic binary tree over sorted leaves.
|
|
3
|
+
*
|
|
4
|
+
* Used by the anchor hierarchy (Patent N) to aggregate chain head hashes
|
|
5
|
+
* into a single root. Supports proof generation for selective disclosure:
|
|
6
|
+
* prove one leaf is included in the root without revealing sibling leaves.
|
|
7
|
+
*
|
|
8
|
+
* Construction rules:
|
|
9
|
+
* - Leaves are sorted lexicographically before tree construction
|
|
10
|
+
* - Odd leaf counts: last leaf is duplicated (standard padding)
|
|
11
|
+
* - Pairing: SHA-256(left || right) at each level
|
|
12
|
+
* - Empty input: SHA-256 of empty string
|
|
13
|
+
*
|
|
14
|
+
* Patent N: Hierarchical Anchor Chains for Verifiable Agent Accountability
|
|
15
|
+
*/
|
|
16
|
+
import { sha256 } from "./durable-reducer.js";
|
|
17
|
+
import assert from "node:assert";
|
|
18
|
+
// ── Tree construction ───────────────────────────────────────────────────────
|
|
19
|
+
/**
|
|
20
|
+
* Compute the Merkle root of a set of leaf hashes.
|
|
21
|
+
*
|
|
22
|
+
* Leaves are NOT pre-sorted — the caller provides them in the desired order.
|
|
23
|
+
* For anchor chains, sort by child name before calling.
|
|
24
|
+
*/
|
|
25
|
+
export function computeMerkleRoot(leaves) {
|
|
26
|
+
if (leaves.length === 0)
|
|
27
|
+
return sha256("");
|
|
28
|
+
let level = [...leaves];
|
|
29
|
+
while (level.length > 1) {
|
|
30
|
+
// Odd count: duplicate last leaf
|
|
31
|
+
if (level.length % 2 !== 0) {
|
|
32
|
+
level.push(level[level.length - 1]);
|
|
33
|
+
}
|
|
34
|
+
const nextLevel = [];
|
|
35
|
+
for (let i = 0; i < level.length; i += 2) {
|
|
36
|
+
nextLevel.push(sha256(level[i] + level[i + 1]));
|
|
37
|
+
}
|
|
38
|
+
level = nextLevel;
|
|
39
|
+
}
|
|
40
|
+
return level[0];
|
|
41
|
+
}
|
|
42
|
+
// ── Proof generation ────────────────────────────────────────────────────────
|
|
43
|
+
/**
|
|
44
|
+
* Generate a Merkle inclusion proof for the leaf at `index`.
|
|
45
|
+
*
|
|
46
|
+
* The proof contains sibling hashes and directions needed to reconstruct
|
|
47
|
+
* the root from the leaf. The verifier learns the tree depth and leaf
|
|
48
|
+
* position but not the content of any sibling leaf.
|
|
49
|
+
*/
|
|
50
|
+
export function generateProof(leaves, index) {
|
|
51
|
+
assert(leaves.length > 0, "cannot generate proof for empty tree");
|
|
52
|
+
assert(index >= 0 && index < leaves.length, `index ${index} out of bounds for ${leaves.length} leaves`);
|
|
53
|
+
const root = computeMerkleRoot(leaves);
|
|
54
|
+
// Single leaf — no siblings needed
|
|
55
|
+
if (leaves.length === 1) {
|
|
56
|
+
return { leaf: leaves[0], index, siblings: [], root };
|
|
57
|
+
}
|
|
58
|
+
let level = [...leaves];
|
|
59
|
+
let currentIndex = index;
|
|
60
|
+
const siblings = [];
|
|
61
|
+
while (level.length > 1) {
|
|
62
|
+
if (level.length % 2 !== 0) {
|
|
63
|
+
level.push(level[level.length - 1]);
|
|
64
|
+
}
|
|
65
|
+
const siblingIndex = currentIndex % 2 === 0 ? currentIndex + 1 : currentIndex - 1;
|
|
66
|
+
const direction = currentIndex % 2 === 0 ? "right" : "left";
|
|
67
|
+
siblings.push({ hash: level[siblingIndex], direction });
|
|
68
|
+
// Move up: parent index is floor(currentIndex / 2)
|
|
69
|
+
currentIndex = Math.floor(currentIndex / 2);
|
|
70
|
+
const nextLevel = [];
|
|
71
|
+
for (let i = 0; i < level.length; i += 2) {
|
|
72
|
+
nextLevel.push(sha256(level[i] + level[i + 1]));
|
|
73
|
+
}
|
|
74
|
+
level = nextLevel;
|
|
75
|
+
}
|
|
76
|
+
return { leaf: leaves[index], index, siblings, root };
|
|
77
|
+
}
|
|
78
|
+
// ── Proof verification ──────────────────────────────────────────────────────
|
|
79
|
+
/**
|
|
80
|
+
* Verify a Merkle inclusion proof.
|
|
81
|
+
*
|
|
82
|
+
* Reconstructs the root from the leaf and sibling hashes, then compares
|
|
83
|
+
* against the claimed root. Returns true if they match.
|
|
84
|
+
*/
|
|
85
|
+
export function verifyProof(proof) {
|
|
86
|
+
let hash = proof.leaf;
|
|
87
|
+
for (const sibling of proof.siblings) {
|
|
88
|
+
if (sibling.direction === "right") {
|
|
89
|
+
// sibling is on the right, current hash is on the left
|
|
90
|
+
hash = sha256(hash + sibling.hash);
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
// sibling is on the left, current hash is on the right
|
|
94
|
+
hash = sha256(sibling.hash + hash);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return hash === proof.root;
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=merkle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"merkle.js","sourceRoot":"","sources":["../src/merkle.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Operator anchor reducer — aggregates cartridge chain heads into a Merkle root.
|
|
3
|
+
*
|
|
4
|
+
* The operator anchor is a DurableReducer whose state tracks the chain head
|
|
5
|
+
* hashes of all cartridges (agents, services, infrastructure) under one
|
|
6
|
+
* supervisor. Periodically, the bridge dispatches an anchor_batch action
|
|
7
|
+
* that records the Merkle root over all children — the value that would
|
|
8
|
+
* be anchored to the next level (section/org/public).
|
|
9
|
+
*
|
|
10
|
+
* This reducer is structurally identical to a cartridge reducer: same
|
|
11
|
+
* dispatch, hash-chain, persist, verify primitives. The difference is
|
|
12
|
+
* what it tracks: chain head hashes of children, not application state.
|
|
13
|
+
*
|
|
14
|
+
* Patent N: Hierarchical Anchor Chains for Verifiable Agent Accountability
|
|
15
|
+
*/
|
|
16
|
+
import type { DurableReducer } from "./durable-reducer.js";
|
|
17
|
+
import { type ActionSchema } from "./action-schema.js";
|
|
18
|
+
export interface AnchorChildEntry {
|
|
19
|
+
chainHead: string;
|
|
20
|
+
seq: number;
|
|
21
|
+
anchoredAt: number;
|
|
22
|
+
}
|
|
23
|
+
export interface OperatorAnchorState {
|
|
24
|
+
children: Record<string, AnchorChildEntry>;
|
|
25
|
+
merkleRoot: string | null;
|
|
26
|
+
anchorCount: number;
|
|
27
|
+
updatedAt: number;
|
|
28
|
+
}
|
|
29
|
+
export type OperatorAnchorAction = {
|
|
30
|
+
type: "anchor_child";
|
|
31
|
+
name: string;
|
|
32
|
+
chainHead: string;
|
|
33
|
+
seq: number;
|
|
34
|
+
ts: number;
|
|
35
|
+
} | {
|
|
36
|
+
type: "anchor_batch";
|
|
37
|
+
merkleRoot: string;
|
|
38
|
+
childCount: number;
|
|
39
|
+
ts: number;
|
|
40
|
+
} | {
|
|
41
|
+
type: "child_added";
|
|
42
|
+
name: string;
|
|
43
|
+
ts: number;
|
|
44
|
+
} | {
|
|
45
|
+
type: "child_removed";
|
|
46
|
+
name: string;
|
|
47
|
+
ts: number;
|
|
48
|
+
};
|
|
49
|
+
export declare const operatorAnchorReducer: DurableReducer<OperatorAnchorState, OperatorAnchorAction>;
|
|
50
|
+
export declare const operatorAnchorActionSchema: ActionSchema;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Operator anchor reducer — aggregates cartridge chain heads into a Merkle root.
|
|
3
|
+
*
|
|
4
|
+
* The operator anchor is a DurableReducer whose state tracks the chain head
|
|
5
|
+
* hashes of all cartridges (agents, services, infrastructure) under one
|
|
6
|
+
* supervisor. Periodically, the bridge dispatches an anchor_batch action
|
|
7
|
+
* that records the Merkle root over all children — the value that would
|
|
8
|
+
* be anchored to the next level (section/org/public).
|
|
9
|
+
*
|
|
10
|
+
* This reducer is structurally identical to a cartridge reducer: same
|
|
11
|
+
* dispatch, hash-chain, persist, verify primitives. The difference is
|
|
12
|
+
* what it tracks: chain head hashes of children, not application state.
|
|
13
|
+
*
|
|
14
|
+
* Patent N: Hierarchical Anchor Chains for Verifiable Agent Accountability
|
|
15
|
+
*/
|
|
16
|
+
import assert from "node:assert";
|
|
17
|
+
import { defineActionSchema, action } from "./action-schema.js";
|
|
18
|
+
// ── Reducer ─────────────────────────────────────────────────────────────────
|
|
19
|
+
function reduce(state, action) {
|
|
20
|
+
switch (action.type) {
|
|
21
|
+
case "anchor_child": {
|
|
22
|
+
assert(action.name, "anchor_child requires a name");
|
|
23
|
+
assert(action.chainHead, "anchor_child requires a chainHead");
|
|
24
|
+
return {
|
|
25
|
+
...state,
|
|
26
|
+
children: {
|
|
27
|
+
...state.children,
|
|
28
|
+
[action.name]: {
|
|
29
|
+
chainHead: action.chainHead,
|
|
30
|
+
seq: action.seq,
|
|
31
|
+
anchoredAt: action.ts,
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
updatedAt: action.ts,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
case "anchor_batch": {
|
|
38
|
+
// No children → no batch. The bridge should not dispatch this.
|
|
39
|
+
const childCount = Object.keys(state.children).length;
|
|
40
|
+
if (childCount === 0)
|
|
41
|
+
return state;
|
|
42
|
+
assert(action.merkleRoot, "anchor_batch requires a merkleRoot");
|
|
43
|
+
return {
|
|
44
|
+
...state,
|
|
45
|
+
merkleRoot: action.merkleRoot,
|
|
46
|
+
anchorCount: state.anchorCount + 1,
|
|
47
|
+
updatedAt: action.ts,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
case "child_added": {
|
|
51
|
+
assert(action.name, "child_added requires a name");
|
|
52
|
+
// Already exists → no-op (idempotent)
|
|
53
|
+
if (state.children[action.name])
|
|
54
|
+
return state;
|
|
55
|
+
return {
|
|
56
|
+
...state,
|
|
57
|
+
children: {
|
|
58
|
+
...state.children,
|
|
59
|
+
[action.name]: { chainHead: "", seq: 0, anchoredAt: 0 },
|
|
60
|
+
},
|
|
61
|
+
updatedAt: action.ts,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
case "child_removed": {
|
|
65
|
+
assert(action.name, "child_removed requires a name");
|
|
66
|
+
// Doesn't exist → no-op
|
|
67
|
+
if (!state.children[action.name])
|
|
68
|
+
return state;
|
|
69
|
+
const { [action.name]: _, ...rest } = state.children;
|
|
70
|
+
return {
|
|
71
|
+
...state,
|
|
72
|
+
children: rest,
|
|
73
|
+
updatedAt: action.ts,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
default:
|
|
77
|
+
return state;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// ── DurableReducer implementation ───────────────────────────────────────────
|
|
81
|
+
export const operatorAnchorReducer = {
|
|
82
|
+
reduce,
|
|
83
|
+
init: () => ({
|
|
84
|
+
children: {},
|
|
85
|
+
merkleRoot: null,
|
|
86
|
+
anchorCount: 0,
|
|
87
|
+
updatedAt: 0,
|
|
88
|
+
}),
|
|
89
|
+
serialize: (state) => ({ ...state }),
|
|
90
|
+
deserialize: (raw) => ({
|
|
91
|
+
children: raw.children ?? {},
|
|
92
|
+
merkleRoot: raw.merkleRoot ?? null,
|
|
93
|
+
anchorCount: raw.anchorCount ?? 0,
|
|
94
|
+
updatedAt: raw.updatedAt ?? 0,
|
|
95
|
+
}),
|
|
96
|
+
};
|
|
97
|
+
// ── Action schema ───────────────────────────────────────────────────────────
|
|
98
|
+
export const operatorAnchorActionSchema = defineActionSchema("operator-anchor", [
|
|
99
|
+
action("anchor_child", { name: "string", chainHead: "string", seq: "number", ts: "number" }, "Record a child cartridge's chain head hash"),
|
|
100
|
+
action("anchor_batch", { merkleRoot: "string", childCount: "number", ts: "number" }, "Record Merkle root over all children"),
|
|
101
|
+
action("child_added", { name: "string", ts: "number" }, "Register a new child chain"),
|
|
102
|
+
action("child_removed", { name: "string", ts: "number" }, "Remove a child chain"),
|
|
103
|
+
]);
|
|
104
|
+
//# sourceMappingURL=operator-reducer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operator-reducer.js","sourceRoot":"","sources":["../src/operator-reducer.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@helmetfire-labs/cartridge-common",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Shared logging, error boundaries, trace helpers, and durable reducer runtime for infrastructure cartridges",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -27,4 +27,4 @@
|
|
|
27
27
|
"typescript": "^5.0.0",
|
|
28
28
|
"vitest": "^3.0.0"
|
|
29
29
|
}
|
|
30
|
-
}
|
|
30
|
+
}
|