sibyl-system 1.3.6 → 1.5.1

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 (4) hide show
  1. package/README.md +26 -6
  2. package/dist/cli.js +1689 -786
  3. package/dist/index.js +3967 -15331
  4. package/package.json +13 -3
package/README.md CHANGED
@@ -104,8 +104,8 @@ stderr, registers nothing, and returns empty hooks.
104
104
  | `sibyl_status` | `{ runId? }` | Read-only. Lists all recorded runs (newest last) + the last chamber-ledger rows, or shows one run's full record and space dir. |
105
105
  | `sibyl_review` | `{ target, goal, seed?, maxRounds? }` | v1.1 general democratic-centralism chamber: launches the isolated evidence→clash→judge pipeline detached and returns a receipt (explicitly NOT a verdict); the single voice lands in the run record at terminal state. CLI twin: `sibyl-chamber`. |
106
106
  | `sibyl_anchor_check` | `{ sessionId, index?, body?, expectSha256?, label? }` | Read-only verifier for "human anchor" claims (an order/approval message the owner says they sent): re-checks the claim against the engine's own session store instead of trusting a transcribed string. Closed 4-state verdict `MATCH` / `MISMATCH` / `ABSENT` / `ERROR`; the receipt carries a hash of the canonical view read, so later store mutation shows up as a view-hash difference. No `expectSha256` claim → non-verdict. |
107
- | `sibyl_time_probe` | `{ endpoints?, toleranceMs? }` | Clock-integrity check against independent HTTP `Date` headers (default pool: cloudflare / google / mozilla; sources with the same owner dept collapse to ONE source). Verdict: `SYNCED` / `DRIFT` / `INSUFFICIENT-SOURCES` (< 2 distinct owners is never consent). Default tolerance 300000 ms. Reads remote endpoints; sends no data beyond a HEAD request. |
108
- | `sibyl_attribute` | `{ moves, commits, roster }` | Pure comparator (zero network/git of its own): attributes git ref-moves to committer identities against a roster. Per-move verdict: `ATTRIBUTED` / `UNATTRIBUTED` (the silent-egress case) / `AMBIGUOUS` (byte-equal roster pair = registry defect, blocks, never picks). Identity matching is byte-exact by design — no normalization. |
107
+ | `sibyl_time_probe` | `{ endpoints?, toleranceMs? }` | Clock-integrity check against independent HTTP `Date` headers (default pool: cloudflare / google / mozilla; sources with the same owner dept collapse to ONE source). Verdict: `SYNCED` / `DRIFT` / `INSUFFICIENT-SOURCES` (< 2 distinct owners is never consent). Default tolerance 300000 ms. `endpoints` JSON is shape-validated and every URL passes the egress gate before any fetch (reserved/internal shapes refused by rule name; blocked = failed receipt, never consent). HEAD only, zero payload, redirects not followed. |
108
+ | `sibyl_attribute` | `{ moves, commits, roster }` | Pure comparator (zero network/git of its own): attributes git ref-moves to committer identities against a roster. Per-move verdict: `ATTRIBUTED` / `UNATTRIBUTED` (the silent-egress case) / `AMBIGUOUS` (byte-equal roster pair = registry defect, blocks, never picks). Identity matching is byte-exact by design — no normalization. `moves`/`roster` JSON is shape-validated; malformed input is refused by name (entry-indexed), never guessed at. |
109
109
 
110
110
  ## Options
111
111
 
@@ -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
@@ -201,10 +208,20 @@ Plainly stated:
201
208
 
202
209
  ## Security notes
203
210
 
211
+ See **[SECURITY.md](SECURITY.md)** for the disclosure channel (private GitHub
212
+ advisory), the full data-egress map, and the honestly-named limitations.
213
+ Summary:
214
+
204
215
  - Consult/swarm send the artifact text to your configured model pool providers.
216
+ - `sibyl_time_probe` fetches nothing before the URL passes the egress gate
217
+ (v1.5.0): reserved/internal address shapes, single-label hosts, non-http(s)
218
+ schemes, userinfo and non-default ports are refused by rule name; a blocked
219
+ source is a failed receipt, never consent.
205
220
  - The plugin writes under its state paths (the runs file and the per-run space) and,
206
221
  for chamber/exam lanes, sealed run directories under `lane.runRoot`
207
- (default `/tmp`) — role homes, transcripts, pidfiles, CHECKSUMS.
222
+ (default `/tmp`), every plugin-created dir `0700` (mkdir mode + explicit chmod:
223
+ unreachable to group/other regardless of umask — v1.4.0 private-dir law) —
224
+ role homes, transcripts, pidfiles, CHECKSUMS.
208
225
  - Voter/worker turns run with `bash`, `edit`, and `write` disabled per prompt.
209
226
 
210
227
  ## Architecture (`src/`)
@@ -244,8 +261,10 @@ index.ts plugin entry: parse options → share one RunStore + client
244
261
  ├── independence.ts W1 convener-recusal: engine-store chain walk +
245
262
  │ drafting-evidence scan (INDEPENDENT / NOT-INDEPENDENT /
246
263
  │ UNVERIFIABLE, fail-closed on unreadable)
247
- ├── options.ts zod v4 schema + parseOptions (never throws)
264
+ ├── options.ts zod v4 schema + parseOptions (never throws); home of the
265
+ │ config-default single sources (DEFAULT_TIMEOUT_MS)
248
266
  ├── cli.ts v1.1 sibyl-chamber bin: run | status | spotcheck | kill
267
+ ├── util.ts v1.5.0 single definitions: withTimeout + errMessage
249
268
  └── tools/ sibyl_consult / sibyl_swarm / sibyl_status / sibyl_review
250
269
  + audit primitives (anchor / time probe / attribution)
251
270
  glue + shared helpers (model-slot chain, artifact reader)
@@ -263,7 +282,8 @@ PLAN→MINT→DISPATCH→AGGREGATE pipeline over ordinary child sessions.
263
282
 
264
283
  ```bash
265
284
  npm run typecheck # tsc --noEmit, strict + noUncheckedIndexedAccess + exactOptionalPropertyTypes
266
- npm test # full unit suite, fully offline (no network, no LLM; ~420 at v1.3.0 — the run prints the exact count)
285
+ npm test # full unit suite, fully offline (no network, no LLM; 480 at v1.5.0 — the run prints the exact count)
286
+ npm run coverage # offline suite + coverage floor ratchet (lines 55 / branches 80 / funcs 90 — floors only move up; CI door)
267
287
  npm run build # esbuild bundle → dist/index.js + dist/cli.js (ESM)
268
288
  node smoke/run-smoke.mjs # offline smoke of the shipped surface (see smoke/README.md)
269
289
  ./ship.sh # the full release gate: all of the above + portability scan of the packed tarball
@@ -295,4 +315,4 @@ MIT
295
315
 
296
316
  ## Release wheel
297
317
 
298
- Tags v* require a packet receipt (docs/release/<ver>.md with a real `gate: PASS` line) and a lease; after cloning run `scripts/install-hooks.sh` — hooks are per-clone and ship empty. **W4 (2026-10-05):** the hook reads the receipt AND `package.json`'s version exclusively from the pushed tag's **object body** (`git show <oid>:<path>`); working-tree reads are forbidden — the tag must carry its own paperwork, and the in-tag version must equal the tag name (ghost-version class killed). Regression-locked in `test/hook-prepush.test.ts` (ref lines fed via stdin).
318
+ Tags v* require a packet receipt (docs/release/<ver>.md with a real `gate: PASS` line) and a lease; after cloning run `scripts/install-hooks.sh` — hooks are per-clone and ship empty. **W4 (2026-10-05):** the hook reads the receipt AND `package.json`'s version exclusively from the pushed tag's **object body** (`git show <oid>:<path>`); working-tree reads are forbidden — the tag must carry its own paperwork, and the in-tag version must equal the tag name (ghost-version class killed). **Tag-body hygiene (2026-10-24):** annotated-tag message bodies are scanned on push — home-path and email shapes refuse by rule name (the message is public release content; anchor facts by hash/run-id, not machine paths). Regression-locked in `test/hook-prepush.test.ts` (ref lines fed via stdin).