kodelyth-ecc 1.8.0 → 1.8.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.
Files changed (91) hide show
  1. package/CLAUDE.md +1 -1
  2. package/VERSION +1 -1
  3. package/bin/kodelyth-ecc.js +54 -5
  4. package/install.ps1 +30 -13
  5. package/install.sh +11 -4
  6. package/package.json +1 -1
  7. package/rules/common/agent-intent-routing.md +96 -195
  8. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -47
  9. package/.github/ISSUE_TEMPLATE/config.yml +0 -8
  10. package/.github/ISSUE_TEMPLATE/feature_request.md +0 -41
  11. package/.github/ISSUE_TEMPLATE/good_first_issue.md +0 -36
  12. package/.github/ISSUE_TEMPLATE/new_agent.md +0 -52
  13. package/.github/PULL_REQUEST_TEMPLATE.md +0 -53
  14. package/.github/workflows/ci.yml +0 -45
  15. package/.github/workflows/publish.yml +0 -60
  16. package/brand/concepts.svg +0 -109
  17. package/brand/convert.js +0 -161
  18. package/brand/favicon.svg +0 -7
  19. package/brand/fb-cover.svg +0 -34
  20. package/brand/fb-profile.svg +0 -21
  21. package/brand/kodelyth-dark.svg +0 -24
  22. package/brand/kodelyth-light.svg +0 -24
  23. package/brand/kodelyth-mark.svg +0 -20
  24. package/brand/package.json +0 -12
  25. package/docs/dashboard.md +0 -211
  26. package/docs/evolve.md +0 -303
  27. package/docs/mcp-clients.md +0 -167
  28. package/docs/mcp.md +0 -178
  29. package/docs/replay.md +0 -244
  30. package/docs/supply-chain.md +0 -207
  31. package/docs/swarm.md +0 -243
  32. package/skills/skill-comply/tests/test_grader.py +0 -137
  33. package/skills/skill-comply/tests/test_parser.py +0 -90
  34. package/social/card-agents.svg +0 -104
  35. package/social/card-install.svg +0 -58
  36. package/social/card-main.svg +0 -54
  37. package/social/facebook-v150.svg +0 -110
  38. package/social/fb-ad-main.svg +0 -128
  39. package/social/fb-post-features.svg +0 -118
  40. package/social/fb-post-launch.svg +0 -144
  41. package/social/fb-post-platforms.svg +0 -135
  42. package/social/github-social-preview.svg +0 -151
  43. package/social/hype-compound-learning.svg +0 -129
  44. package/social/hype-devil-mode.svg +0 -240
  45. package/social/hype-mcp-server.svg +0 -148
  46. package/social/hype-parallel-agents.svg +0 -162
  47. package/social/hype-stats-hero.svg +0 -138
  48. package/social/og-image.svg +0 -151
  49. package/social/readme-agents.svg +0 -138
  50. package/social/readme-hero.svg +0 -102
  51. package/social/section-agents.svg +0 -69
  52. package/social/section-author.svg +0 -66
  53. package/social/section-dashboard.svg +0 -71
  54. package/social/section-devil.svg +0 -66
  55. package/social/section-hooks.svg +0 -63
  56. package/social/section-install.svg +0 -54
  57. package/social/section-learning.svg +0 -64
  58. package/social/section-mcp.svg +0 -58
  59. package/social/section-memory.svg +0 -69
  60. package/social/section-parallel.svg +0 -84
  61. package/social/section-routing.svg +0 -63
  62. package/social/twitter-threads.md +0 -621
  63. package/social/x-card-agents-grid.svg +0 -120
  64. package/social/x-card-free.svg +0 -71
  65. package/social/x-card-hook.svg +0 -94
  66. package/tests/dashboard/data.test.js +0 -391
  67. package/tests/dashboard/server.test.js +0 -257
  68. package/tests/evolve/analyze.test.js +0 -169
  69. package/tests/evolve/proposals.test.js +0 -173
  70. package/tests/evolve/stats.test.js +0 -167
  71. package/tests/hooks/branch-name-check.test.js +0 -184
  72. package/tests/hooks/smart-suggest.test.js +0 -149
  73. package/tests/hooks/test-reminder.test.js +0 -181
  74. package/tests/mcp/catalog.test.js +0 -98
  75. package/tests/mcp/client.test.js +0 -113
  76. package/tests/mcp/resources-prompts.test.js +0 -70
  77. package/tests/mcp/tools.test.js +0 -159
  78. package/tests/memory/auto-recall.test.js +0 -132
  79. package/tests/memory/instincts.test.js +0 -258
  80. package/tests/memory/store.test.js +0 -203
  81. package/tests/replay/bundle.test.js +0 -181
  82. package/tests/replay/replay.test.js +0 -131
  83. package/tests/router/classify.test.js +0 -164
  84. package/tests/run-all.js +0 -55
  85. package/tests/safety/patterns.test.js +0 -94
  86. package/tests/safety/prompt-injection-guard.test.js +0 -111
  87. package/tests/safety/token-budget.test.js +0 -119
  88. package/tests/supply-chain/manifest.test.js +0 -147
  89. package/tests/supply-chain/sbom.test.js +0 -170
  90. package/tests/supply-chain/verify.test.js +0 -146
  91. package/tests/swarm/build-plan.test.js +0 -188
package/docs/mcp.md DELETED
@@ -1,178 +0,0 @@
1
- # Kodelyth ECC — MCP Server
2
-
3
- The Kodelyth ECC MCP (Model Context Protocol) server is the **universal adapter** that lets any MCP-compatible client consume the full ECC stack: 70 agents, 194 skills, 97 commands, 14 rules, 3 power bundles, and the local BM25 self-learning memory.
4
-
5
- If you've ever wished LangGraph, AutoGen, CrewAI, OpenAI Agents SDK, Claude Desktop, or any other agent framework could speak ECC natively — this is that bridge.
6
-
7
- Local-only, zero telemetry, stdio transport.
8
-
9
- ---
10
-
11
- ## Quick start
12
-
13
- ### 1. Run the server
14
-
15
- ```bash
16
- # From npm (recommended):
17
- npx kodelyth-ecc mcp
18
-
19
- # From this repo:
20
- node scripts/mcp/server.js
21
- ```
22
-
23
- The server speaks JSON-RPC over **stdio**. It stays alive until stdin closes.
24
-
25
- You'll see one stderr banner on boot, e.g.:
26
-
27
- ```
28
- [kodelyth-mcp] ready · 1.7.0 · 16 tools · 6 prompts · 365 resources
29
- ```
30
-
31
- ### 2. Wire it into your MCP client
32
-
33
- #### Claude Desktop (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS)
34
-
35
- ```json
36
- {
37
- "mcpServers": {
38
- "kodelyth-ecc": {
39
- "command": "npx",
40
- "args": ["-y", "kodelyth-ecc", "mcp"]
41
- }
42
- }
43
- }
44
- ```
45
-
46
- #### Cursor / Windsurf / any MCP-aware IDE
47
-
48
- Use the same `command` + `args` pattern under whatever the IDE's MCP server config key is.
49
-
50
- #### Programmatic clients (LangGraph, AutoGen, CrewAI, OpenAI Agents SDK, custom)
51
-
52
- Spawn the server as a subprocess and connect via the official MCP client SDK for your language. The transport is **stdio JSON-RPC** — every spec-compliant client supports it.
53
-
54
- ---
55
-
56
- ## What it exposes
57
-
58
- ### Tools (16)
59
-
60
- | Name | Purpose |
61
- |---|---|
62
- | `route_intent` | Suggest the best ECC agent for a user message via token-overlap. Pair with the `routing-rule` prompt for full tier-based routing. |
63
- | `list_agents` | List every ECC agent (name, description, relpath). |
64
- | `list_skills` | List every ECC skill. |
65
- | `list_commands` | List every slash command. |
66
- | `list_rules` | List every rule file in `rules/common/`. |
67
- | `list_bundles` | List the power bundles (indie-hacker, red-team, enterprise). |
68
- | `get_agent` | Fetch the full markdown body of one agent. |
69
- | `get_skill` | Fetch the full markdown body of one skill. |
70
- | `get_command` | Fetch the full markdown body of one slash command (with or without leading `/`). |
71
- | `get_rule` | Fetch a rule file body. |
72
- | `get_bundle` | Fetch a bundle cheat sheet body. |
73
- | `recall_memory` | BM25 search across the local Kodelyth memory store. |
74
- | `capture_memory` | Append a new memory entry (problem + approach + tags). |
75
- | `memory_stats` | Summary of the local memory store. |
76
- | `catalog_stats` | Summary of how many agents/skills/commands/rules/bundles are loaded. |
77
- | `audit_skill_match` | Suggest skills whose description/body overlap a task — useful for deciding which skills to attach as context. |
78
-
79
- All tool results follow the MCP `{ content: [{ type: 'text', text: ... }], isError? }` shape. Most return JSON-encoded payloads inside the text channel.
80
-
81
- ### Prompts (6)
82
-
83
- Prompts let clients summon canonical ECC context blocks by name, no tool call needed.
84
-
85
- | Name | Returns |
86
- |---|---|
87
- | `routing-rule` | The full ECC intent routing rule (10-tier priority system). |
88
- | `agents-overview` | Compact list of all 70 agents with one-line descriptions. |
89
- | `skills-overview` | Compact list of all 194 skills. |
90
- | `commands-overview` | Compact list of all 97 slash commands. |
91
- | `handoff-chains` | The `agent-handoff` skill body — standard multi-agent chains for new feature, bug fix, refactor, incident, etc. |
92
- | `devil-mode` | The `/devil-mode` parallel command — fires the adversarial red-team crew. |
93
-
94
- ### Resources (365)
95
-
96
- Every agent, skill, command, rule, and bundle is also addressable as an MCP resource:
97
-
98
- ```
99
- kodelyth://agents/<name>
100
- kodelyth://skills/<name>
101
- kodelyth://commands/<name>
102
- kodelyth://rules/<name>
103
- kodelyth://bundles/<name>
104
- ```
105
-
106
- All resources are `text/markdown`. Use `resources/list` to discover, `resources/read` to fetch.
107
-
108
- ---
109
-
110
- ## Example session
111
-
112
- ```jsonc
113
- // → client
114
- { "jsonrpc": "2.0", "id": 1, "method": "initialize",
115
- "params": { "protocolVersion": "2024-11-05", "capabilities": {},
116
- "clientInfo": { "name": "my-client", "version": "0.1.0" } } }
117
-
118
- // ← server
119
- { "jsonrpc": "2.0", "id": 1, "result": {
120
- "protocolVersion": "2024-11-05",
121
- "capabilities": { "tools": {}, "resources": {}, "prompts": {} },
122
- "serverInfo": { "name": "kodelyth-ecc", "version": "1.7.0" } } }
123
-
124
- // → client
125
- { "jsonrpc": "2.0", "id": 2, "method": "tools/call",
126
- "params": { "name": "route_intent",
127
- "arguments": { "message": "production is down and i don't know why",
128
- "top_k": 3 } } }
129
-
130
- // ← server (paraphrased)
131
- { "result": { "content": [{ "type": "text", "text":
132
- "{ \"suggestions\": [
133
- { \"agent\": \"incident-commander\", ... },
134
- { \"agent\": \"debug-detective\", ... },
135
- { \"agent\": \"silent-failure-hunter\", ... }
136
- ] }" }] } }
137
- ```
138
-
139
- ---
140
-
141
- ## Design notes
142
-
143
- - **Pure file reads + memory passthrough.** The server adds no LLM calls of its own. It surfaces ECC context; your client's model decides what to do with it.
144
- - **No telemetry, no network egress.** stdio only. Local memory only. Reads from this repo's checked-in markdown.
145
- - **Lazy SDK load.** The MCP SDK is an `optionalDependency` so installs work without it; the `mcp` subcommand prints a friendly install hint if missing.
146
- - **Cached catalog.** Agent/skill/command lists are cached in-process after first read for sub-millisecond subsequent calls.
147
- - **Memory store is project-aware.** `recall_memory` accepts an optional `project_root` to scope BM25 results to memories captured against that project, falling back to global memories if scoped results are sparse.
148
-
149
- ---
150
-
151
- ## Privacy & safety
152
-
153
- - The server only reads files under this package and the local memory directory (default `~/.kodelyth/memory/`, override via `KODELYTH_MEMORY_DIR`).
154
- - It writes only when the client invokes `capture_memory`.
155
- - No network calls. No analytics. No phone-home.
156
- - The server never executes arbitrary commands or code. Tools that surface code (`get_agent`, etc.) return markdown documentation, not executable instructions.
157
-
158
- ---
159
-
160
- ## Troubleshooting
161
-
162
- **"Kodelyth MCP server requires `@modelcontextprotocol/sdk`"** — run `npm install @modelcontextprotocol/sdk` once, or rerun via `npx -y kodelyth-ecc mcp` to let npm fetch optional deps.
163
-
164
- **Empty results from `recall_memory` on a fresh memory store** — BM25 needs a few documents before IDF scores rise above the default `minScore` floor. Capture 2-3 memories first.
165
-
166
- **Resources missing in your client UI** — some MCP clients render only tools and prompts. Resources are still queryable via `resources/list`.
167
-
168
- ---
169
-
170
- ## Roadmap interactions
171
-
172
- - **Phase 2.5 — MCP client mode** will add the inverse: ECC agents consuming external MCP servers (Stripe, GitHub, Postgres, Brave, etc.) — making ECC the MCP **hub**, not just a node.
173
- - **Phase 2.3 — local dashboard** will visualize live MCP traffic so you can see which tools/prompts/resources clients hit, in real time.
174
- - **Phase 2.10 — prompt-injection guardrail** will sit in front of MCP responses to scrub jailbreak patterns before they reach client models.
175
-
176
- ---
177
-
178
- Built into [Kodelyth ECC](../README.md). MIT licensed. PRs welcome.
package/docs/replay.md DELETED
@@ -1,244 +0,0 @@
1
- # Kodelyth ECC — Session Replay
2
-
3
- Bundle, share, and re-run swarm sessions for regression testing, reproducible bug reports, and A/B testing across harnesses, agents, and base refs.
4
-
5
- > **Phase 2.8 of the [Devil Roadmap](../README.md).** Companion to the swarm orchestrator (Phase 2.7) — every swarm coordination dir is portable, replayable, and diff-friendly.
6
-
7
- ---
8
-
9
- ## Why replay
10
-
11
- Three concrete wins:
12
-
13
- 1. **Reproducible bug reports.** Bundle a buggy swarm into a single JSON file, ship to maintainers. They `replay --execute` locally and see the same agent behavior.
14
- 2. **Regression testing.** Save a known-good baseline. After an agent prompt rev, replay against the new agent and diff handoffs. Did quality regress?
15
- 3. **Model A/B testing.** Same task, two harnesses. Side-by-side handoff comparison reveals which model handles the swarm better for your codebase.
16
-
17
- ---
18
-
19
- ## CLI
20
-
21
- | Command | Purpose |
22
- |---|---|
23
- | `kodelyth-ecc session-export <session> [flags]` | Bundle a coordination dir to JSON. |
24
- | `kodelyth-ecc session-import <bundle.json> [flags]` | Restore a bundle to a coordination dir. |
25
- | `kodelyth-ecc replay <bundle\|session> [flags]` | Re-run a session with variations. |
26
-
27
- ### `session-export`
28
-
29
- ```bash
30
- kodelyth-ecc session-export <session> \
31
- [--out file.json] \
32
- [--task "..."] [--agents a,b,c] [--harness claude] [--base-ref HEAD] \
33
- [--coord-root <dir>]
34
- ```
35
-
36
- | Flag | Description |
37
- |---|---|
38
- | `<session>` | Required. Directory name under `.orchestration/`. |
39
- | `--out` | Output JSON path. Default: `.orchestration/<session>.bundle.json`. |
40
- | `--task "..."` | Enrich `meta.task` for cleaner replays. |
41
- | `--agents a,b,c` | Enrich `meta.agents`. |
42
- | `--harness <h>` | Enrich `meta.harness`. |
43
- | `--base-ref <ref>` | Enrich `meta.base_ref`. |
44
- | `--coord-root` | Where to look for coordination dirs (default: `<repo>/.orchestration`). |
45
-
46
- ### `session-import`
47
-
48
- ```bash
49
- kodelyth-ecc session-import <bundle.json> \
50
- [--target <dir>] [--overwrite] \
51
- [--coord-root <dir>]
52
- ```
53
-
54
- | Flag | Description |
55
- |---|---|
56
- | `<bundle.json>` | Required. Bundle to restore. |
57
- | `--target` | Output directory. Default: `.orchestration/<session-from-bundle>`. |
58
- | `--overwrite` | Replace any existing target dir. |
59
-
60
- ### `replay`
61
-
62
- ```bash
63
- kodelyth-ecc replay <bundle.json|session-name> \
64
- [--harness h] [--agents a,b,c] [--base-ref ref] [--session NAME] [--replace] \
65
- [--execute|--write-only|--json]
66
- ```
67
-
68
- | Flag | Description |
69
- |---|---|
70
- | `<target>` | Required. Bundle file (ends in `.json`) or session name in `.orchestration/`. |
71
- | `--harness` | Override launcher harness. |
72
- | `--agents` | Replace the agent list. |
73
- | `--base-ref` | Branch base for replay worktrees. |
74
- | `--session` | Override auto-generated `-replay-N` name. |
75
- | `--replace` | Tear down any existing session/worktrees with the same names. |
76
- | `--execute` | Actually spawn worktrees + tmux + agents. |
77
- | `--write-only` | Just materialize coordination files. |
78
- | `--json` | Print plan + planConfig. |
79
-
80
- Default mode is **dry-run**. Always inspect first.
81
-
82
- ---
83
-
84
- ## Bundle format
85
-
86
- Stable schema `kodelyth.session-bundle/v1`. Single JSON file:
87
-
88
- ```json
89
- {
90
- "schema": "kodelyth.session-bundle/v1",
91
- "session": "swarm-2026-05-10-4a",
92
- "exported_at": "2026-05-10T17:30:00Z",
93
- "exported_by": "kodelyth-ecc@1.7.0",
94
- "meta": {
95
- "task": "audit oauth flow",
96
- "agents": ["security-reviewer", "code-reviewer", "pair-programmer", "tdd-guide"],
97
- "harness": "claude",
98
- "base_ref": "HEAD"
99
- },
100
- "workers": [
101
- { "slug": "code-reviewer", "task": "...", "handoff": "...", "status": "..." },
102
- { "slug": "pair-programmer", "task": "...", "handoff": "...", "status": "..." },
103
- { "slug": "security-reviewer", "task": "...", "handoff": "...", "status": "..." },
104
- { "slug": "tdd-guide", "task": "...", "handoff": "...", "status": "..." }
105
- ]
106
- }
107
- ```
108
-
109
- Pure JSON. No archives, no binaries. Diff-friendly for `git diff` review of regression bundles.
110
-
111
- ---
112
-
113
- ## How replay reconstructs the task
114
-
115
- 1. **Prefer `meta.task`** if the bundle was exported with `--task "..."`.
116
- 2. **Fallback: parse the first worker's `task.md`** for the `## Shared Task` section (the agent-shaped header from `scripts/swarm/build-plan.js`).
117
- 3. **Final fallback: parse the orchestrator's own `## Objective` block** (works for hand-written tasks).
118
-
119
- This means replay works even on bundles that pre-date the `--task` flag — the heuristic recovers the shared task from the first worker.
120
-
121
- ---
122
-
123
- ## Replay variations
124
-
125
- | Want to test | Flags |
126
- |---|---|
127
- | Same task, different model | `--harness claude` vs `--harness codex` (or vary `KODELYTH_ROUTER_*`) |
128
- | Same task, different agents | `--agents new1,new2,new3` |
129
- | Same task, new code | `--base-ref refactor-branch` |
130
- | Custom session name | `--session my-replay-1` |
131
- | Inspect plan only | (default — dry-run) |
132
- | Just write coordination files | `--write-only` |
133
- | Full execute | `--execute` |
134
-
135
- ---
136
-
137
- ## Hard rules
138
-
139
- 1. **Never `--execute` without inspecting the dry-run.** Worktrees mutate disk.
140
- 2. **Replays are auto-named** (`-replay-N`) to avoid collisions. Don't manually reuse the origin name.
141
- 3. **Bundles are public artifacts** — strip secrets before sharing externally. Use `opensource-sanitizer` if needed.
142
- 4. **A/B comparisons require human review.** Never auto-pick a "winner" between two replays.
143
- 5. **Don't replay across incompatible base refs.** A swarm built against `main` may break if replayed against `feature-branch` with conflicting changes.
144
-
145
- ---
146
-
147
- ## Pairing with the rest of ECC
148
-
149
- | Pairs with | How |
150
- |---|---|
151
- | **2.7 swarm orchestrator** | Replay only works on swarm coordination dirs. The two ship together. |
152
- | **2.4 cost router** | Vary `KODELYTH_ROUTER_*` env vars across replays for A/B model tests. |
153
- | **2.10 token-budget hook** | Replays open new sessions with fresh budgets — no spillover from the origin. |
154
- | **2.5 MCP client mode** | Replays inherit the same MCP registry, so tool calls reproduce. |
155
- | **opensource-sanitizer** | Run on a bundle before sharing externally. |
156
-
157
- ---
158
-
159
- ## Examples
160
-
161
- ### Reproducible bug report
162
-
163
- ```bash
164
- # 1. Capture the buggy run
165
- npx kodelyth-ecc swarm --task "..." --execute
166
-
167
- # 2. After it finishes, export with rich meta
168
- npx kodelyth-ecc session-export swarm-2026-05-10-4a \
169
- --task "..." --agents code-reviewer,security-reviewer --harness claude \
170
- --out bug-report.bundle.json
171
-
172
- # 3. Strip secrets if needed
173
- # (manually edit bug-report.bundle.json)
174
-
175
- # 4. Ship to maintainers
176
- gh issue create --body "Reproducer attached: bug-report.bundle.json"
177
- ```
178
-
179
- ### Model A/B test
180
-
181
- ```bash
182
- # Run with claude
183
- npx kodelyth-ecc swarm --task "refactor payments module" --agents 4 --harness claude --execute
184
- npx kodelyth-ecc session-export swarm-... --out claude-run.bundle.json
185
-
186
- # Replay with codex against the same task
187
- npx kodelyth-ecc replay claude-run.bundle.json --harness codex --execute
188
- npx kodelyth-ecc session-export swarm-...-replay-1 --out codex-run.bundle.json
189
-
190
- # Compare handoffs
191
- diff <(jq -r '.workers[] | "\(.slug):\n\(.handoff)"' claude-run.bundle.json) \
192
- <(jq -r '.workers[] | "\(.slug):\n\(.handoff)"' codex-run.bundle.json)
193
- ```
194
-
195
- ### Regression check after agent rev
196
-
197
- ```bash
198
- # 1. Save a baseline.
199
- npx kodelyth-ecc session-export swarm-baseline --out baseline.bundle.json
200
-
201
- # 2. After updating an agent prompt, replay.
202
- npx kodelyth-ecc replay baseline.bundle.json --execute
203
- npx kodelyth-ecc session-export swarm-baseline-replay-1 --out replay.bundle.json
204
-
205
- # 3. Inspect the diff manually — has quality regressed?
206
- diff <(jq -r '.workers[] | "\(.slug)\n\(.handoff)"' baseline.bundle.json) \
207
- <(jq -r '.workers[] | "\(.slug)\n\(.handoff)"' replay.bundle.json)
208
- ```
209
-
210
- ---
211
-
212
- ## Programmatic use
213
-
214
- ```js
215
- const bundleLib = require('kodelyth-ecc/scripts/replay/bundle.js');
216
- const replayLib = require('kodelyth-ecc/scripts/replay/replay.js');
217
- const { buildOrchestrationPlan, executePlan } = require('kodelyth-ecc/scripts/lib/tmux-worktree-orchestrator.js');
218
-
219
- // Read a bundle
220
- const bundle = bundleLib.readBundle('./oauth-audit.bundle.json');
221
-
222
- // Build a replay plan with overrides
223
- const planConfig = replayLib.buildReplayPlanConfig(bundle, {
224
- harness: 'codex',
225
- baseRef: 'main',
226
- });
227
-
228
- // Execute
229
- const plan = buildOrchestrationPlan(planConfig);
230
- const result = executePlan(plan);
231
- console.log(`replay started: ${result.sessionName}`);
232
- ```
233
-
234
- ---
235
-
236
- ## Roadmap interactions
237
-
238
- - **Phase 2.3 — local dashboard** will surface replay history and side-by-side handoff diffs for the same task across runs.
239
- - **Phase 2.6 — sandbox layer** will isolate replay execution in Docker so re-running an external bundle doesn't trust the source.
240
- - **Phase 2.2 — SWE-Bench harness** will use bundle replay as its evaluation primitive.
241
-
242
- ---
243
-
244
- Built into [Kodelyth ECC](../README.md). MIT licensed.
@@ -1,207 +0,0 @@
1
- # Supply chain — SBOM, manifest, SLSA provenance
2
-
3
- > Phase 2.9 of the Devil Roadmap. Every kodelyth-ecc release ships with three independent supply-chain artifacts so any consumer (audit team, downstream agent, security tool) can answer "where does this code come from, can I trust it, and has it been tampered" without trusting kodelyth-ecc.
4
-
5
- ---
6
-
7
- ## What ships with every release
8
-
9
- | Artifact | Format | Where to find it | Issued by |
10
- |---|---|---|---|
11
- | **SLSA build provenance** | sigstore-signed npm provenance | npmjs.com/package/kodelyth-ecc → "Provenance" tab | npm + GitHub OIDC (`npm publish --provenance`) |
12
- | **CycloneDX SBOM** | CycloneDX 1.5 JSON | GitHub release page → `kodelyth-ecc-sbom.cdx.json` | `kodelyth-ecc sbom` |
13
- | **Content manifest** | sha256 manifest JSON | GitHub release page → `kodelyth-ecc-manifest.json` | `kodelyth-ecc manifest` |
14
-
15
- All three are emitted by `.github/workflows/publish.yml` on every tagged release.
16
-
17
- ---
18
-
19
- ## CLI
20
-
21
- ### `kodelyth-ecc sbom`
22
-
23
- ```
24
- kodelyth-ecc sbom [--root DIR] [--out FILE] [--json]
25
- ```
26
-
27
- Generates a CycloneDX 1.5 software bill of materials.
28
-
29
- | Field | Source | Notes |
30
- |---|---|---|
31
- | `metadata.component` | `package.json` | The kodelyth-ecc package itself |
32
- | `components[]` | `package-lock.json` v3 | One entry per locked dependency, including dev + transitive |
33
- | `purl` | `pkg:npm/<name>@<version>` | scoped packages keep the leading `@` |
34
- | `licenses` | lockfile `license` | normalized to CycloneDX shape |
35
- | `hashes` | npm SRI (`integrity`) | base64 → hex, algo mapped to `SHA-256/384/512` |
36
- | `dependencies[]` | root entry's `dependencies` + `optionalDependencies` | Direct edges only |
37
- | `serialNumber` | `urn:uuid:<sha256("name@version|timestamp")>` | Stable for same inputs |
38
-
39
- **Pure function. No network. No exec.**
40
-
41
- ### `kodelyth-ecc manifest`
42
-
43
- ```
44
- kodelyth-ecc manifest [--root DIR] [--out FILE] [--json]
45
- ```
46
-
47
- Generates a sha256 content manifest of every shipped asset.
48
-
49
- ```json
50
- {
51
- "schema": "kodelyth.content-manifest/v1",
52
- "package": "kodelyth-ecc",
53
- "pkg_version": "1.7.0",
54
- "generated_at": "2026-05-10T17:00:00Z",
55
- "file_count": 730,
56
- "digest": "20813125…",
57
- "files": [
58
- { "path": "agents/code-reviewer.md", "size": 4521, "sha256": "…" }
59
- ]
60
- }
61
- ```
62
-
63
- Walks: `agents/`, `skills/`, `commands/`, `rules/`, `hooks/`, `scripts/`, `bin/`, `parallel-commands/`, `bundles/`, plus root files (`package.json`, `README.md`, `CHANGELOG.md`, `VERSION`, `install.sh`, `install.ps1`).
64
-
65
- Skips: `node_modules/`, `.git/`, `.DS_Store`, `__pycache__/`, `*.pyc`.
66
-
67
- The top-level `digest` is the sha256 over the deterministic JSON of `files[]`. Two runs against the same source state produce the same digest.
68
-
69
- ### `kodelyth-ecc verify`
70
-
71
- ```
72
- kodelyth-ecc verify [--root DIR] [--manifest FILE] [--json]
73
- ```
74
-
75
- Compares disk against the manifest:
76
-
77
- | Category | Means | Fails verify? |
78
- |---|---|---|
79
- | `ok` | sha256 matches | No |
80
- | `modified` | hash differs | **Yes** |
81
- | `missing` | not on disk | **Yes** |
82
- | `extra` | on disk but not in manifest | No (advisory) |
83
-
84
- Exits `0` on `ok=true`, `1` otherwise. With `--json`, prints the full report:
85
-
86
- ```json
87
- {
88
- "ok": false,
89
- "summary": { "total_in_manifest": 730, "ok": 729, "modified": 1, "missing": 0, "extra": 0 },
90
- "details": {
91
- "ok": ["agents/api-guardian.md", …],
92
- "modified": [{ "path": "agents/code-reviewer.md", "expected_sha256": "…", "actual_sha256": "…" }],
93
- "missing": [],
94
- "extra": []
95
- }
96
- }
97
- ```
98
-
99
- ---
100
-
101
- ## Verifying a downstream install
102
-
103
- ```bash
104
- # 1) Download the manifest from the GitHub release that matches your installed version.
105
- gh release download v1.7.3 -p kodelyth-ecc-manifest.json -O /tmp/manifest.json
106
-
107
- # 2) Run verify against your installed copy.
108
- npx kodelyth-ecc verify --root "$(npm root -g)/kodelyth-ecc" --manifest /tmp/manifest.json
109
- ```
110
-
111
- Or, if you cloned the repo:
112
-
113
- ```bash
114
- cd ~/path/to/kodelyth-ecc
115
- node bin/kodelyth-ecc.js verify --manifest /tmp/manifest.json
116
- ```
117
-
118
- A successful run looks like:
119
-
120
- ```
121
- Kodelyth ECC supply-chain verify
122
- package: kodelyth-ecc@1.7.0
123
- manifest digest: 20813125baad127bb578e4cbad6b72e2c4721d71cd236b6c039e7c155cd322ef
124
- files in manifest: 730
125
- ✓ ok: 730
126
- ✗ modified: 0
127
- ✗ missing: 0
128
- ⚠ extra: 0 (advisory)
129
-
130
- ✓ verify OK
131
- ```
132
-
133
- ---
134
-
135
- ## SLSA provenance
136
-
137
- `.github/workflows/publish.yml` runs `npm publish --provenance --access public`. This requires `id-token: write` (set on the job) and uses GitHub's OIDC token to sign a sigstore-backed provenance statement that:
138
-
139
- 1. Pins the workflow file SHA + commit SHA that produced the build.
140
- 2. Pins the GitHub repo + ref.
141
- 3. Pins the npm package name + version.
142
-
143
- Result: **SLSA Level 3** by npm's published criteria (hosted build platform, signed provenance, verifiable from npm registry metadata).
144
-
145
- To verify a downloaded tarball matches the npm-published provenance:
146
-
147
- ```bash
148
- npm audit signatures kodelyth-ecc
149
- # or
150
- npm view kodelyth-ecc --json | jq .dist.signatures
151
- ```
152
-
153
- ---
154
-
155
- ## Programmatic API
156
-
157
- ```js
158
- const { generateSBOM } = require('kodelyth-ecc/scripts/supply-chain/sbom.js');
159
- const { generateManifest } = require('kodelyth-ecc/scripts/supply-chain/manifest.js');
160
- const { verifyAgainstManifest } = require('kodelyth-ecc/scripts/supply-chain/verify.js');
161
-
162
- const bom = generateSBOM({ rootDir });
163
- const manifest = generateManifest({ rootDir });
164
- const report = verifyAgainstManifest({ rootDir, manifest });
165
- ```
166
-
167
- All three are pure functions. Safe to call from a CI step, an MCP tool, or any external automation. They never spawn subprocesses, never make network calls, and never write to disk.
168
-
169
- ---
170
-
171
- ## When to call which surface
172
-
173
- | Situation | Use |
174
- |---|---|
175
- | Compliance team wants an SBOM for Dependency-Track / Snyk ingestion | `sbom --out` |
176
- | Need to ship a tamper-detection seal with a release artifact | `manifest --out` |
177
- | Validating a downstream install hasn't been edited | `verify` |
178
- | CI gate that should fail on tamper | `verify --json` + script that checks `.ok` |
179
- | Reproducibility check between two release archives | `manifest` on both, diff `digest` |
180
-
181
- ---
182
-
183
- ## Composition with other phases
184
-
185
- | Pair | Effect |
186
- |---|---|
187
- | **2.7 swarm + verify** | Run `verify` as a pre-flight before spawning workers. Refuse to spawn from a tampered toolkit. |
188
- | **2.8 replay + manifest** | Embed the manifest digest of the producing toolkit into a session bundle. Replays then verify they're being run by the same toolkit version. |
189
- | **2.10 safety hooks + verify** | The token-budget hook can read the manifest digest at session start to surface a "you're running tampered tooling" warning. |
190
- | **2.1 MCP server + verify** | Expose `verify` as an MCP tool. Downstream agents can call it before trusting any other ECC tool's output. |
191
-
192
- ---
193
-
194
- ## Hard rules
195
-
196
- 1. Treat the manifest published with a release as authoritative. **Do not** regenerate locally and pretend it's the same.
197
- 2. **Do not** suppress a non-zero exit from `verify` in CI. Modified or missing files mean a tamper or a partial install — both are blocking.
198
- 3. **Do not** include `node_modules/` or `.git/` in the manifest. The skip list is in `scripts/supply-chain/manifest.js`; extend deliberately if needed.
199
- 4. **Do not** store secrets in any file under the shipped directory list. Anything that's manifested gets its sha256 published.
200
-
201
- ---
202
-
203
- ## See also
204
-
205
- - `skills/supply-chain-verification/SKILL.md` — explicit-invocation skill
206
- - `commands/verify-supply-chain.md` — `/verify-supply-chain` slash command
207
- - `.github/workflows/publish.yml` — release pipeline (npm provenance + SBOM + manifest upload)