wyrm-mcp 6.18.1 → 7.0.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.
- package/README.md +23 -3
- package/dist/attribution.d.ts +51 -0
- package/dist/attribution.d.ts.map +1 -0
- package/dist/attribution.js +49 -0
- package/dist/attribution.js.map +1 -0
- package/dist/audit.d.ts +184 -8
- package/dist/audit.d.ts.map +1 -1
- package/dist/audit.js +331 -22
- package/dist/audit.js.map +1 -1
- package/dist/auto-capture.d.ts +11 -0
- package/dist/auto-capture.d.ts.map +1 -1
- package/dist/auto-capture.js +13 -0
- package/dist/auto-capture.js.map +1 -1
- package/dist/capture.js +5 -5
- package/dist/capture.js.map +1 -1
- package/dist/causality.d.ts.map +1 -1
- package/dist/causality.js +6 -3
- package/dist/causality.js.map +1 -1
- package/dist/daemon-write-endpoint.d.ts +112 -0
- package/dist/daemon-write-endpoint.d.ts.map +1 -0
- package/dist/daemon-write-endpoint.js +290 -0
- package/dist/daemon-write-endpoint.js.map +1 -0
- package/dist/daemon-writer.d.ts +196 -0
- package/dist/daemon-writer.d.ts.map +1 -0
- package/dist/daemon-writer.js +406 -0
- package/dist/daemon-writer.js.map +1 -0
- package/dist/database.d.ts +33 -1
- package/dist/database.d.ts.map +1 -1
- package/dist/database.js +92 -31
- package/dist/database.js.map +1 -1
- package/dist/deprecations.d.ts +41 -12
- package/dist/deprecations.d.ts.map +1 -1
- package/dist/deprecations.js +56 -27
- package/dist/deprecations.js.map +1 -1
- package/dist/event-replication.d.ts +2 -2
- package/dist/event-replication.d.ts.map +1 -1
- package/dist/event-replication.js +1 -1
- package/dist/events-sse.d.ts +4 -2
- package/dist/events-sse.d.ts.map +1 -1
- package/dist/events-sse.js +4 -2
- package/dist/events-sse.js.map +1 -1
- package/dist/events.d.ts +13 -0
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +17 -6
- package/dist/events.js.map +1 -1
- package/dist/failure-patterns.d.ts +416 -3
- package/dist/failure-patterns.d.ts.map +1 -1
- package/dist/failure-patterns.js +693 -46
- package/dist/failure-patterns.js.map +1 -1
- package/dist/handlers/alias-adapters.d.ts +62 -0
- package/dist/handlers/alias-adapters.d.ts.map +1 -0
- package/dist/handlers/alias-adapters.js +129 -0
- package/dist/handlers/alias-adapters.js.map +1 -0
- package/dist/handlers/aliases.d.ts +54 -0
- package/dist/handlers/aliases.d.ts.map +1 -0
- package/dist/handlers/aliases.js +170 -0
- package/dist/handlers/aliases.js.map +1 -0
- package/dist/handlers/boundary.d.ts +114 -0
- package/dist/handlers/boundary.d.ts.map +1 -0
- package/dist/handlers/boundary.js +203 -0
- package/dist/handlers/boundary.js.map +1 -0
- package/dist/handlers/capture.d.ts +25 -0
- package/dist/handlers/capture.d.ts.map +1 -0
- package/dist/handlers/capture.js +969 -0
- package/dist/handlers/capture.js.map +1 -0
- package/dist/handlers/failure.d.ts +28 -0
- package/dist/handlers/failure.d.ts.map +1 -0
- package/dist/handlers/failure.js +340 -0
- package/dist/handlers/failure.js.map +1 -0
- package/dist/handlers/goals.d.ts +21 -5
- package/dist/handlers/goals.d.ts.map +1 -1
- package/dist/handlers/goals.js +283 -52
- package/dist/handlers/goals.js.map +1 -1
- package/dist/handlers/output-schemas.d.ts +25 -0
- package/dist/handlers/output-schemas.d.ts.map +1 -0
- package/dist/handlers/output-schemas.js +24 -0
- package/dist/handlers/output-schemas.js.map +1 -0
- package/dist/handlers/prompts.d.ts +59 -0
- package/dist/handlers/prompts.d.ts.map +1 -0
- package/dist/handlers/prompts.js +156 -0
- package/dist/handlers/prompts.js.map +1 -0
- package/dist/handlers/quest.d.ts +24 -0
- package/dist/handlers/quest.d.ts.map +1 -0
- package/dist/handlers/quest.js +224 -0
- package/dist/handlers/quest.js.map +1 -0
- package/dist/handlers/recall.d.ts +20 -0
- package/dist/handlers/recall.d.ts.map +1 -0
- package/dist/handlers/recall.js +188 -0
- package/dist/handlers/recall.js.map +1 -0
- package/dist/handlers/registry.d.ts +72 -6
- package/dist/handlers/registry.d.ts.map +1 -1
- package/dist/handlers/registry.js +116 -9
- package/dist/handlers/registry.js.map +1 -1
- package/dist/handlers/review.d.ts +16 -0
- package/dist/handlers/review.d.ts.map +1 -0
- package/dist/handlers/review.js +66 -0
- package/dist/handlers/review.js.map +1 -0
- package/dist/handlers/run.d.ts +47 -0
- package/dist/handlers/run.d.ts.map +1 -0
- package/dist/handlers/run.js +498 -0
- package/dist/handlers/run.js.map +1 -0
- package/dist/handlers/search.d.ts +22 -0
- package/dist/handlers/search.d.ts.map +1 -0
- package/dist/handlers/search.js +326 -0
- package/dist/handlers/search.js.map +1 -0
- package/dist/handlers/session.d.ts +54 -0
- package/dist/handlers/session.d.ts.map +1 -0
- package/dist/handlers/session.js +623 -0
- package/dist/handlers/session.js.map +1 -0
- package/dist/handlers/shims.d.ts +84 -0
- package/dist/handlers/shims.d.ts.map +1 -0
- package/dist/handlers/shims.js +463 -0
- package/dist/handlers/shims.js.map +1 -0
- package/dist/handlers/survivors.d.ts +76 -0
- package/dist/handlers/survivors.d.ts.map +1 -0
- package/dist/handlers/survivors.js +101 -0
- package/dist/handlers/survivors.js.map +1 -0
- package/dist/handlers/types.d.ts +156 -7
- package/dist/handlers/types.d.ts.map +1 -1
- package/dist/handlers/types.js +9 -1
- package/dist/handlers/types.js.map +1 -1
- package/dist/http-fast.d.ts.map +1 -1
- package/dist/http-fast.js +157 -76
- package/dist/http-fast.js.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +483 -1747
- package/dist/index.js.map +1 -1
- package/dist/intelligence.d.ts.map +1 -1
- package/dist/intelligence.js +7 -3
- package/dist/intelligence.js.map +1 -1
- package/dist/maintenance.d.ts +56 -0
- package/dist/maintenance.d.ts.map +1 -0
- package/dist/maintenance.js +150 -0
- package/dist/maintenance.js.map +1 -0
- package/dist/memory-artifacts.d.ts.map +1 -1
- package/dist/memory-artifacts.js +7 -3
- package/dist/memory-artifacts.js.map +1 -1
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +281 -0
- package/dist/migrations.js.map +1 -1
- package/dist/presence.d.ts +48 -8
- package/dist/presence.d.ts.map +1 -1
- package/dist/presence.js +61 -14
- package/dist/presence.js.map +1 -1
- package/dist/reindex.d.ts +28 -0
- package/dist/reindex.d.ts.map +1 -0
- package/dist/reindex.js +88 -0
- package/dist/reindex.js.map +1 -0
- package/dist/render.d.ts +240 -0
- package/dist/render.d.ts.map +1 -0
- package/dist/render.js +280 -0
- package/dist/render.js.map +1 -0
- package/dist/resilience.d.ts.map +1 -1
- package/dist/resilience.js +30 -4
- package/dist/resilience.js.map +1 -1
- package/dist/sqlite-busy.d.ts +134 -0
- package/dist/sqlite-busy.d.ts.map +1 -0
- package/dist/sqlite-busy.js +154 -0
- package/dist/sqlite-busy.js.map +1 -0
- package/dist/statusline.d.ts.map +1 -1
- package/dist/statusline.js +8 -2
- package/dist/statusline.js.map +1 -1
- package/dist/tool-annotations.d.ts +39 -0
- package/dist/tool-annotations.d.ts.map +1 -1
- package/dist/tool-annotations.js +99 -3
- package/dist/tool-annotations.js.map +1 -1
- package/dist/tool-manifest.json +1 -1
- package/dist/tool-profiles.d.ts +35 -27
- package/dist/tool-profiles.d.ts.map +1 -1
- package/dist/tool-profiles.js +41 -118
- package/dist/tool-profiles.js.map +1 -1
- package/dist/ulid.d.ts +26 -0
- package/dist/ulid.d.ts.map +1 -0
- package/dist/ulid.js +81 -0
- package/dist/ulid.js.map +1 -0
- package/dist/version-check.d.ts.map +1 -1
- package/dist/version-check.js +4 -1
- package/dist/version-check.js.map +1 -1
- package/dist/wyrm-cli.js +531 -2
- package/dist/wyrm-cli.js.map +1 -1
- package/dist/wyrm-guard.d.ts +97 -0
- package/dist/wyrm-guard.d.ts.map +1 -0
- package/dist/wyrm-guard.js +425 -0
- package/dist/wyrm-guard.js.map +1 -0
- package/dist/wyrm-manifest.json +1233 -0
- package/package.json +5 -6
- package/dist/http-server.d.ts +0 -12
- package/dist/http-server.d.ts.map +0 -1
- package/dist/http-server.js +0 -563
- package/dist/http-server.js.map +0 -1
- package/ui/index.html +0 -575
package/README.md
CHANGED
|
@@ -4,10 +4,14 @@
|
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/wyrm-mcp)
|
|
6
6
|
[](LICENSE)
|
|
7
|
-
[](https://github.com/Ghosts-Protocol-Pvt-Ltd/Wyrm)
|
|
8
8
|
[](https://www.typescriptlang.org/)
|
|
9
9
|
[](https://modelcontextprotocol.io)
|
|
10
10
|
|
|
11
|
+
**[wyrm.ghosts.lk](https://wyrm.ghosts.lk)** · **[npm](https://www.npmjs.com/package/wyrm-mcp)** · **[GitHub](https://github.com/Ghosts-Protocol-Pvt-Ltd/Wyrm)** · **[Ghost Protocol](https://ghosts.lk)** · `npm i -g wyrm-mcp`
|
|
12
|
+
|
|
13
|
+
Local-first persistent memory for AI agents over MCP — by [Ghost Protocol](https://ghosts.lk). Runs fully offline on your machine: no cloud, no account, no LLM required. The managed cloud tier lives at **[wyrm.ghosts.lk](https://wyrm.ghosts.lk)**.
|
|
14
|
+
|
|
11
15
|
---
|
|
12
16
|
|
|
13
17
|
## What Wyrm actually is
|
|
@@ -31,11 +35,27 @@ You don't ask for memory. The AI cites it on its own. Visibly, with sources.
|
|
|
31
35
|
|
|
32
36
|
---
|
|
33
37
|
|
|
38
|
+
## New in 7.0 — "BROOD": memory for agent FLEETS
|
|
39
|
+
|
|
40
|
+
> *One agent burns its hand and a hundred siblings never touch the stove.*
|
|
41
|
+
|
|
42
|
+
The unit of cognition is now the **run** — an orchestrator fanning out structured-output subagents — and 7.0 rebuilds Wyrm around it:
|
|
43
|
+
|
|
44
|
+
- **The lean frozen surface.** Default ListTools advertises **32 tools** (≈7,993 tokens — chars/4, the F1-census convention — byte-stable across calls) instead of 6.x's 62-tool default / 137 full-load — and **every one of the 137 6.x names stays callable** through a generated alias spine routing to the same handlers. `WYRM_PROFILE=essential` = the core 4 (`session_prime` / `recall` / `capture` / `failure_check`); `WYRM_PROFILE=legacy` (or `full`, now its permanent synonym) re-advertises everything. Discovery is a hard CI gate: BM25 top-3 **100%** on 65 intent queries (threshold 90%).
|
|
45
|
+
- **Run-native attribution.** First-class `runs`/`run_agents` tables; every write attributable to `(agent_id, run_id)` (explicit param > `_meta['wyrm/actor']` > env > clientInfo), bound into the signed Ed25519 audit chain.
|
|
46
|
+
- **Fleet negative learning.** A failure recorded by one subagent **blocks the repeat for every sibling**: run-scoped quarantine with principled promotion, structured `failure_check` verdicts (`{blocked, matches[], recorded_by_agent, run_id, confidence}` — deterministic, no LLM), and **`wyrm-guard`** — a PreToolUse hook bin that enforces it harness-side (block / warn / silent when clean; measured p95 ≤70ms incl. node startup). `wyrm_stats view=failures` prints the ROI number nobody else can: *"N repeats blocked this run."*
|
|
47
|
+
- **The run loop.** `wyrm_run` `action=start|join|status|debrief|end` — debrief fans each agent's learnings through LOCAL-only extraction (Ollama / deterministic fallback, never a cloud LLM) into a run-scoped review queue; `end` promotes/expires quarantined failures and releases the run's claims. Fleet-mode `session_prime {run_id, role}` returns a byte-stable cached brief (≤1,200 tokens) — 12 simultaneous primes share one prompt-cache prefix. **Distribute-once**: an orchestrator that primes one `{run_id, role, for_spawn: true}` per role gets that brief back as clean embeddable markdown (+ `brief_hash` + the `run_briefs` cache key) and embeds it in each same-role agent's spawn-prompt **prefix** — so the cacheable share of the fleet's prime cost becomes never-sent bytes (measured: a 12-agent / 4-role run's prime deliveries drop 12 → 4; bench `S3b` is −38.7% vs the `S3` floor). Agent-side prime stays the byte-identical CAS-row fallback, so a forgetful orchestrator degrades to the unchanged per-agent cost, never below.
|
|
48
|
+
- **A typed machine wire.** The 7 hot-path domains (capture, recall, search, failure, quest, session/prime, review) return schema-validated `structuredContent`; `content[0].text` is *derived* from it (plain ASCII default, `WYRM_FANCY=1` for glyphs); SEP-1303 structured errors fleets self-correct on; 100% of advertised tools annotated; `prime`/`debrief` exposed as MCP protocol-level prompts.
|
|
49
|
+
- **Single-channel wire (opt-in token economy).** `WYRM_CHANNEL` (vendor-neutral, set per MCP-client config) chooses which channel(s) ride the wire. Default **`both`** = today's exact bytes (no change unless you opt in). **`structured`** keeps the full `structuredContent` body byte-identical and collapses `content[0].text` to the template's summary line + a "full body in structuredContent" pointer — **lossless by construction** (the text was always *derived* from the body) and protocol-valid, but requires that your harness forwards `structuredContent` to the model. **`text`** drops `structuredContent` and keeps the full prose (the human-complete derivation) — the lean mode for harnesses that read text only; **note:** a strict MCP client rejects a body-less response for a tool that declares an `outputSchema`, so `text` is for non-strict / text-only consumers. Measured on `bench/token-economy.mjs --channel`: an opted-in working hour drops **~40%** (`structured`) to **~49%** (`text`); recall (82% of that hour) is the lever. `session_rehydrate` is exempt (its briefing markdown *is* the payload).
|
|
50
|
+
- **CLI exile + deletions.** 22 operator/egress tools moved to `wyrm` subcommands — their MCP names return a structured redirect with the exact command (`wyrm_cloud_backup`/`wyrm_sync_export` keep executing through 7.0.x so scheduled backups never silently stop). The legacy `wyrm-http` server is **deleted** (its 6.18 access log measured zero traffic) — `wyrm serve` is the HTTP surface.
|
|
51
|
+
|
|
52
|
+
**Compatibility:** all 137 names callable; text output reformats (exact-string consumers pin the 6.x line — kept on the `legacy` dist-tag (`wyrm-mcp@6.18.1`): `npm i wyrm-mcp@legacy`); a v6.x database opens with 100% rows (migrations 20–24, all additive + guarded). Per-name dispositions: `specs/wyrm-v7-brood/disposition.md` in the repo.
|
|
53
|
+
|
|
34
54
|
## New in 6.0 — "Present"
|
|
35
55
|
|
|
36
56
|
- **Live statusline** — `wyrm-statusline` binary renders Wyrm's live state into your Claude Code (or Cursor / Windsurf) statusline: `Wyrm · ProjectName · 3 ⟶ · ~12k saved · ⬢ 7`. Auto-spawned daemon, idle-times-out, privacy mode for screen-shares.
|
|
37
57
|
- **✧ Cross-project memory** — `wyrm_constellation` queries FTS5 across every registered Wyrm project at once. *"Have I solved this before in any project?"* Privacy-gated: per-row `cross_project_visibility` defaults to `'within'`.
|
|
38
|
-
- **▰ Tool profiles** — `essential` / `standard` / `full` profiles
|
|
58
|
+
- **▰ Tool profiles** — `essential` / `standard` / `full` profiles. *(7.0: client-name auto-detection removed — `WYRM_PROFILE` is the one lever; `full` = `legacy`.)*
|
|
39
59
|
- **⊡ Cache markers** — `wyrm_context_build` segregates a stable preamble for Anthropic prompt-caching (10× cost cut on cached portions).
|
|
40
60
|
- **↺ `wyrm_migrate_prompt`** — rewrite Wyrm-managed blocks in `.cursor/rules`, `.github/copilot-instructions.md`, `CLAUDE.md` idempotently. Operator content outside the markers is preserved verbatim.
|
|
41
61
|
|
|
@@ -44,7 +64,7 @@ Enable the statusline in Claude Code:
|
|
|
44
64
|
{ "statusLine": { "type": "command", "command": "wyrm-statusline", "padding": 0 } }
|
|
45
65
|
```
|
|
46
66
|
|
|
47
|
-
## What's in the box (
|
|
67
|
+
## What's in the box (32 advertised tools · 137 names callable)
|
|
48
68
|
|
|
49
69
|
- **⌇ Memory** — projects, sessions, quests, ground truths, memory artifacts, hybrid FTS5 + vector search
|
|
50
70
|
- **✖ Counter-pattern** — failure check / record / resolve, blocks repeated mistakes at suggestion time
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wyrm attribution read helpers (v7 F2, T008).
|
|
3
|
+
*
|
|
4
|
+
* @copyright 2026 Ghost Protocol (Pvt) Ltd.
|
|
5
|
+
* @license AGPL-3.0-or-later — dual-licensed; commercial terms: ghosts.lk@proton.me. See LICENSE.
|
|
6
|
+
*
|
|
7
|
+
* Migration 20 adds nullable `agent_id`/`run_id` attribution columns to 9
|
|
8
|
+
* tables. Every row written before v7 — and any v7 row written outside a fleet
|
|
9
|
+
* run — carries NULL attribution. Article VI: a v6.x DB must open under v7
|
|
10
|
+
* with 100% of its rows, and that history must stay legibly attributed, so at
|
|
11
|
+
* every READ SITE that surfaces attribution, NULL reads as actor='legacy'.
|
|
12
|
+
*
|
|
13
|
+
* Precedence when rendering "who did this" (the same order is documented in
|
|
14
|
+
* migration 20 next to the events.agent_id column):
|
|
15
|
+
* 1. agent_id — machine identity (v7 fleet writes)
|
|
16
|
+
* 2. actor — display identity (the existing 6.x column on
|
|
17
|
+
* events/audit_log; it is EXTENDED, never replaced)
|
|
18
|
+
* 3. LEGACY_ACTOR — 'legacy' (neither set: a pre-v7 row)
|
|
19
|
+
*
|
|
20
|
+
* Wire paths (eventsForPush, ingestRemoteEvent, replication) intentionally do
|
|
21
|
+
* NOT coalesce: NULL stays NULL in storage and on the wire so replication
|
|
22
|
+
* round-trips are byte-faithful. 'legacy' is a READ-TIME presentation value
|
|
23
|
+
* only — it is never written back to the database.
|
|
24
|
+
*/
|
|
25
|
+
/** What NULL attribution reads as at attribution-surfacing read sites. */
|
|
26
|
+
export declare const LEGACY_ACTOR = "legacy";
|
|
27
|
+
/**
|
|
28
|
+
* Read a display actor from a nullable actor column.
|
|
29
|
+
* NULL/undefined/blank -> 'legacy'; anything else passes through trimmed.
|
|
30
|
+
*/
|
|
31
|
+
export declare function readActor(actor?: string | null): string;
|
|
32
|
+
/** The attribution fields migration 20 adds (all nullable). */
|
|
33
|
+
export interface AttributedRow {
|
|
34
|
+
agent_id?: string | null;
|
|
35
|
+
run_id?: string | null;
|
|
36
|
+
/** Existing display-identity column on events/audit_log (6.x). */
|
|
37
|
+
actor?: string | null;
|
|
38
|
+
}
|
|
39
|
+
export interface ResolvedAttribution {
|
|
40
|
+
/** Display identity, never null: agent_id > actor > 'legacy'. */
|
|
41
|
+
actor: string;
|
|
42
|
+
agent_id: string | null;
|
|
43
|
+
run_id: string | null;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Resolve the full attribution for one row using the documented precedence.
|
|
47
|
+
* Use this at any read site that surfaces who/which-run produced a row
|
|
48
|
+
* (failure_check verdicts, wyrm_stats view=failures, event displays).
|
|
49
|
+
*/
|
|
50
|
+
export declare function resolveAttribution(row: AttributedRow): ResolvedAttribution;
|
|
51
|
+
//# sourceMappingURL=attribution.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attribution.d.ts","sourceRoot":"","sources":["../src/attribution.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,0EAA0E;AAC1E,eAAO,MAAM,YAAY,WAAW,CAAC;AAErC;;;GAGG;AACH,wBAAgB,SAAS,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAGvD;AAED,+DAA+D;AAC/D,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,kEAAkE;IAClE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,mBAAmB;IAClC,iEAAiE;IACjE,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,aAAa,GAAG,mBAAmB,CAQ1E"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wyrm attribution read helpers (v7 F2, T008).
|
|
3
|
+
*
|
|
4
|
+
* @copyright 2026 Ghost Protocol (Pvt) Ltd.
|
|
5
|
+
* @license AGPL-3.0-or-later — dual-licensed; commercial terms: ghosts.lk@proton.me. See LICENSE.
|
|
6
|
+
*
|
|
7
|
+
* Migration 20 adds nullable `agent_id`/`run_id` attribution columns to 9
|
|
8
|
+
* tables. Every row written before v7 — and any v7 row written outside a fleet
|
|
9
|
+
* run — carries NULL attribution. Article VI: a v6.x DB must open under v7
|
|
10
|
+
* with 100% of its rows, and that history must stay legibly attributed, so at
|
|
11
|
+
* every READ SITE that surfaces attribution, NULL reads as actor='legacy'.
|
|
12
|
+
*
|
|
13
|
+
* Precedence when rendering "who did this" (the same order is documented in
|
|
14
|
+
* migration 20 next to the events.agent_id column):
|
|
15
|
+
* 1. agent_id — machine identity (v7 fleet writes)
|
|
16
|
+
* 2. actor — display identity (the existing 6.x column on
|
|
17
|
+
* events/audit_log; it is EXTENDED, never replaced)
|
|
18
|
+
* 3. LEGACY_ACTOR — 'legacy' (neither set: a pre-v7 row)
|
|
19
|
+
*
|
|
20
|
+
* Wire paths (eventsForPush, ingestRemoteEvent, replication) intentionally do
|
|
21
|
+
* NOT coalesce: NULL stays NULL in storage and on the wire so replication
|
|
22
|
+
* round-trips are byte-faithful. 'legacy' is a READ-TIME presentation value
|
|
23
|
+
* only — it is never written back to the database.
|
|
24
|
+
*/
|
|
25
|
+
/** What NULL attribution reads as at attribution-surfacing read sites. */
|
|
26
|
+
export const LEGACY_ACTOR = 'legacy';
|
|
27
|
+
/**
|
|
28
|
+
* Read a display actor from a nullable actor column.
|
|
29
|
+
* NULL/undefined/blank -> 'legacy'; anything else passes through trimmed.
|
|
30
|
+
*/
|
|
31
|
+
export function readActor(actor) {
|
|
32
|
+
const a = typeof actor === 'string' ? actor.trim() : '';
|
|
33
|
+
return a !== '' ? a : LEGACY_ACTOR;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Resolve the full attribution for one row using the documented precedence.
|
|
37
|
+
* Use this at any read site that surfaces who/which-run produced a row
|
|
38
|
+
* (failure_check verdicts, wyrm_stats view=failures, event displays).
|
|
39
|
+
*/
|
|
40
|
+
export function resolveAttribution(row) {
|
|
41
|
+
const agentId = row.agent_id ?? null;
|
|
42
|
+
const runId = row.run_id ?? null;
|
|
43
|
+
return {
|
|
44
|
+
actor: agentId ?? readActor(row.actor),
|
|
45
|
+
agent_id: agentId,
|
|
46
|
+
run_id: runId,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=attribution.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attribution.js","sourceRoot":"","sources":["../src/attribution.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,0EAA0E;AAC1E,MAAM,CAAC,MAAM,YAAY,GAAG,QAAQ,CAAC;AAErC;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,KAAqB;IAC7C,MAAM,CAAC,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACxD,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC;AACrC,CAAC;AAiBD;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAkB;IACnD,MAAM,OAAO,GAAG,GAAG,CAAC,QAAQ,IAAI,IAAI,CAAC;IACrC,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,IAAI,IAAI,CAAC;IACjC,OAAO;QACL,KAAK,EAAE,OAAO,IAAI,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC;QACtC,QAAQ,EAAE,OAAO;QACjB,MAAM,EAAE,KAAK;KACd,CAAC;AACJ,CAAC"}
|
package/dist/audit.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Compliance audit trail (Tier 3.9)
|
|
2
|
+
* Compliance audit trail (Tier 3.9) — per-agent attribution + versioned
|
|
3
|
+
* Ed25519 signing (v7 F2, T010).
|
|
3
4
|
*
|
|
4
5
|
* Hash-chained event log: each row records sha256(prev_hash || payload ||
|
|
5
6
|
* timestamp). Tampering with any historical entry breaks the chain.
|
|
@@ -10,13 +11,59 @@
|
|
|
10
11
|
* `wyrm_audit_export(range)` produces a tamper-evident JSON bundle that
|
|
11
12
|
* an external auditor can verify offline:
|
|
12
13
|
* 1. Recompute the hash chain from genesis through the range.
|
|
13
|
-
* 2. Verify Ed25519 signatures against the operator's public key.
|
|
14
|
+
* 2. Verify Ed25519 signatures against the operator's public key(s).
|
|
14
15
|
* 3. Confirm no gaps in IDs.
|
|
15
16
|
*
|
|
17
|
+
* ## Signed-payload versioning (v7 F2, T010)
|
|
18
|
+
*
|
|
19
|
+
* Migration 20's `agent_id`/`run_id` columns are NOT part of the hash-chain
|
|
20
|
+
* input — the chain rule is byte-identical to 6.x:
|
|
21
|
+
*
|
|
22
|
+
* row_hash = sha256(`${prev_hash}|${event_kind}|${payload_json}|${logged_at}`)
|
|
23
|
+
*
|
|
24
|
+
* so a 6.x DB opened under v7 keeps verifying and the v1→v2 transition can
|
|
25
|
+
* never break the chain (old rows verify as v1, new rows as v2, one chain).
|
|
26
|
+
* Attribution is instead bound TAMPER-EVIDENTLY into the Ed25519 signature
|
|
27
|
+
* via a payload-version byte:
|
|
28
|
+
*
|
|
29
|
+
* v1 (legacy 6.x): signed message = utf8(row_hash) — no attribution
|
|
30
|
+
* stored signature = bare base64 (unchanged on old rows)
|
|
31
|
+
* v2 (v7): signed message = 0x02 ‖ utf8(JSON.stringify(
|
|
32
|
+
* { row_hash, agent_id, run_id })) — attribution bound
|
|
33
|
+
* stored signature = `v2:<key_fp16>:<base64>`
|
|
34
|
+
*
|
|
35
|
+
* The leading 0x02 version byte domain-separates the payloads (a v1 message
|
|
36
|
+
* is 64 ASCII-hex bytes and can never begin with 0x02), and the canonical
|
|
37
|
+
* JSON body (fixed key order, NULLs preserved) makes the agent_id/run_id
|
|
38
|
+
* field boundaries unambiguous — no delimiter-shifting forgeries.
|
|
39
|
+
* `key_fp16` = first 16 hex chars of sha256(SPKI DER of the signing public
|
|
40
|
+
* key): the "which key" answer, claimed in the row and CONFIRMED whenever
|
|
41
|
+
* public keys are handed to `verify()`.
|
|
42
|
+
*
|
|
43
|
+
* ## The rule for 6.x verifiers (explicit — locked by tests/audit-attribution.test.ts)
|
|
44
|
+
*
|
|
45
|
+
* The verify structure 6.x actually shipped (`verify()` / `verifyBundle()`)
|
|
46
|
+
* checks ONLY the hash chain and never parses the `signature` column.
|
|
47
|
+
* Therefore:
|
|
48
|
+
* (a) a 6.x verifier verifies BOTH v1 and v2 rows exactly as today — the
|
|
49
|
+
* chain rule is unchanged, mixed v1/v2 chains pass, and exported
|
|
50
|
+
* bundles remain version-1 bundles that 6.x `verifyBundle()` accepts;
|
|
51
|
+
* (b) a 6.x auditor's out-of-band Ed25519 step ("signature of the
|
|
52
|
+
* row_hash") FAILS CLOSED on a v2 row: the stored `v2:`-prefixed value
|
|
53
|
+
* is not the base64 of an Ed25519 signature over the row_hash, so the
|
|
54
|
+
* 6.x signature check reports INVALID — it can never silently accept a
|
|
55
|
+
* v7 signature (and so can never silently accept forged attribution).
|
|
56
|
+
* The chain walk itself stays green.
|
|
57
|
+
*
|
|
58
|
+
* Signing is OPT-IN (Articles I & VII): no key configured → rows are written
|
|
59
|
+
* unsigned, byte-identical to 6.x behavior. `WYRM_AUDIT_SIGNING_KEY` holds a
|
|
60
|
+
* PEM-encoded (pkcs8) Ed25519 private key, or a path to one.
|
|
61
|
+
*
|
|
16
62
|
* @copyright 2024-2026 Ghost Protocol (Pvt) Ltd.
|
|
17
63
|
* @license AGPL-3.0-or-later — dual-licensed; commercial terms: ghosts.lk@proton.me. See LICENSE.
|
|
18
64
|
*/
|
|
19
65
|
import type Database from 'better-sqlite3';
|
|
66
|
+
import { KeyObject } from 'crypto';
|
|
20
67
|
export interface AuditEntry {
|
|
21
68
|
id: number;
|
|
22
69
|
event_kind: string;
|
|
@@ -27,13 +74,24 @@ export interface AuditEntry {
|
|
|
27
74
|
row_hash: string;
|
|
28
75
|
signature: string | null;
|
|
29
76
|
logged_at: string;
|
|
77
|
+
/** v7 F2 (migration 20): machine attribution columns. NULL on pre-v7 rows
|
|
78
|
+
* (reads as actor='legacy'). NOT part of the hash chain — the v2 signed
|
|
79
|
+
* payload (T010) is what binds them tamper-evidently. */
|
|
80
|
+
agent_id: string | null;
|
|
81
|
+
run_id: string | null;
|
|
30
82
|
}
|
|
31
83
|
export interface LogInput {
|
|
32
84
|
event_kind: string;
|
|
33
85
|
actor?: string | null;
|
|
34
86
|
project_id?: number | null;
|
|
35
87
|
payload: Record<string, unknown>;
|
|
88
|
+
/** Explicit caller-supplied signature (stored as-is — the legacy 6.x v1
|
|
89
|
+
* path). When omitted and a signer is configured, the entry is auto-signed
|
|
90
|
+
* with a v2 attribution-binding signature. */
|
|
36
91
|
signature?: string | null;
|
|
92
|
+
/** v7 F2 (T009): omitted → stamped from the ambient actor envelope. */
|
|
93
|
+
agent_id?: string | null;
|
|
94
|
+
run_id?: string | null;
|
|
37
95
|
}
|
|
38
96
|
export interface AuditBundle {
|
|
39
97
|
version: 1;
|
|
@@ -49,24 +107,135 @@ export interface AuditBundle {
|
|
|
49
107
|
final_row_hash: string;
|
|
50
108
|
entries: AuditEntry[];
|
|
51
109
|
}
|
|
110
|
+
/** v7 F2 (T010): signature-layer report — present when public keys are
|
|
111
|
+
* handed to verify()/verifyBundle(). Chain and signature layers are reported
|
|
112
|
+
* separately so a chain-intact/signature-forged DB is precisely described. */
|
|
113
|
+
export interface AuditSignatureReport {
|
|
114
|
+
/** Rows carrying any signature (v1 or v2) that were checked. */
|
|
115
|
+
checked: number;
|
|
116
|
+
valid: number;
|
|
117
|
+
invalid: number;
|
|
118
|
+
first_invalid_id?: number;
|
|
119
|
+
reason?: string;
|
|
120
|
+
}
|
|
52
121
|
export interface VerificationResult {
|
|
53
122
|
ok: boolean;
|
|
54
123
|
total: number;
|
|
55
124
|
verified: number;
|
|
56
125
|
first_invalid_id?: number;
|
|
57
126
|
reason?: string;
|
|
127
|
+
/** v7 F2 (T010): rows by signed-payload version (v1 legacy / v2 attribution
|
|
128
|
+
* / unsigned). Computed whenever the chain verifies. */
|
|
129
|
+
payload_versions?: {
|
|
130
|
+
v1: number;
|
|
131
|
+
v2: number;
|
|
132
|
+
unsigned: number;
|
|
133
|
+
};
|
|
134
|
+
/** v7 F2 (T010): who / which-run / which-key across the verified rows.
|
|
135
|
+
* `agents` are resolved display identities (NULL attribution reads as
|
|
136
|
+
* 'legacy' per Article VI); `keys` are signing-key fingerprints seen. */
|
|
137
|
+
attribution?: {
|
|
138
|
+
agents: string[];
|
|
139
|
+
runs: string[];
|
|
140
|
+
keys: string[];
|
|
141
|
+
};
|
|
142
|
+
/** v7 F2 (T010): only present when public keys were provided. */
|
|
143
|
+
signatures?: AuditSignatureReport;
|
|
144
|
+
}
|
|
145
|
+
/** Stored-signature prefix marking a v2 (attribution-binding) signature. */
|
|
146
|
+
export declare const AUDIT_SIG_V2_PREFIX = "v2:";
|
|
147
|
+
export type AuditPayloadVersion = 1 | 2;
|
|
148
|
+
export interface ParsedAuditSignature {
|
|
149
|
+
version: AuditPayloadVersion;
|
|
150
|
+
/** Claimed signing-key fingerprint (v2 only; null when absent/malformed). */
|
|
151
|
+
key_fp: string | null;
|
|
152
|
+
sig_b64: string;
|
|
58
153
|
}
|
|
154
|
+
/**
|
|
155
|
+
* Classify a stored signature string by payload version.
|
|
156
|
+
* Bare base64 (anything without the `v2:` prefix) = v1 legacy; `v2:<fp>:<b64>`
|
|
157
|
+
* = v2. Returns null for unsigned (NULL/empty). Never throws.
|
|
158
|
+
*/
|
|
159
|
+
export declare function parseAuditSignature(signature: string | null | undefined): ParsedAuditSignature | null;
|
|
160
|
+
/** Fingerprint of an Ed25519 public key: sha256 over the SPKI DER, first 16 hex. */
|
|
161
|
+
export declare function auditKeyFingerprint(publicKey: string | KeyObject): string;
|
|
162
|
+
/**
|
|
163
|
+
* Build the exact byte string an audit Ed25519 signature covers.
|
|
164
|
+
* v1: utf8(row_hash) — the legacy 6.x payload, no attribution.
|
|
165
|
+
* v2: 0x02 version byte ‖ utf8(JSON.stringify({row_hash, agent_id, run_id})).
|
|
166
|
+
*/
|
|
167
|
+
export declare function buildSignedPayload(version: AuditPayloadVersion, fields: {
|
|
168
|
+
row_hash: string;
|
|
169
|
+
agent_id?: string | null;
|
|
170
|
+
run_id?: string | null;
|
|
171
|
+
}): Buffer;
|
|
172
|
+
/** A loaded Ed25519 signing identity (per-agent: each agent process may run
|
|
173
|
+
* with its own key via WYRM_AUDIT_SIGNING_KEY). */
|
|
174
|
+
export interface AuditSigner {
|
|
175
|
+
privateKey: KeyObject;
|
|
176
|
+
publicKeyPem: string;
|
|
177
|
+
key_fp: string;
|
|
178
|
+
}
|
|
179
|
+
/** Materialize a signer from a PEM (pkcs8) Ed25519 private key; the public
|
|
180
|
+
* half and fingerprint are derived. Throws on non-Ed25519 keys. */
|
|
181
|
+
export declare function createAuditSigner(privateKeyPem: string): AuditSigner;
|
|
182
|
+
/** Sign the v2 payload for a row. Returns the stored form `v2:<fp>:<base64>`. */
|
|
183
|
+
export declare function signAuditEntry(signer: AuditSigner, fields: {
|
|
184
|
+
row_hash: string;
|
|
185
|
+
agent_id?: string | null;
|
|
186
|
+
run_id?: string | null;
|
|
187
|
+
}): string;
|
|
188
|
+
/**
|
|
189
|
+
* Opt-in signer bootstrap (Articles I & VII): `WYRM_AUDIT_SIGNING_KEY` is a
|
|
190
|
+
* PEM string or a path to a PEM file. Absent → null (rows stay unsigned —
|
|
191
|
+
* exactly the 6.x behavior). Unusable → warn on STDERR (stdout is the MCP
|
|
192
|
+
* wire) and run unsigned; never throws.
|
|
193
|
+
*/
|
|
194
|
+
export declare function loadAuditSignerFromEnv(env?: NodeJS.ProcessEnv): AuditSigner | null;
|
|
195
|
+
export interface AuditSignatureCheck {
|
|
196
|
+
ok: boolean;
|
|
197
|
+
/** null = the row carries no signature (not a failure). */
|
|
198
|
+
version: AuditPayloadVersion | null;
|
|
199
|
+
/** v2: the claimed fingerprint; v1-valid: the fingerprint of the key that verified. */
|
|
200
|
+
key_fp: string | null;
|
|
201
|
+
reason?: string;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Verify ONE row's signature against a set of public keys (PEM or KeyObject).
|
|
205
|
+
* Fail-closed: malformed signatures, unknown fingerprints, undecodable
|
|
206
|
+
* base64, and crypto-layer rejections all report ok=false. Never throws.
|
|
207
|
+
*/
|
|
208
|
+
export declare function verifyAuditEntrySignature(row: Pick<AuditEntry, 'row_hash' | 'signature' | 'agent_id' | 'run_id'>, publicKeys: Array<string | KeyObject>): AuditSignatureCheck;
|
|
59
209
|
export declare class AuditLog {
|
|
60
210
|
private db;
|
|
61
|
-
|
|
211
|
+
private signer;
|
|
212
|
+
constructor(db: Database.Database, signer?: AuditSigner | null);
|
|
213
|
+
/** Swap or clear the signing identity (key rotation, tests). */
|
|
214
|
+
setSigner(signer: AuditSigner | null): void;
|
|
62
215
|
/** Get the hash of the most recent entry (or 'genesis' if empty). */
|
|
63
216
|
private latestHash;
|
|
64
|
-
/** Append a hash-chained event. Returns the inserted row.
|
|
217
|
+
/** Append a hash-chained event. Returns the inserted row.
|
|
218
|
+
*
|
|
219
|
+
* v7 F2 review fix: the head-read + INSERT pair runs in ONE transaction
|
|
220
|
+
* declared IMMEDIATE, so BEGIN takes the cross-process write lock BEFORE
|
|
221
|
+
* latestHash() reads the chain head. Two concurrent OS processes appending
|
|
222
|
+
* (the T010 per-agent-key fleet shape — audit ops are not in
|
|
223
|
+
* DAEMON_WRITE_OPS, so fleet agents write audit_log directly) could
|
|
224
|
+
* otherwise both read head H and both insert prev_hash=H, FORKING the
|
|
225
|
+
* chain — after which verify() reports the compliance log as tampered
|
|
226
|
+
* forever on legitimate writes. */
|
|
65
227
|
log(input: LogInput): AuditEntry;
|
|
66
228
|
get(id: number): AuditEntry | null;
|
|
67
229
|
/** Verify the entire chain from the first row through the latest.
|
|
68
|
-
* Useful for periodic self-audits.
|
|
69
|
-
|
|
230
|
+
* Useful for periodic self-audits.
|
|
231
|
+
*
|
|
232
|
+
* v7 F2 (T010): pass `publicKeys` (PEM strings) to additionally verify the
|
|
233
|
+
* Ed25519 signature layer; the report then answers who / which-run /
|
|
234
|
+
* which-key. Without keys the result is the 6.x chain-only semantics plus
|
|
235
|
+
* the attribution summary. */
|
|
236
|
+
verify(opts?: {
|
|
237
|
+
publicKeys?: string[];
|
|
238
|
+
}): VerificationResult;
|
|
70
239
|
/** Export a date-ranged tamper-evident bundle. Range is inclusive on
|
|
71
240
|
* both ends. Verification still walks from genesis to ensure no gaps. */
|
|
72
241
|
export(opts: {
|
|
@@ -74,8 +243,15 @@ export declare class AuditLog {
|
|
|
74
243
|
range_end?: string;
|
|
75
244
|
}): AuditBundle;
|
|
76
245
|
/** Statically verify a previously-exported bundle (no DB required).
|
|
77
|
-
* Useful for the external auditor who only has the JSON file.
|
|
78
|
-
|
|
246
|
+
* Useful for the external auditor who only has the JSON file.
|
|
247
|
+
*
|
|
248
|
+
* The chain walk is the unchanged 6.x structure — it never parses
|
|
249
|
+
* signatures, so mixed v1/v2 bundles verify exactly as they did under 6.x.
|
|
250
|
+
* v7 F2 (T010): optional `publicKeys` adds the signature-layer check, same
|
|
251
|
+
* as the instance `verify()`. */
|
|
252
|
+
static verifyBundle(bundle: AuditBundle, opts?: {
|
|
253
|
+
publicKeys?: string[];
|
|
254
|
+
}): VerificationResult;
|
|
79
255
|
/** Slim query for recent entries — UI / dashboards. */
|
|
80
256
|
recent(limit?: number, kind?: string): AuditEntry[];
|
|
81
257
|
}
|
package/dist/audit.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":"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"}
|