sibyl-system 1.3.5 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -2
- package/dist/cli.js +65 -22
- package/dist/index.js +54 -21
- package/package.json +8 -2
package/README.md
CHANGED
|
@@ -186,6 +186,13 @@ Plainly stated:
|
|
|
186
186
|
A kinship hit stamps the run `independence=NOT-INDEPENDENT`: the ballot is
|
|
187
187
|
preserved as data but is not in any effective path. A chain that cannot be
|
|
188
188
|
read stamps `UNVERIFIABLE` — unreadable is never silently clean.
|
|
189
|
+
- **Refused launches leave records (v1.4.0, council 16a2):** an explicit `--run-id`
|
|
190
|
+
whose tool-staged `launch-context.json` is missing or malformed is REFUSED, with a
|
|
191
|
+
`launch-refusal.json` written into the private run dir — a pinned id claiming a
|
|
192
|
+
tool launch that never staged its finding is a provenance lie, not an absence.
|
|
193
|
+
The bare CLI lane (no `--run-id`) keeps the named `UNVERIFIABLE` leg, and once the
|
|
194
|
+
chamber runner regenerates its run record, that face outvouches any contradicted
|
|
195
|
+
staged claim ("record wins").
|
|
189
196
|
- **Absence is a disability (W2).** Before any tally is honored, every declared
|
|
190
197
|
voter/worker must have left a terminal row (`ok|error|timeout` + detail) in
|
|
191
198
|
the run's `TERMINALS.txt`. A declared seat without its row is counted
|
|
@@ -204,7 +211,9 @@ Plainly stated:
|
|
|
204
211
|
- Consult/swarm send the artifact text to your configured model pool providers.
|
|
205
212
|
- The plugin writes under its state paths (the runs file and the per-run space) and,
|
|
206
213
|
for chamber/exam lanes, sealed run directories under `lane.runRoot`
|
|
207
|
-
(default `/tmp`)
|
|
214
|
+
(default `/tmp`), every plugin-created dir `0700` (mkdir mode + explicit chmod:
|
|
215
|
+
unreachable to group/other regardless of umask — v1.4.0 private-dir law) —
|
|
216
|
+
role homes, transcripts, pidfiles, CHECKSUMS.
|
|
208
217
|
- Voter/worker turns run with `bash`, `edit`, and `write` disabled per prompt.
|
|
209
218
|
|
|
210
219
|
## Architecture (`src/`)
|
|
@@ -263,7 +272,7 @@ PLAN→MINT→DISPATCH→AGGREGATE pipeline over ordinary child sessions.
|
|
|
263
272
|
|
|
264
273
|
```bash
|
|
265
274
|
npm run typecheck # tsc --noEmit, strict + noUncheckedIndexedAccess + exactOptionalPropertyTypes
|
|
266
|
-
npm test # full unit suite, fully offline (no network, no LLM;
|
|
275
|
+
npm test # full unit suite, fully offline (no network, no LLM; 459 at v1.4.0 — the run prints the exact count)
|
|
267
276
|
npm run build # esbuild bundle → dist/index.js + dist/cli.js (ESM)
|
|
268
277
|
node smoke/run-smoke.mjs # offline smoke of the shipped surface (see smoke/README.md)
|
|
269
278
|
./ship.sh # the full release gate: all of the above + portability scan of the packed tarball
|
package/dist/cli.js
CHANGED
|
@@ -9,7 +9,16 @@ var __export = (target, all) => {
|
|
|
9
9
|
import { randomBytes } from "node:crypto";
|
|
10
10
|
import { spawn as spawn2 } from "node:child_process";
|
|
11
11
|
import { existsSync as existsSync3 } from "node:fs";
|
|
12
|
-
import { copyFile as copyFile2, mkdir as mkdir6, readFile as readFile6 } from "node:fs/promises";
|
|
12
|
+
import { access, copyFile as copyFile2, mkdir as mkdir6, readFile as readFile6, writeFile as writeFile7 } from "node:fs/promises";
|
|
13
|
+
|
|
14
|
+
// src/fsperm.ts
|
|
15
|
+
import { chmod, mkdir } from "node:fs/promises";
|
|
16
|
+
async function mkdirPrivate(dir) {
|
|
17
|
+
await mkdir(dir, { recursive: true, mode: 448 });
|
|
18
|
+
await chmod(dir, 448);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// src/cli.ts
|
|
13
22
|
import { basename, dirname as dirname4, isAbsolute as isAbsolute2, join as join7, resolve as resolve2 } from "node:path";
|
|
14
23
|
|
|
15
24
|
// src/state/record.ts
|
|
@@ -73,7 +82,7 @@ var COUNCIL_SIZE = COUNCILORS.length;
|
|
|
73
82
|
var KNOWN_IDS = new Set(COUNCILORS);
|
|
74
83
|
|
|
75
84
|
// src/chamber/protocol.ts
|
|
76
|
-
import { mkdir as
|
|
85
|
+
import { mkdir as mkdir3, readFile as readFile2, writeFile as writeFile2 } from "node:fs/promises";
|
|
77
86
|
import { join as join2 } from "node:path";
|
|
78
87
|
|
|
79
88
|
// src/lane/seating.ts
|
|
@@ -185,7 +194,7 @@ var FAIL_CLOSED_REJECT = rejectVerdict("no-parse-performed");
|
|
|
185
194
|
|
|
186
195
|
// src/state/chamber.ts
|
|
187
196
|
import { createHash as createHash2 } from "node:crypto";
|
|
188
|
-
import { mkdir, readFile, readdir, rename, unlink, writeFile } from "node:fs/promises";
|
|
197
|
+
import { mkdir as mkdir2, readFile, readdir, rename, unlink, writeFile } from "node:fs/promises";
|
|
189
198
|
import { homedir } from "node:os";
|
|
190
199
|
import { dirname, isAbsolute, join, resolve } from "node:path";
|
|
191
200
|
var DEFAULT_CHAMBER_LEDGER = join(homedir(), ".sibyl", "chamber-ledger.jsonl");
|
|
@@ -293,7 +302,7 @@ async function appendLedgerRow(ledgerPath, record2) {
|
|
|
293
302
|
const stamped = { ...record2, serial };
|
|
294
303
|
const line = JSON.stringify(stamped);
|
|
295
304
|
if (line.includes("\n")) return { ok: false, reason: "row serializes with a newline \u2014 refused (ledger is one-JSON-per-line)" };
|
|
296
|
-
await
|
|
305
|
+
await mkdir2(dirname(ledgerPath), { recursive: true });
|
|
297
306
|
await writeFile(ledgerPath, `${line}
|
|
298
307
|
`, { flag: "a" });
|
|
299
308
|
return { ok: true, serial, line };
|
|
@@ -334,7 +343,7 @@ var RECORD_FILE = "run-record.json";
|
|
|
334
343
|
var CHECKSUMS_FILE = "CHECKSUMS.txt";
|
|
335
344
|
var LEDGER_LINE_FILE = "ledger-line.txt";
|
|
336
345
|
async function atomicWrite(path, content) {
|
|
337
|
-
await
|
|
346
|
+
await mkdir2(dirname(path), { recursive: true });
|
|
338
347
|
const tmp = `${path}.${String(process.pid)}.tmp`;
|
|
339
348
|
try {
|
|
340
349
|
await writeFile(tmp, content, "utf8");
|
|
@@ -636,9 +645,9 @@ var Protocol = class {
|
|
|
636
645
|
}
|
|
637
646
|
};
|
|
638
647
|
async function runChamber(cfg, onRecord) {
|
|
639
|
-
await
|
|
640
|
-
await
|
|
641
|
-
for (const role of CHAMBER_ROLES) await
|
|
648
|
+
await mkdir3(join2(cfg.runDir, "pids"), { recursive: true });
|
|
649
|
+
await mkdir3(join2(cfg.runDir, "evidence"), { recursive: true });
|
|
650
|
+
for (const role of CHAMBER_ROLES) await mkdir3(join2(cfg.runDir, role), { recursive: true });
|
|
642
651
|
const roster = CHAMBER_ROLES.map((role) => {
|
|
643
652
|
const d = resolveSeat(role, cfg.slots[role], cfg.pool, cfg.policy);
|
|
644
653
|
return d.ok ? { role, slot: d.slot, modelId: d.modelId, policyCheck: "allow" } : { role, slot: cfg.slots[role], modelId: "", policyCheck: "deny", denyReason: d.deny };
|
|
@@ -852,7 +861,7 @@ function renderVoice(voice) {
|
|
|
852
861
|
// src/lane/isolated.ts
|
|
853
862
|
import { spawn } from "node:child_process";
|
|
854
863
|
import { createWriteStream, existsSync } from "node:fs";
|
|
855
|
-
import { copyFile,
|
|
864
|
+
import { copyFile, readFile as readFile3, writeFile as writeFile3 } from "node:fs/promises";
|
|
856
865
|
import { dirname as dirname2, join as join3 } from "node:path";
|
|
857
866
|
var DEFAULT_PINNED_PATH = "/usr/bin:/bin";
|
|
858
867
|
function composeSandboxArgs(opts) {
|
|
@@ -882,12 +891,12 @@ function rolePaths(cfg, role) {
|
|
|
882
891
|
}
|
|
883
892
|
async function prepareRoleHome(cfg, role) {
|
|
884
893
|
const paths = rolePaths(cfg, role);
|
|
885
|
-
await
|
|
886
|
-
await
|
|
887
|
-
await
|
|
888
|
-
await
|
|
889
|
-
await
|
|
890
|
-
await
|
|
894
|
+
await mkdirPrivate(join3(paths.home, ".config", "opencode"));
|
|
895
|
+
await mkdirPrivate(dirname2(paths.dbPath));
|
|
896
|
+
await mkdirPrivate(join3(paths.home, ".cache", "opencode"));
|
|
897
|
+
await mkdirPrivate(join3(paths.home, ".local", "state", "opencode"));
|
|
898
|
+
await mkdirPrivate(paths.workspace);
|
|
899
|
+
await mkdirPrivate(join3(cfg.runDir, "pids"));
|
|
891
900
|
try {
|
|
892
901
|
if (cfg.configSource.length > 0) {
|
|
893
902
|
await copyFile(cfg.configSource, join3(paths.home, ".config", "opencode", "opencode.jsonc"));
|
|
@@ -20381,17 +20390,51 @@ async function resolveRun(flags) {
|
|
|
20381
20390
|
return { ok: false, error: `--run-id must be a bare sibyl run id, got "${flagRunId}"` };
|
|
20382
20391
|
}
|
|
20383
20392
|
const runId = flagRunId ?? `sibyl-${compactIso(now)}-${randomBytes(2).toString("hex")}`;
|
|
20393
|
+
if (targetRaw !== "-") {
|
|
20394
|
+
const abs = isAbsolute2(targetRaw) ? targetRaw : resolve2(process.cwd(), targetRaw);
|
|
20395
|
+
try {
|
|
20396
|
+
await access(abs);
|
|
20397
|
+
} catch (e) {
|
|
20398
|
+
return { ok: false, error: `--target unreadable: ${e instanceof Error ? e.message : String(e)}` };
|
|
20399
|
+
}
|
|
20400
|
+
}
|
|
20384
20401
|
const runDir = join7(laneCfg.runRoot, `sibyl-run-${runId}`);
|
|
20385
|
-
await
|
|
20386
|
-
let
|
|
20402
|
+
await mkdirPrivate(runDir);
|
|
20403
|
+
let contextLeg = null;
|
|
20404
|
+
let contextProblem = null;
|
|
20387
20405
|
try {
|
|
20388
20406
|
const lc = JSON.parse(await readFile6(join7(runDir, "launch-context.json"), "utf8"));
|
|
20389
|
-
|
|
20390
|
-
|
|
20391
|
-
|
|
20392
|
-
|
|
20407
|
+
if (isIndependenceShape(lc["independence"])) contextLeg = lc;
|
|
20408
|
+
else contextProblem = "launch-context staged but its independence leg is malformed";
|
|
20409
|
+
} catch (err) {
|
|
20410
|
+
contextProblem = err instanceof Error && err.name === "SyntaxError" ? "launch-context exists but is not valid JSON" : "no launch-context staged in the run dir";
|
|
20411
|
+
}
|
|
20412
|
+
if (flagRunId !== null && contextProblem !== null) {
|
|
20413
|
+
const refusal = {
|
|
20414
|
+
kind: "refused-launch",
|
|
20415
|
+
runId: flagRunId,
|
|
20416
|
+
reason: `${contextProblem} \u2014 a --run-id launch claims a tool-staged review that never happened; rerun through the sibyl_review tool, or drop --run-id for the supported bare headless launch`,
|
|
20417
|
+
at: now.toISOString()
|
|
20393
20418
|
};
|
|
20394
|
-
|
|
20419
|
+
await writeFile7(join7(runDir, "launch-refusal.json"), `${JSON.stringify(refusal, null, 2)}
|
|
20420
|
+
`, "utf8");
|
|
20421
|
+
return { ok: false, error: refusal.reason };
|
|
20422
|
+
}
|
|
20423
|
+
let launchIndependence;
|
|
20424
|
+
if (contextLeg !== null) {
|
|
20425
|
+
launchIndependence = contextLeg["independence"];
|
|
20426
|
+
try {
|
|
20427
|
+
const face = JSON.parse(await readFile6(join7(runDir, "run-record.json"), "utf8"));
|
|
20428
|
+
const faceInd = face["independence"];
|
|
20429
|
+
if (isIndependenceShape(faceInd) && faceInd.status !== launchIndependence.status) {
|
|
20430
|
+
launchIndependence = {
|
|
20431
|
+
...faceInd,
|
|
20432
|
+
evidence: `context claimed ${launchIndependence.status}, run record carries ${faceInd.status} \u2014 record wins. ${faceInd.evidence}`
|
|
20433
|
+
};
|
|
20434
|
+
}
|
|
20435
|
+
} catch {
|
|
20436
|
+
}
|
|
20437
|
+
} else {
|
|
20395
20438
|
launchIndependence = {
|
|
20396
20439
|
status: "UNVERIFIABLE",
|
|
20397
20440
|
convenerChain: [],
|
package/dist/index.js
CHANGED
|
@@ -18981,7 +18981,16 @@ function parseOptions(raw) {
|
|
|
18981
18981
|
|
|
18982
18982
|
// src/state/index.ts
|
|
18983
18983
|
import { randomBytes } from "node:crypto";
|
|
18984
|
-
import {
|
|
18984
|
+
import { readFile, rename, unlink, writeFile } from "node:fs/promises";
|
|
18985
|
+
|
|
18986
|
+
// src/fsperm.ts
|
|
18987
|
+
import { chmod, mkdir } from "node:fs/promises";
|
|
18988
|
+
async function mkdirPrivate(dir) {
|
|
18989
|
+
await mkdir(dir, { recursive: true, mode: 448 });
|
|
18990
|
+
await chmod(dir, 448);
|
|
18991
|
+
}
|
|
18992
|
+
|
|
18993
|
+
// src/state/index.ts
|
|
18985
18994
|
import { homedir as homedir2 } from "node:os";
|
|
18986
18995
|
import { dirname, join as join2 } from "node:path";
|
|
18987
18996
|
|
|
@@ -19176,7 +19185,7 @@ var RunStore = class {
|
|
|
19176
19185
|
* which briefly widens the crash window but never writes torn JSON. */
|
|
19177
19186
|
async save(records, opts) {
|
|
19178
19187
|
const dir = dirname(this.runsFile);
|
|
19179
|
-
await
|
|
19188
|
+
await mkdirPrivate(dir);
|
|
19180
19189
|
const tmp = join2(dir, `runs.${process.pid}.${randomBytes(4).toString("hex")}.tmp`);
|
|
19181
19190
|
const renameStep = opts?.rename ?? this.renameFile;
|
|
19182
19191
|
try {
|
|
@@ -19219,7 +19228,7 @@ var RunStore = class {
|
|
|
19219
19228
|
const now = /* @__PURE__ */ new Date();
|
|
19220
19229
|
const runId = `sibyl-${compactIso(now)}-${randomBytes(2).toString("hex")}`;
|
|
19221
19230
|
const spaceDir = join2(input2.spaceRootDir ?? this.spaceRoot, runId);
|
|
19222
|
-
await
|
|
19231
|
+
await mkdirPrivate(spaceDir);
|
|
19223
19232
|
const record3 = {
|
|
19224
19233
|
runId,
|
|
19225
19234
|
kind: input2.kind,
|
|
@@ -31989,6 +31998,8 @@ var LINEAGE_CHUNK = 256;
|
|
|
31989
31998
|
var LINEAGE_SAMPLES = 32;
|
|
31990
31999
|
var LINEAGE_UNION_RATIO = 0.6;
|
|
31991
32000
|
var LINEAGE_MIN_WINDOWS = 3;
|
|
32001
|
+
var LINEAGE_FLOOR_MIN = 8;
|
|
32002
|
+
var LINEAGE_FLOOR_RATIO = 0.3;
|
|
31992
32003
|
function sampleWindows(text) {
|
|
31993
32004
|
const total = Math.floor(text.length / LINEAGE_CHUNK);
|
|
31994
32005
|
if (total < LINEAGE_MIN_WINDOWS) return [];
|
|
@@ -32000,17 +32011,33 @@ function sampleWindows(text) {
|
|
|
32000
32011
|
}
|
|
32001
32012
|
function beginLineage(artifact) {
|
|
32002
32013
|
if (artifact.kind !== "path" || artifact.mtimeMs === void 0) return null;
|
|
32003
|
-
|
|
32014
|
+
return lineageFrom(artifact.text, artifact.mtimeMs);
|
|
32015
|
+
}
|
|
32016
|
+
function lineageFrom(text, mtimeMs) {
|
|
32017
|
+
const chunks = sampleWindows(text);
|
|
32004
32018
|
if (chunks.length < LINEAGE_MIN_WINDOWS) return null;
|
|
32019
|
+
const unique = new Set(chunks).size;
|
|
32005
32020
|
return {
|
|
32006
32021
|
chunks,
|
|
32007
|
-
|
|
32008
|
-
|
|
32022
|
+
unique,
|
|
32023
|
+
need: Math.max(2, Math.ceil(unique * LINEAGE_UNION_RATIO)),
|
|
32024
|
+
mtimeMs,
|
|
32009
32025
|
matched: /* @__PURE__ */ new Map(),
|
|
32010
32026
|
copiedAfterMtime: 0,
|
|
32011
32027
|
timeless: 0
|
|
32012
32028
|
};
|
|
32013
32029
|
}
|
|
32030
|
+
function lineageConvinced(lg) {
|
|
32031
|
+
const n = lg.matched.size;
|
|
32032
|
+
return n >= lg.need || n >= LINEAGE_FLOOR_MIN && n >= Math.ceil(lg.unique * LINEAGE_FLOOR_RATIO);
|
|
32033
|
+
}
|
|
32034
|
+
function creditWindows(lg, cands, label) {
|
|
32035
|
+
for (const cand of cands) {
|
|
32036
|
+
for (const chunk of lg.chunks) {
|
|
32037
|
+
if (!lg.matched.has(chunk) && cand.includes(chunk)) lg.matched.set(chunk, label);
|
|
32038
|
+
}
|
|
32039
|
+
}
|
|
32040
|
+
}
|
|
32014
32041
|
function messageTime(m) {
|
|
32015
32042
|
const t = m.info?.time?.created;
|
|
32016
32043
|
return typeof t === "number" ? t : void 0;
|
|
@@ -32028,7 +32055,8 @@ function partCandidates(p) {
|
|
|
32028
32055
|
}
|
|
32029
32056
|
function lineageVerdict(lg, artifact) {
|
|
32030
32057
|
const sources = [.../* @__PURE__ */ new Set([...lg.matched.values()])].slice(0, 3).join("; ");
|
|
32031
|
-
|
|
32058
|
+
const majority = lg.matched.size >= lg.need;
|
|
32059
|
+
return `content-lineage evidence: ${String(lg.matched.size)} of ${String(lg.unique)} DISTINCT verbatim ${String(LINEAGE_CHUNK)}-byte windows of ${artifact.source} appear in convener-chain tool inputs that predate its mtime (${sources}) \u2014 ${majority ? "majority" : "absolute floor"} of drafting; repeated identical windows counted once`;
|
|
32032
32060
|
}
|
|
32033
32061
|
function scanMessages(rows, convenerIndex, sid, artifact, lg) {
|
|
32034
32062
|
for (const [mi, m] of rows.entries()) {
|
|
@@ -32055,14 +32083,13 @@ function scanMessages(rows, convenerIndex, sid, artifact, lg) {
|
|
|
32055
32083
|
continue;
|
|
32056
32084
|
}
|
|
32057
32085
|
const label = `${p.tool ?? "tool"}@${sid}:${String(mi)}`;
|
|
32058
|
-
|
|
32086
|
+
const cands = partCandidates(p);
|
|
32087
|
+
for (const cand of cands) {
|
|
32059
32088
|
if (artifact.kind === "path" && cand.includes(artifact.text.trim())) {
|
|
32060
32089
|
return `content-lineage evidence: the FULL text of ${artifact.source} appears verbatim in ${label} (convener-chain tool input, before the file's mtime) \u2014 the chain wrote these bytes elsewhere and moved them here; the chain cannot sit on both sides of this ballot`;
|
|
32061
32090
|
}
|
|
32062
|
-
for (const [wi, chunk] of lg.chunks.entries()) {
|
|
32063
|
-
if (!lg.matched.has(wi) && cand.includes(chunk)) lg.matched.set(wi, label);
|
|
32064
|
-
}
|
|
32065
32091
|
}
|
|
32092
|
+
creditWindows(lg, cands, label);
|
|
32066
32093
|
}
|
|
32067
32094
|
}
|
|
32068
32095
|
}
|
|
@@ -32117,7 +32144,7 @@ async function assessIndependence(client, directory, convenerSessionID, artifact
|
|
|
32117
32144
|
return { status: "NOT-INDEPENDENT", convenerChain: chain, evidence: hit };
|
|
32118
32145
|
}
|
|
32119
32146
|
}
|
|
32120
|
-
if (lg !== null && lg
|
|
32147
|
+
if (lg !== null && lineageConvinced(lg)) {
|
|
32121
32148
|
return { status: "NOT-INDEPENDENT", convenerChain: chain, evidence: lineageVerdict(lg, artifact) };
|
|
32122
32149
|
}
|
|
32123
32150
|
if (scanFailed.length > 0 || walkIncomplete) {
|
|
@@ -32134,7 +32161,9 @@ async function assessIndependence(client, directory, convenerSessionID, artifact
|
|
|
32134
32161
|
}
|
|
32135
32162
|
function lineageFaceNote(lg) {
|
|
32136
32163
|
if (lg === null) return "";
|
|
32137
|
-
const parts = [
|
|
32164
|
+
const parts = [
|
|
32165
|
+
`${String(lg.matched.size)}/${String(lg.unique)} distinct lineage windows matched (majority need ${String(lg.need)}, floor ${String(LINEAGE_FLOOR_MIN)}@${String(LINEAGE_FLOOR_RATIO * 100)}%)`
|
|
32166
|
+
];
|
|
32138
32167
|
if (lg.copiedAfterMtime > 0) parts.push(`${String(lg.copiedAfterMtime)} part(s) excluded as post-mtime copies`);
|
|
32139
32168
|
if (lg.timeless > 0) parts.push(`${String(lg.timeless)} part(s) lacked timestamps`);
|
|
32140
32169
|
return `; content-lineage: ${parts.join(", ")}`;
|
|
@@ -32850,7 +32879,7 @@ function ballotTag(vote) {
|
|
|
32850
32879
|
import { spawn } from "node:child_process";
|
|
32851
32880
|
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
32852
32881
|
import { existsSync as existsSync2 } from "node:fs";
|
|
32853
|
-
import {
|
|
32882
|
+
import { writeFile as writeFile4 } from "node:fs/promises";
|
|
32854
32883
|
import { dirname as dirname3, join as join6 } from "node:path";
|
|
32855
32884
|
import { fileURLToPath } from "node:url";
|
|
32856
32885
|
var REVIEW_TOOL_NAME = "sibyl_review";
|
|
@@ -32859,12 +32888,16 @@ function nodeBinary() {
|
|
|
32859
32888
|
}
|
|
32860
32889
|
function cliCommand(thisUrl, node2) {
|
|
32861
32890
|
const moduleDir = dirname3(fileURLToPath(thisUrl));
|
|
32862
|
-
const
|
|
32863
|
-
const
|
|
32864
|
-
|
|
32865
|
-
|
|
32866
|
-
|
|
32867
|
-
|
|
32891
|
+
const roots = [dirname3(moduleDir), dirname3(dirname3(moduleDir))];
|
|
32892
|
+
for (const root of roots) {
|
|
32893
|
+
const distCli = join6(root, "dist", "cli.js");
|
|
32894
|
+
if (existsSync2(distCli)) return { bin: node2, args: [distCli] };
|
|
32895
|
+
const srcCli = join6(root, "src", "cli.ts");
|
|
32896
|
+
const hooks = join6(root, "tools", "register-ts.mjs");
|
|
32897
|
+
if (existsSync2(srcCli) && existsSync2(hooks)) return { bin: node2, args: ["--import", hooks, srcCli] };
|
|
32898
|
+
}
|
|
32899
|
+
const repoRoot = roots[1] ?? dirname3(dirname3(moduleDir));
|
|
32900
|
+
return { bin: node2, args: ["--import", join6(repoRoot, "tools", "register-ts.mjs"), join6(repoRoot, "src", "cli.ts")] };
|
|
32868
32901
|
}
|
|
32869
32902
|
async function reviewExecute(deps, args, context) {
|
|
32870
32903
|
try {
|
|
@@ -32873,7 +32906,7 @@ async function reviewExecute(deps, args, context) {
|
|
|
32873
32906
|
const now = /* @__PURE__ */ new Date();
|
|
32874
32907
|
const runId = `sibyl-${compactIso(now)}-${randomBytes2(2).toString("hex")}`;
|
|
32875
32908
|
const runDir = join6(opts.lane.runRoot, `sibyl-run-${runId}`);
|
|
32876
|
-
await
|
|
32909
|
+
await mkdirPrivate(runDir);
|
|
32877
32910
|
const artifact = await readArtifact(args.target, context.directory);
|
|
32878
32911
|
if (!artifact.ok) return `SIBYL review: ${artifact.error}`;
|
|
32879
32912
|
let targetArg;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sibyl-system",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Sibyl-System: democratic-centralism review chamber (one conclusion, one voice) + fail-closed council voting + dynamic swarm plugin for OpenCode",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"prepack": "npm run build"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@opencode-ai/plugin": "1.
|
|
38
|
+
"@opencode-ai/plugin": "1.19.4",
|
|
39
39
|
"zod": "^4"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
@@ -45,5 +45,11 @@
|
|
|
45
45
|
},
|
|
46
46
|
"bin": {
|
|
47
47
|
"sibyl-chamber": "./dist/cli.js"
|
|
48
|
+
},
|
|
49
|
+
"overrides": {
|
|
50
|
+
"toml": "5.0.1"
|
|
51
|
+
},
|
|
52
|
+
"engines": {
|
|
53
|
+
"node": ">=22"
|
|
48
54
|
}
|
|
49
55
|
}
|