sibyl-system 1.3.1 → 1.3.2
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/index.js +87 -5
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -31971,7 +31971,53 @@ function contentMatches(input2, needle) {
|
|
|
31971
31971
|
}
|
|
31972
31972
|
return false;
|
|
31973
31973
|
}
|
|
31974
|
-
|
|
31974
|
+
var SHELL_TOOLS = ["bash"];
|
|
31975
|
+
var SHELL_KEYS = ["command"];
|
|
31976
|
+
var LINEAGE_CHUNK = 256;
|
|
31977
|
+
var LINEAGE_SAMPLES = 32;
|
|
31978
|
+
var LINEAGE_UNION_RATIO = 0.6;
|
|
31979
|
+
var LINEAGE_MIN_WINDOWS = 3;
|
|
31980
|
+
function sampleWindows(text) {
|
|
31981
|
+
const total = Math.floor(text.length / LINEAGE_CHUNK);
|
|
31982
|
+
if (total < LINEAGE_MIN_WINDOWS) return [];
|
|
31983
|
+
const step = Math.max(1, Math.floor(total / LINEAGE_SAMPLES));
|
|
31984
|
+
const out = [];
|
|
31985
|
+
for (let i = 0; i < total; i += step) out.push(text.slice(i * LINEAGE_CHUNK, (i + 1) * LINEAGE_CHUNK));
|
|
31986
|
+
return out.slice(0, LINEAGE_SAMPLES);
|
|
31987
|
+
}
|
|
31988
|
+
function beginLineage(artifact) {
|
|
31989
|
+
if (artifact.kind !== "path" || artifact.mtimeMs === void 0) return null;
|
|
31990
|
+
const chunks = sampleWindows(artifact.text);
|
|
31991
|
+
if (chunks.length < LINEAGE_MIN_WINDOWS) return null;
|
|
31992
|
+
return {
|
|
31993
|
+
chunks,
|
|
31994
|
+
need: Math.max(2, Math.ceil(chunks.length * LINEAGE_UNION_RATIO)),
|
|
31995
|
+
mtimeMs: artifact.mtimeMs,
|
|
31996
|
+
matched: /* @__PURE__ */ new Map(),
|
|
31997
|
+
copiedAfterMtime: 0,
|
|
31998
|
+
timeless: 0
|
|
31999
|
+
};
|
|
32000
|
+
}
|
|
32001
|
+
function messageTime(m) {
|
|
32002
|
+
const t = m.info?.time?.created;
|
|
32003
|
+
return typeof t === "number" ? t : void 0;
|
|
32004
|
+
}
|
|
32005
|
+
function partCandidates(p) {
|
|
32006
|
+
const shell = p.tool !== void 0 && SHELL_TOOLS.includes(p.tool);
|
|
32007
|
+
if (!shell && !isDraftingTool(p.tool)) return [];
|
|
32008
|
+
const keys = shell ? SHELL_KEYS : CONTENT_KEYS;
|
|
32009
|
+
const out = [];
|
|
32010
|
+
for (const key of keys) {
|
|
32011
|
+
const v = p.input?.[key];
|
|
32012
|
+
if (typeof v === "string" && v.length >= LINEAGE_CHUNK) out.push(v);
|
|
32013
|
+
}
|
|
32014
|
+
return out;
|
|
32015
|
+
}
|
|
32016
|
+
function lineageVerdict(lg, artifact) {
|
|
32017
|
+
const sources = [.../* @__PURE__ */ new Set([...lg.matched.values()])].slice(0, 3).join("; ");
|
|
32018
|
+
return `content-lineage evidence: ${String(lg.matched.size)} of ${String(lg.chunks.length)} verbatim ${String(LINEAGE_CHUNK)}-byte windows of ${artifact.source} appear in convener-chain tool inputs that predate its mtime (${sources}) \u2014 the chain authored this artifact's bytes before/independently of this path`;
|
|
32019
|
+
}
|
|
32020
|
+
function scanMessages(rows, convenerIndex, sid, artifact, lg) {
|
|
31975
32021
|
for (const [mi, m] of rows.entries()) {
|
|
31976
32022
|
for (const p of m.parts ?? []) {
|
|
31977
32023
|
if (p.type === "tool" && isDraftingTool(p.tool)) {
|
|
@@ -31985,6 +32031,26 @@ function scanMessages(rows, convenerIndex, sid, artifact) {
|
|
|
31985
32031
|
if (artifact.kind === "inline" && m.info?.role === "assistant" && p.type === "text" && typeof p.text === "string" && artifact.text.trim().length >= MIN_INLINE_MATCH && p.text.includes(artifact.text.trim())) {
|
|
31986
32032
|
return `drafting evidence: assistant text in convener-chain session ${sid} (chain position ${String(convenerIndex)}, message ${String(mi)}) contains the inline artifact`;
|
|
31987
32033
|
}
|
|
32034
|
+
if (p.type === "tool" && lg !== null) {
|
|
32035
|
+
const t = messageTime(m);
|
|
32036
|
+
if (t === void 0) {
|
|
32037
|
+
lg.timeless += 1;
|
|
32038
|
+
continue;
|
|
32039
|
+
}
|
|
32040
|
+
if (t > lg.mtimeMs) {
|
|
32041
|
+
lg.copiedAfterMtime += 1;
|
|
32042
|
+
continue;
|
|
32043
|
+
}
|
|
32044
|
+
const label = `${p.tool ?? "tool"}@${sid}:${String(mi)}`;
|
|
32045
|
+
for (const cand of partCandidates(p)) {
|
|
32046
|
+
if (artifact.kind === "path" && cand.includes(artifact.text.trim())) {
|
|
32047
|
+
return `${lineageVerdict({ ...lg, matched: /* @__PURE__ */ new Map([[0, label]]) }, artifact)}; full-text containment in ${label}`;
|
|
32048
|
+
}
|
|
32049
|
+
for (const [wi, chunk] of lg.chunks.entries()) {
|
|
32050
|
+
if (!lg.matched.has(wi) && cand.includes(chunk)) lg.matched.set(wi, label);
|
|
32051
|
+
}
|
|
32052
|
+
}
|
|
32053
|
+
}
|
|
31988
32054
|
}
|
|
31989
32055
|
}
|
|
31990
32056
|
return null;
|
|
@@ -32025,6 +32091,7 @@ async function assessIndependence(client, directory, convenerSessionID, artifact
|
|
|
32025
32091
|
seen.add(parent);
|
|
32026
32092
|
current = parent;
|
|
32027
32093
|
}
|
|
32094
|
+
const lg = beginLineage(artifact);
|
|
32028
32095
|
let scanFailed = "";
|
|
32029
32096
|
for (const [i, sid] of chain.entries()) {
|
|
32030
32097
|
const res = await client.session.messages({ path: { id: sid }, query: { directory } });
|
|
@@ -32032,22 +32099,33 @@ async function assessIndependence(client, directory, convenerSessionID, artifact
|
|
|
32032
32099
|
scanFailed = scanFailed.length > 0 ? scanFailed : `messages(${sid}) refused`;
|
|
32033
32100
|
continue;
|
|
32034
32101
|
}
|
|
32035
|
-
const hit = scanMessages(res.data, i, sid, artifact);
|
|
32102
|
+
const hit = scanMessages(res.data, i, sid, artifact, lg);
|
|
32036
32103
|
if (hit !== null) {
|
|
32037
32104
|
return { status: "NOT-INDEPENDENT", convenerChain: chain, evidence: hit };
|
|
32038
32105
|
}
|
|
32039
32106
|
}
|
|
32107
|
+
if (lg !== null && lg.matched.size >= lg.need) {
|
|
32108
|
+
return { status: "NOT-INDEPENDENT", convenerChain: chain, evidence: lineageVerdict(lg, artifact) };
|
|
32109
|
+
}
|
|
32040
32110
|
if (scanFailed.length > 0 || walkIncomplete) {
|
|
32041
32111
|
const why = [walkIncomplete ? walkReason : "", scanFailed].filter((s) => s.length > 0).join("; ");
|
|
32042
32112
|
return { status: "UNVERIFIABLE", convenerChain: chain, evidence: `partial read: ${why} \u2014 independence was NOT established` };
|
|
32043
32113
|
}
|
|
32044
32114
|
const note = walkReason.length > 0 ? `; walk note: ${walkReason}` : "";
|
|
32115
|
+
const lineageNote = lineageFaceNote(lg);
|
|
32045
32116
|
return {
|
|
32046
32117
|
status: "INDEPENDENT",
|
|
32047
32118
|
convenerChain: chain,
|
|
32048
|
-
evidence: `scanned ${String(chain.length)} session(s) of the convener chain to root; no drafting evidence within read scope${note}`
|
|
32119
|
+
evidence: `scanned ${String(chain.length)} session(s) of the convener chain to root; no drafting evidence within read scope${lineageNote}${note}`
|
|
32049
32120
|
};
|
|
32050
32121
|
}
|
|
32122
|
+
function lineageFaceNote(lg) {
|
|
32123
|
+
if (lg === null) return "";
|
|
32124
|
+
const parts = [`${String(lg.matched.size)}/${String(lg.chunks.length)} lineage windows matched (need ${String(lg.need)})`];
|
|
32125
|
+
if (lg.copiedAfterMtime > 0) parts.push(`${String(lg.copiedAfterMtime)} part(s) excluded as post-mtime copies`);
|
|
32126
|
+
if (lg.timeless > 0) parts.push(`${String(lg.timeless)} part(s) lacked timestamps`);
|
|
32127
|
+
return `; content-lineage: ${parts.join(", ")}`;
|
|
32128
|
+
}
|
|
32051
32129
|
function independenceLabel(v) {
|
|
32052
32130
|
return v.status === "INDEPENDENT" ? "independence=INDEPENDENT" : `independence=${v.status} \u2014 ${v.evidence}`;
|
|
32053
32131
|
}
|
|
@@ -32526,7 +32604,7 @@ async function readArtifact(raw, cwd) {
|
|
|
32526
32604
|
} catch (err) {
|
|
32527
32605
|
return { ok: false, error: `artifact "${path}": ${errMessage(err)}` };
|
|
32528
32606
|
}
|
|
32529
|
-
return { ok: true, kind: "path", source: path, text };
|
|
32607
|
+
return { ok: true, kind: "path", source: path, text, mtimeMs: info.mtimeMs };
|
|
32530
32608
|
}
|
|
32531
32609
|
function errMessage(err) {
|
|
32532
32610
|
if (err instanceof Error) return err.message;
|
|
@@ -33858,7 +33936,11 @@ function toEngineClient(sdk) {
|
|
|
33858
33936
|
...m.info.providerID !== void 0 && { providerID: m.info.providerID },
|
|
33859
33937
|
...m.info.modelID !== void 0 && { modelID: m.info.modelID },
|
|
33860
33938
|
...m.info.time !== void 0 && {
|
|
33861
|
-
time: {
|
|
33939
|
+
time: {
|
|
33940
|
+
...m.info.time.completed !== void 0 && { completed: m.info.time.completed },
|
|
33941
|
+
// W1-v2 lineage time gate needs creation stamps too
|
|
33942
|
+
..."created" in m.info.time && m.info.time.created !== void 0 && { created: m.info.time.created }
|
|
33943
|
+
}
|
|
33862
33944
|
},
|
|
33863
33945
|
...m.info.error !== void 0 && { error: m.info.error }
|
|
33864
33946
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sibyl-system",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.2",
|
|
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",
|