@guyghost/swarm-dao-graph 0.2.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 +29 -0
- package/dist/cli.d.ts +10 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +52 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/runner.d.ts +27 -0
- package/dist/runner.d.ts.map +1 -0
- package/dist/runner.js +143 -0
- package/dist/runner.js.map +1 -0
- package/dist/signal.d.ts +20 -0
- package/dist/signal.d.ts.map +1 -0
- package/dist/signal.js +155 -0
- package/dist/signal.js.map +1 -0
- package/package.json +54 -0
package/README.md
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# @guyghost/swarm-dao-graph
|
|
2
|
+
|
|
3
|
+
Swarm DAO Graph Engineering run executor.
|
|
4
|
+
|
|
5
|
+
Runs the frozen Graph Engineering machine (in `@guyghost/swarm-dao-core`) as
|
|
6
|
+
journal-replayed runs on disk: every submitted signal is validated (AI signals
|
|
7
|
+
never carry state targets, commands, approvals, retries, cancellations, or
|
|
8
|
+
permission decisions), journaled to `journal.ndjson`, and the snapshot is
|
|
9
|
+
persisted for deterministic replay.
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import { createGraphRunner, validateGraphSignal } from "@guyghost/swarm-dao-graph";
|
|
15
|
+
|
|
16
|
+
const runner = await createGraphRunner({ evidenceRoot: ".dao/graph-runs", runId: "my-run" });
|
|
17
|
+
const result = await runner.submit(signal);
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Or through the CLI entry:
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
import { runGraphCli } from "@guyghost/swarm-dao-graph";
|
|
24
|
+
const code = await runGraphCli(["status", "--run-id", "my-run"]); // 0 | 1 | 2
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
The `swarm-dao` CLI exposes the same surface as `swarm-dao graph
|
|
28
|
+
<init|status|submit>`; exit codes are 0 (success), 2 (machine rejection),
|
|
29
|
+
1 (usage or execution error).
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface GraphCliDefaults {
|
|
2
|
+
/** Evidence root used when --evidence-root is absent (resolved from cwd). */
|
|
3
|
+
evidenceRoot?: string;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Entry point for the `graph:*` repo scripts and the swarm-dao CLI.
|
|
7
|
+
* Exit codes: 0 success, 2 machine rejection, 1 usage or execution error.
|
|
8
|
+
*/
|
|
9
|
+
export declare const runGraphCli: (argv: readonly string[], defaults?: GraphCliDefaults) => Promise<number>;
|
|
10
|
+
//# sourceMappingURL=cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAYA,MAAM,WAAW,gBAAgB;IAC/B,6EAA6E;IAC7E,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAMD;;;GAGG;AACH,eAAO,MAAM,WAAW,GAAU,MAAM,SAAS,MAAM,EAAE,EAAE,WAAU,gBAAqB,KAAG,OAAO,CAAC,MAAM,CAkC1G,CAAC"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// Swarm DAO — Graph Engineering run CLI.
|
|
2
|
+
//
|
|
3
|
+
// Thin host entry over GraphRunner: init/status/submit with the same exit-code
|
|
4
|
+
// contract as the improvement series CLI (0 success, 2 machine rejection,
|
|
5
|
+
// 1 usage or execution error). Hosts stay free of transition rules — every
|
|
6
|
+
// submitted signal passes through validateGraphSignal and the frozen machine.
|
|
7
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
8
|
+
import { resolve } from "node:path";
|
|
9
|
+
import { parseArgs } from "node:util";
|
|
10
|
+
import { createGraphRunner } from "./runner.js";
|
|
11
|
+
const usage = `Usage:
|
|
12
|
+
graph <init|status|submit> --run-id <id> [--evidence-root <path>]
|
|
13
|
+
graph submit --run-id <id> --signal <file> [--evidence-root <path>]`;
|
|
14
|
+
/**
|
|
15
|
+
* Entry point for the `graph:*` repo scripts and the swarm-dao CLI.
|
|
16
|
+
* Exit codes: 0 success, 2 machine rejection, 1 usage or execution error.
|
|
17
|
+
*/
|
|
18
|
+
export const runGraphCli = async (argv, defaults = {}) => {
|
|
19
|
+
const command = argv[0];
|
|
20
|
+
if (command !== "init" && command !== "status" && command !== "submit")
|
|
21
|
+
throw new Error(usage);
|
|
22
|
+
const { values } = parseArgs({
|
|
23
|
+
args: argv.slice(1),
|
|
24
|
+
strict: true,
|
|
25
|
+
options: {
|
|
26
|
+
"run-id": { type: "string" },
|
|
27
|
+
"evidence-root": { type: "string" },
|
|
28
|
+
signal: { type: "string" },
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
const runId = values["run-id"];
|
|
32
|
+
if (!runId)
|
|
33
|
+
throw new Error(`--run-id is required\n${usage}`);
|
|
34
|
+
const evidenceRoot = resolve(values["evidence-root"] ?? defaults.evidenceRoot ?? ".dao/graph-runs");
|
|
35
|
+
if (command === "submit" && !values.signal)
|
|
36
|
+
throw new Error(`--signal is required\n${usage}`);
|
|
37
|
+
const runner = await createGraphRunner({ evidenceRoot, runId });
|
|
38
|
+
if (command === "init") {
|
|
39
|
+
await writeFile(resolve(evidenceRoot, "active-run.json"), `${JSON.stringify({ runId }, null, 2)}\n`, "utf8");
|
|
40
|
+
process.stdout.write(`${JSON.stringify(runner.snapshot(), null, 2)}\n`);
|
|
41
|
+
return 0;
|
|
42
|
+
}
|
|
43
|
+
if (command === "status") {
|
|
44
|
+
process.stdout.write(`${JSON.stringify(runner.snapshot(), null, 2)}\n`);
|
|
45
|
+
return 0;
|
|
46
|
+
}
|
|
47
|
+
const signal = JSON.parse(await readFile(resolve(values.signal), "utf8"));
|
|
48
|
+
const result = await runner.submit(signal);
|
|
49
|
+
process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
|
|
50
|
+
return result.accepted ? 0 : 2;
|
|
51
|
+
};
|
|
52
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// @guyghost/swarm-dao-graph — executor for Swarm DAO Graph Engineering runs:
|
|
2
|
+
// journal-replayed change-control runs over the frozen machine in
|
|
3
|
+
// @guyghost/swarm-dao-core, with strict signal validation (AI signals never
|
|
4
|
+
// carry authority keys; human-source events cannot be forged by tools).
|
|
5
|
+
export * from "./cli.js";
|
|
6
|
+
export * from "./runner.js";
|
|
7
|
+
export * from "./signal.js";
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,kEAAkE;AAClE,4EAA4E;AAC5E,wEAAwE;AAExE,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC"}
|
package/dist/runner.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type GraphEngineeringContext } from "@guyghost/swarm-dao-core";
|
|
2
|
+
export type PersistedGraphSnapshot = Readonly<{
|
|
3
|
+
runId: string;
|
|
4
|
+
state: string;
|
|
5
|
+
status: string;
|
|
6
|
+
context: GraphEngineeringContext;
|
|
7
|
+
}>;
|
|
8
|
+
export type GraphSubmissionResult = Readonly<{
|
|
9
|
+
accepted: boolean;
|
|
10
|
+
issues: readonly string[];
|
|
11
|
+
snapshot: PersistedGraphSnapshot;
|
|
12
|
+
}>;
|
|
13
|
+
type RunnerOptions = Readonly<{
|
|
14
|
+
evidenceRoot: string;
|
|
15
|
+
runId: string;
|
|
16
|
+
clock?: () => string;
|
|
17
|
+
}>;
|
|
18
|
+
export declare class GraphRunner {
|
|
19
|
+
#private;
|
|
20
|
+
private constructor();
|
|
21
|
+
static create(options: RunnerOptions): Promise<GraphRunner>;
|
|
22
|
+
snapshot(): PersistedGraphSnapshot;
|
|
23
|
+
submit(input: unknown): Promise<GraphSubmissionResult>;
|
|
24
|
+
}
|
|
25
|
+
export declare const createGraphRunner: (options: RunnerOptions) => Promise<GraphRunner>;
|
|
26
|
+
export {};
|
|
27
|
+
//# sourceMappingURL=runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,uBAAuB,EAC7B,MAAM,0BAA0B,CAAC;AAGlC,MAAM,MAAM,sBAAsB,GAAG,QAAQ,CAAC;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,uBAAuB,CAAC;CAClC,CAAC,CAAC;AAEH,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAAC;IAC3C,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,QAAQ,EAAE,sBAAsB,CAAC;CAClC,CAAC,CAAC;AAeH,KAAK,aAAa,GAAG,QAAQ,CAAC;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,MAAM,CAAC;CACtB,CAAC,CAAC;AAyBH,qBAAa,WAAW;;IAQtB,OAAO;WAOM,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,WAAW,CAAC;IAcjE,QAAQ,IAAI,sBAAsB;IAIlC,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,qBAAqB,CAAC;CA8FvD;AAED,eAAO,MAAM,iBAAiB,GAAI,SAAS,aAAa,KAAG,OAAO,CAAC,WAAW,CAAgC,CAAC"}
|
package/dist/runner.js
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { appendFile, mkdir, readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import { resolve, sep } from "node:path";
|
|
3
|
+
import { createGraphEngineeringActor, } from "@guyghost/swarm-dao-core";
|
|
4
|
+
import { validateGraphSignal } from "./signal.js";
|
|
5
|
+
const validRunId = (runId) => /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/.test(runId) && !runId.includes("..");
|
|
6
|
+
const eventTypeFrom = (input) => {
|
|
7
|
+
if (typeof input !== "object" || input === null || !("type" in input))
|
|
8
|
+
return null;
|
|
9
|
+
return typeof input.type === "string" ? input.type : null;
|
|
10
|
+
};
|
|
11
|
+
const serializeSnapshot = (actor) => {
|
|
12
|
+
const snapshot = actor.getSnapshot();
|
|
13
|
+
return {
|
|
14
|
+
runId: snapshot.context.runId,
|
|
15
|
+
state: String(snapshot.value),
|
|
16
|
+
status: snapshot.status,
|
|
17
|
+
context: structuredClone(snapshot.context),
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
const snapshotChanged = (before, after) => before.state !== after.state ||
|
|
21
|
+
before.status !== after.status ||
|
|
22
|
+
JSON.stringify(before.context) !== JSON.stringify(after.context);
|
|
23
|
+
export class GraphRunner {
|
|
24
|
+
#runId;
|
|
25
|
+
#runDirectory;
|
|
26
|
+
#clock;
|
|
27
|
+
#actor;
|
|
28
|
+
#sequence = 0;
|
|
29
|
+
#tail = Promise.resolve();
|
|
30
|
+
constructor(options, runDirectory) {
|
|
31
|
+
this.#runId = options.runId;
|
|
32
|
+
this.#runDirectory = runDirectory;
|
|
33
|
+
this.#clock = options.clock ?? (() => new Date().toISOString());
|
|
34
|
+
this.#actor = createGraphEngineeringActor(options.runId);
|
|
35
|
+
}
|
|
36
|
+
static async create(options) {
|
|
37
|
+
if (!validRunId(options.runId))
|
|
38
|
+
throw new Error("runId must be a safe non-empty filesystem identifier");
|
|
39
|
+
const root = resolve(options.evidenceRoot);
|
|
40
|
+
const runDirectory = resolve(root, options.runId);
|
|
41
|
+
if (!runDirectory.startsWith(`${root}${sep}`))
|
|
42
|
+
throw new Error("runId resolves outside the evidence root");
|
|
43
|
+
await mkdir(runDirectory, { recursive: true });
|
|
44
|
+
const runner = new GraphRunner(options, runDirectory);
|
|
45
|
+
await runner.#restoreJournal();
|
|
46
|
+
await runner.#persistSnapshot(serializeSnapshot(runner.#actor));
|
|
47
|
+
return runner;
|
|
48
|
+
}
|
|
49
|
+
snapshot() {
|
|
50
|
+
return serializeSnapshot(this.#actor);
|
|
51
|
+
}
|
|
52
|
+
submit(input) {
|
|
53
|
+
const operation = this.#tail.then(() => this.#submitNow(input));
|
|
54
|
+
this.#tail = operation.then(() => undefined, () => undefined);
|
|
55
|
+
return operation;
|
|
56
|
+
}
|
|
57
|
+
async #submitNow(input) {
|
|
58
|
+
const before = serializeSnapshot(this.#actor);
|
|
59
|
+
const validation = validateGraphSignal(input);
|
|
60
|
+
let accepted = false;
|
|
61
|
+
let issues = [];
|
|
62
|
+
let signal;
|
|
63
|
+
if (!validation.ok) {
|
|
64
|
+
issues = validation.issues;
|
|
65
|
+
}
|
|
66
|
+
else if (validation.signal.runId !== this.#runId) {
|
|
67
|
+
issues = [`signal runId must match ${this.#runId}`];
|
|
68
|
+
signal = validation.signal;
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
signal = validation.signal;
|
|
72
|
+
this.#actor.send(validation.event);
|
|
73
|
+
accepted = snapshotChanged(before, serializeSnapshot(this.#actor));
|
|
74
|
+
if (!accepted)
|
|
75
|
+
issues = ["machine rejected event for the current state or guards"];
|
|
76
|
+
}
|
|
77
|
+
const after = serializeSnapshot(this.#actor);
|
|
78
|
+
const entry = {
|
|
79
|
+
sequence: ++this.#sequence,
|
|
80
|
+
runId: this.#runId,
|
|
81
|
+
receivedAt: this.#clock(),
|
|
82
|
+
eventType: eventTypeFrom(input),
|
|
83
|
+
producer: signal?.producer ?? null,
|
|
84
|
+
accepted,
|
|
85
|
+
issues,
|
|
86
|
+
beforeState: before.state,
|
|
87
|
+
afterState: after.state,
|
|
88
|
+
...(signal ? { signal } : {}),
|
|
89
|
+
};
|
|
90
|
+
await appendFile(resolve(this.#runDirectory, "journal.ndjson"), `${JSON.stringify(entry)}\n`, "utf8");
|
|
91
|
+
await this.#persistSnapshot(after);
|
|
92
|
+
return { accepted, issues, snapshot: after };
|
|
93
|
+
}
|
|
94
|
+
async #persistSnapshot(snapshot) {
|
|
95
|
+
await writeFile(resolve(this.#runDirectory, "snapshot.json"), `${JSON.stringify(snapshot, null, 2)}\n`, "utf8");
|
|
96
|
+
}
|
|
97
|
+
async #restoreJournal() {
|
|
98
|
+
const journalPath = resolve(this.#runDirectory, "journal.ndjson");
|
|
99
|
+
let content;
|
|
100
|
+
try {
|
|
101
|
+
content = await readFile(journalPath, "utf8");
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
if (typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT")
|
|
105
|
+
return;
|
|
106
|
+
throw error;
|
|
107
|
+
}
|
|
108
|
+
const lines = content.split("\n").filter((line) => line.trim().length > 0);
|
|
109
|
+
for (const [index, line] of lines.entries()) {
|
|
110
|
+
let entry;
|
|
111
|
+
try {
|
|
112
|
+
entry = JSON.parse(line);
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
throw new Error(`journal line ${index + 1} is not valid JSON`);
|
|
116
|
+
}
|
|
117
|
+
if (typeof entry !== "object" ||
|
|
118
|
+
entry === null ||
|
|
119
|
+
!("sequence" in entry) ||
|
|
120
|
+
entry.sequence !== index + 1 ||
|
|
121
|
+
!("accepted" in entry) ||
|
|
122
|
+
typeof entry.accepted !== "boolean") {
|
|
123
|
+
throw new Error(`journal line ${index + 1} violates sequence contract`);
|
|
124
|
+
}
|
|
125
|
+
this.#sequence = entry.sequence;
|
|
126
|
+
if (!entry.accepted)
|
|
127
|
+
continue;
|
|
128
|
+
if (!("signal" in entry))
|
|
129
|
+
throw new Error(`accepted journal line ${index + 1} has no signal`);
|
|
130
|
+
const validation = validateGraphSignal(entry.signal);
|
|
131
|
+
if (!validation.ok || validation.signal.runId !== this.#runId) {
|
|
132
|
+
throw new Error(`accepted journal line ${index + 1} has an invalid signal`);
|
|
133
|
+
}
|
|
134
|
+
const before = serializeSnapshot(this.#actor);
|
|
135
|
+
this.#actor.send(validation.event);
|
|
136
|
+
if (!snapshotChanged(before, serializeSnapshot(this.#actor))) {
|
|
137
|
+
throw new Error(`accepted journal line ${index + 1} cannot be replayed deterministically`);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
export const createGraphRunner = (options) => GraphRunner.create(options);
|
|
143
|
+
//# sourceMappingURL=runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"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"}
|
package/dist/signal.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type GraphEngineeringEvent, type GraphSignalSource } from "@guyghost/swarm-dao-core";
|
|
2
|
+
export type GraphSignal = Readonly<{
|
|
3
|
+
runId: string;
|
|
4
|
+
type: string;
|
|
5
|
+
source: GraphSignalSource;
|
|
6
|
+
producer: string;
|
|
7
|
+
occurredAt: string;
|
|
8
|
+
payload: Readonly<Record<string, unknown>>;
|
|
9
|
+
evidence: readonly string[];
|
|
10
|
+
}>;
|
|
11
|
+
export type GraphSignalValidation = Readonly<{
|
|
12
|
+
ok: true;
|
|
13
|
+
signal: GraphSignal;
|
|
14
|
+
event: GraphEngineeringEvent;
|
|
15
|
+
}> | Readonly<{
|
|
16
|
+
ok: false;
|
|
17
|
+
issues: readonly string[];
|
|
18
|
+
}>;
|
|
19
|
+
export declare const validateGraphSignal: (input: unknown) => GraphSignalValidation;
|
|
20
|
+
//# sourceMappingURL=signal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signal.d.ts","sourceRoot":"","sources":["../src/signal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,qBAAqB,EAAE,KAAK,iBAAiB,EAAyB,MAAM,0BAA0B,CAAC;AAErH,MAAM,MAAM,WAAW,GAAG,QAAQ,CAAC;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,iBAAiB,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC3C,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7B,CAAC,CAAC;AAEH,MAAM,MAAM,qBAAqB,GAC7B,QAAQ,CAAC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,qBAAqB,CAAA;CAAE,CAAC,GACzE,QAAQ,CAAC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAAC,CAAC;AAwHvD,eAAO,MAAM,mBAAmB,GAAI,OAAO,OAAO,KAAG,qBAgDpD,CAAC"}
|
package/dist/signal.js
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { isRequiredGraphAnchor } from "@guyghost/swarm-dao-core";
|
|
2
|
+
const EVENT_SOURCES = {
|
|
3
|
+
MODEL_DRAFTED: "ai",
|
|
4
|
+
MODEL_CONTRACT_VALID: "tool",
|
|
5
|
+
MODEL_CONTRACT_INVALID: "tool",
|
|
6
|
+
MODEL_APPROVED: "human",
|
|
7
|
+
MODEL_REJECTED: "human",
|
|
8
|
+
START_IMPLEMENTATION: "system",
|
|
9
|
+
IMPLEMENTATION_READY: "ai",
|
|
10
|
+
IMPLEMENTATION_FAILED: "ai",
|
|
11
|
+
ANCHOR_RECORDED: "tool",
|
|
12
|
+
EVALUATE: "system",
|
|
13
|
+
RETRY_AUTHORIZED: "human",
|
|
14
|
+
PERMISSION_DENIED: "tool",
|
|
15
|
+
CANCEL: "human",
|
|
16
|
+
};
|
|
17
|
+
const FORBIDDEN_TRANSITION_KEYS = new Set(["nextState", "targetState", "transition"]);
|
|
18
|
+
const FORBIDDEN_AI_AUTHORITY_KEYS = new Set([
|
|
19
|
+
"command",
|
|
20
|
+
"cmd",
|
|
21
|
+
"shell",
|
|
22
|
+
"approval",
|
|
23
|
+
"approve",
|
|
24
|
+
"retry",
|
|
25
|
+
"cancel",
|
|
26
|
+
"permission",
|
|
27
|
+
]);
|
|
28
|
+
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
29
|
+
const nonEmptyString = (value) => typeof value === "string" && value.trim().length > 0;
|
|
30
|
+
const findForbiddenKeys = (value, forbidden, path = "signal") => {
|
|
31
|
+
if (Array.isArray(value)) {
|
|
32
|
+
return value.flatMap((entry, index) => findForbiddenKeys(entry, forbidden, `${path}[${index}]`));
|
|
33
|
+
}
|
|
34
|
+
if (!isRecord(value))
|
|
35
|
+
return [];
|
|
36
|
+
return Object.entries(value).flatMap(([key, entry]) => [
|
|
37
|
+
...(forbidden.has(key) ? [`${path}.${key} is forbidden`] : []),
|
|
38
|
+
...findForbiddenKeys(entry, forbidden, `${path}.${key}`),
|
|
39
|
+
]);
|
|
40
|
+
};
|
|
41
|
+
const requiredPayloadString = (payload, key, issues) => {
|
|
42
|
+
const value = payload[key];
|
|
43
|
+
if (!nonEmptyString(value)) {
|
|
44
|
+
issues.push(`payload.${key} must be a non-empty string`);
|
|
45
|
+
return "";
|
|
46
|
+
}
|
|
47
|
+
return value;
|
|
48
|
+
};
|
|
49
|
+
const firstEvidence = (evidence, issues) => {
|
|
50
|
+
const value = evidence.find(nonEmptyString);
|
|
51
|
+
if (!value) {
|
|
52
|
+
issues.push("evidence must contain at least one non-empty entry");
|
|
53
|
+
return "";
|
|
54
|
+
}
|
|
55
|
+
return value;
|
|
56
|
+
};
|
|
57
|
+
const buildEvent = (type, source, payload, evidence, issues) => {
|
|
58
|
+
switch (type) {
|
|
59
|
+
case "MODEL_DRAFTED":
|
|
60
|
+
firstEvidence(evidence, issues);
|
|
61
|
+
return { type, source, modelHash: requiredPayloadString(payload, "modelHash", issues) };
|
|
62
|
+
case "MODEL_CONTRACT_VALID":
|
|
63
|
+
return { type, source, evidence: firstEvidence(evidence, issues) };
|
|
64
|
+
case "MODEL_CONTRACT_INVALID":
|
|
65
|
+
return { type, source, reason: requiredPayloadString(payload, "reason", issues) };
|
|
66
|
+
case "MODEL_APPROVED":
|
|
67
|
+
return { type, source, modelHash: requiredPayloadString(payload, "modelHash", issues) };
|
|
68
|
+
case "MODEL_REJECTED":
|
|
69
|
+
return { type, source, reason: requiredPayloadString(payload, "reason", issues) };
|
|
70
|
+
case "START_IMPLEMENTATION":
|
|
71
|
+
return { type, source };
|
|
72
|
+
case "IMPLEMENTATION_READY":
|
|
73
|
+
firstEvidence(evidence, issues);
|
|
74
|
+
return { type, source, implementationHash: requiredPayloadString(payload, "implementationHash", issues) };
|
|
75
|
+
case "IMPLEMENTATION_FAILED":
|
|
76
|
+
return { type, source, reason: requiredPayloadString(payload, "reason", issues) };
|
|
77
|
+
case "ANCHOR_RECORDED": {
|
|
78
|
+
const anchor = payload.anchor;
|
|
79
|
+
if (!isRequiredGraphAnchor(anchor) || anchor === "model-contract") {
|
|
80
|
+
issues.push("payload.anchor must be a permitted implementation anchor");
|
|
81
|
+
}
|
|
82
|
+
const status = payload.status;
|
|
83
|
+
if (status !== "passed" && status !== "failed") {
|
|
84
|
+
issues.push('payload.status must be "passed" or "failed"');
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
type,
|
|
88
|
+
source,
|
|
89
|
+
anchor: isRequiredGraphAnchor(anchor) ? anchor : "graph-tests",
|
|
90
|
+
status: status === "failed" ? "failed" : "passed",
|
|
91
|
+
evidence: firstEvidence(evidence, issues),
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
case "EVALUATE":
|
|
95
|
+
return { type, source };
|
|
96
|
+
case "RETRY_AUTHORIZED":
|
|
97
|
+
return { type, source };
|
|
98
|
+
case "PERMISSION_DENIED":
|
|
99
|
+
return { type, source, reason: requiredPayloadString(payload, "reason", issues) };
|
|
100
|
+
case "CANCEL":
|
|
101
|
+
return { type, source, reason: requiredPayloadString(payload, "reason", issues) };
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
export const validateGraphSignal = (input) => {
|
|
105
|
+
const issues = [];
|
|
106
|
+
if (!isRecord(input))
|
|
107
|
+
return { ok: false, issues: ["signal must be an object"] };
|
|
108
|
+
if (!nonEmptyString(input.runId))
|
|
109
|
+
issues.push("runId must be a non-empty string");
|
|
110
|
+
if (!nonEmptyString(input.producer))
|
|
111
|
+
issues.push("producer must be a non-empty string");
|
|
112
|
+
if (!nonEmptyString(input.occurredAt) || Number.isNaN(Date.parse(input.occurredAt))) {
|
|
113
|
+
issues.push("occurredAt must be a valid ISO timestamp");
|
|
114
|
+
}
|
|
115
|
+
if (!isRecord(input.payload))
|
|
116
|
+
issues.push("payload must be an object");
|
|
117
|
+
if (!Array.isArray(input.evidence) || !input.evidence.every((entry) => typeof entry === "string")) {
|
|
118
|
+
issues.push("evidence must be an array of strings");
|
|
119
|
+
}
|
|
120
|
+
const type = input.type;
|
|
121
|
+
const knownType = typeof type === "string" && type in EVENT_SOURCES ? type : null;
|
|
122
|
+
if (!knownType)
|
|
123
|
+
issues.push("type must be a known graph event");
|
|
124
|
+
const source = input.source;
|
|
125
|
+
const validSource = source === "ai" || source === "tool" || source === "human" || source === "system";
|
|
126
|
+
if (!validSource)
|
|
127
|
+
issues.push("source must be ai, tool, human, or system");
|
|
128
|
+
if (knownType && validSource && EVENT_SOURCES[knownType] !== source) {
|
|
129
|
+
issues.push(`source for ${knownType} must be ${EVENT_SOURCES[knownType]}`);
|
|
130
|
+
}
|
|
131
|
+
issues.push(...findForbiddenKeys(input, FORBIDDEN_TRANSITION_KEYS));
|
|
132
|
+
if (source === "ai")
|
|
133
|
+
issues.push(...findForbiddenKeys(input, FORBIDDEN_AI_AUTHORITY_KEYS));
|
|
134
|
+
const payload = isRecord(input.payload) ? input.payload : {};
|
|
135
|
+
const evidence = Array.isArray(input.evidence)
|
|
136
|
+
? input.evidence.filter((entry) => typeof entry === "string")
|
|
137
|
+
: [];
|
|
138
|
+
const event = knownType && validSource ? buildEvent(knownType, source, payload, evidence, issues) : null;
|
|
139
|
+
if (issues.length > 0 || !event || !knownType)
|
|
140
|
+
return { ok: false, issues };
|
|
141
|
+
return {
|
|
142
|
+
ok: true,
|
|
143
|
+
signal: {
|
|
144
|
+
runId: input.runId,
|
|
145
|
+
type: knownType,
|
|
146
|
+
source: source,
|
|
147
|
+
producer: input.producer,
|
|
148
|
+
occurredAt: input.occurredAt,
|
|
149
|
+
payload,
|
|
150
|
+
evidence,
|
|
151
|
+
},
|
|
152
|
+
event,
|
|
153
|
+
};
|
|
154
|
+
};
|
|
155
|
+
//# sourceMappingURL=signal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signal.js","sourceRoot":"","sources":["../src/signal.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@guyghost/swarm-dao-graph",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Swarm DAO Graph Engineering run executor — journal-replayed change-control runs with strict signal validation",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"sideEffects": false,
|
|
9
|
+
"files": [
|
|
10
|
+
"dist",
|
|
11
|
+
"README.md"
|
|
12
|
+
],
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"import": "./dist/index.js"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsc",
|
|
21
|
+
"test": "bun test",
|
|
22
|
+
"lint": "biome check .",
|
|
23
|
+
"typecheck": "tsc --noEmit",
|
|
24
|
+
"prepublishOnly": "bun run build"
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"@guyghost/swarm-dao-core": "^0.10.2"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@types/bun": "1.3.14",
|
|
31
|
+
"@types/node": "^26.0.1"
|
|
32
|
+
},
|
|
33
|
+
"keywords": [
|
|
34
|
+
"swarm-dao",
|
|
35
|
+
"graph-engineering",
|
|
36
|
+
"change-control",
|
|
37
|
+
"dao",
|
|
38
|
+
"xstate"
|
|
39
|
+
],
|
|
40
|
+
"author": "guyghost",
|
|
41
|
+
"license": "MIT",
|
|
42
|
+
"repository": {
|
|
43
|
+
"type": "git",
|
|
44
|
+
"url": "git+https://github.com/guyghost/swarm-dao.git",
|
|
45
|
+
"directory": "packages/graph-engineering"
|
|
46
|
+
},
|
|
47
|
+
"bugs": {
|
|
48
|
+
"url": "https://github.com/guyghost/swarm-dao/issues"
|
|
49
|
+
},
|
|
50
|
+
"homepage": "https://github.com/guyghost/swarm-dao#readme",
|
|
51
|
+
"publishConfig": {
|
|
52
|
+
"access": "public"
|
|
53
|
+
}
|
|
54
|
+
}
|