sibyl-system 1.3.5 → 1.3.6

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.
Files changed (2) hide show
  1. package/dist/index.js +30 -10
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -31989,6 +31989,8 @@ var LINEAGE_CHUNK = 256;
31989
31989
  var LINEAGE_SAMPLES = 32;
31990
31990
  var LINEAGE_UNION_RATIO = 0.6;
31991
31991
  var LINEAGE_MIN_WINDOWS = 3;
31992
+ var LINEAGE_FLOOR_MIN = 8;
31993
+ var LINEAGE_FLOOR_RATIO = 0.3;
31992
31994
  function sampleWindows(text) {
31993
31995
  const total = Math.floor(text.length / LINEAGE_CHUNK);
31994
31996
  if (total < LINEAGE_MIN_WINDOWS) return [];
@@ -32000,17 +32002,33 @@ function sampleWindows(text) {
32000
32002
  }
32001
32003
  function beginLineage(artifact) {
32002
32004
  if (artifact.kind !== "path" || artifact.mtimeMs === void 0) return null;
32003
- const chunks = sampleWindows(artifact.text);
32005
+ return lineageFrom(artifact.text, artifact.mtimeMs);
32006
+ }
32007
+ function lineageFrom(text, mtimeMs) {
32008
+ const chunks = sampleWindows(text);
32004
32009
  if (chunks.length < LINEAGE_MIN_WINDOWS) return null;
32010
+ const unique = new Set(chunks).size;
32005
32011
  return {
32006
32012
  chunks,
32007
- need: Math.max(2, Math.ceil(chunks.length * LINEAGE_UNION_RATIO)),
32008
- mtimeMs: artifact.mtimeMs,
32013
+ unique,
32014
+ need: Math.max(2, Math.ceil(unique * LINEAGE_UNION_RATIO)),
32015
+ mtimeMs,
32009
32016
  matched: /* @__PURE__ */ new Map(),
32010
32017
  copiedAfterMtime: 0,
32011
32018
  timeless: 0
32012
32019
  };
32013
32020
  }
32021
+ function lineageConvinced(lg) {
32022
+ const n = lg.matched.size;
32023
+ return n >= lg.need || n >= LINEAGE_FLOOR_MIN && n >= Math.ceil(lg.unique * LINEAGE_FLOOR_RATIO);
32024
+ }
32025
+ function creditWindows(lg, cands, label) {
32026
+ for (const cand of cands) {
32027
+ for (const chunk of lg.chunks) {
32028
+ if (!lg.matched.has(chunk) && cand.includes(chunk)) lg.matched.set(chunk, label);
32029
+ }
32030
+ }
32031
+ }
32014
32032
  function messageTime(m) {
32015
32033
  const t = m.info?.time?.created;
32016
32034
  return typeof t === "number" ? t : void 0;
@@ -32028,7 +32046,8 @@ function partCandidates(p) {
32028
32046
  }
32029
32047
  function lineageVerdict(lg, artifact) {
32030
32048
  const sources = [.../* @__PURE__ */ new Set([...lg.matched.values()])].slice(0, 3).join("; ");
32031
- 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`;
32049
+ const majority = lg.matched.size >= lg.need;
32050
+ 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
32051
  }
32033
32052
  function scanMessages(rows, convenerIndex, sid, artifact, lg) {
32034
32053
  for (const [mi, m] of rows.entries()) {
@@ -32055,14 +32074,13 @@ function scanMessages(rows, convenerIndex, sid, artifact, lg) {
32055
32074
  continue;
32056
32075
  }
32057
32076
  const label = `${p.tool ?? "tool"}@${sid}:${String(mi)}`;
32058
- for (const cand of partCandidates(p)) {
32077
+ const cands = partCandidates(p);
32078
+ for (const cand of cands) {
32059
32079
  if (artifact.kind === "path" && cand.includes(artifact.text.trim())) {
32060
32080
  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
32081
  }
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
32082
  }
32083
+ creditWindows(lg, cands, label);
32066
32084
  }
32067
32085
  }
32068
32086
  }
@@ -32117,7 +32135,7 @@ async function assessIndependence(client, directory, convenerSessionID, artifact
32117
32135
  return { status: "NOT-INDEPENDENT", convenerChain: chain, evidence: hit };
32118
32136
  }
32119
32137
  }
32120
- if (lg !== null && lg.matched.size >= lg.need) {
32138
+ if (lg !== null && lineageConvinced(lg)) {
32121
32139
  return { status: "NOT-INDEPENDENT", convenerChain: chain, evidence: lineageVerdict(lg, artifact) };
32122
32140
  }
32123
32141
  if (scanFailed.length > 0 || walkIncomplete) {
@@ -32134,7 +32152,9 @@ async function assessIndependence(client, directory, convenerSessionID, artifact
32134
32152
  }
32135
32153
  function lineageFaceNote(lg) {
32136
32154
  if (lg === null) return "";
32137
- const parts = [`${String(lg.matched.size)}/${String(lg.chunks.length)} lineage windows matched (need ${String(lg.need)})`];
32155
+ const parts = [
32156
+ `${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)}%)`
32157
+ ];
32138
32158
  if (lg.copiedAfterMtime > 0) parts.push(`${String(lg.copiedAfterMtime)} part(s) excluded as post-mtime copies`);
32139
32159
  if (lg.timeless > 0) parts.push(`${String(lg.timeless)} part(s) lacked timestamps`);
32140
32160
  return `; content-lineage: ${parts.join(", ")}`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sibyl-system",
3
- "version": "1.3.5",
3
+ "version": "1.3.6",
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",