wicked-garden 12.52.1 → 12.53.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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +11 -0
- package/package.json +1 -1
- package/scripts/_estate_client.py +3 -6
- package/scripts/qe/lib/campaign-scoreboard.mjs +3 -47
- package/scripts/qe/lib/gate.mjs +3 -38
- package/scripts/qe/lib/ledger-pkg.mjs +74 -0
- package/skills/learn/SKILL.md +2 -2
- package/skills/qe/refs/accept.md +20 -6
- package/skills/repo-learn/SKILL.md +3 -5
- package/skills/repo-learn/refs/capture-proposals.md +4 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name": "wicked-garden", "owner": {"name": "Mike Parcewski"}, "plugins": [{"name": "wicked-garden", "source": "./", "description": "Your coding agent already plans and swarms \u2014 Wicked Garden is the curated toolkit for what it can't: proof-not-claims gates, code links grep can't see, deterministic refactor, cross-session memory, multi-model second opinions (fallback seats labelled). Don't fight the harness; fill its gaps. The gate needs wicked-vault (a self-contained infra peer, installed directly) and re-derives through garden's built-in engine; estate/bus are opt-in layers (wicked-testing and wicked-brain are retired \u2014 QE ships in-catalog as the qe domain, memory lives in wicked-estate).", "version": "12.
|
|
1
|
+
{"name": "wicked-garden", "owner": {"name": "Mike Parcewski"}, "plugins": [{"name": "wicked-garden", "source": "./", "description": "Your coding agent already plans and swarms \u2014 Wicked Garden is the curated toolkit for what it can't: proof-not-claims gates, code links grep can't see, deterministic refactor, cross-session memory, multi-model second opinions (fallback seats labelled). Don't fight the harness; fill its gaps. The gate needs wicked-vault (a self-contained infra peer, installed directly) and re-derives through garden's built-in engine; estate/bus are opt-in layers (wicked-testing and wicked-brain are retired \u2014 QE ships in-catalog as the qe domain, memory lives in wicked-estate).", "version": "12.53.1"}], "version": "12.53.1"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wicked-garden",
|
|
3
|
-
"version": "12.
|
|
3
|
+
"version": "12.53.1",
|
|
4
4
|
"description": "Your coding agent's harness already plans and swarms; Wicked Garden is the curated toolkit for what it can't do alone. Proof, not claims \u2014 gates re-derive 'done' through the internal loom engine (fail-closed, independently attested via wicked-vault), so a self-asserted pass can't lie its way green. Relationships grep can't see \u2014 the wicked-estate code graph + injected bus/dispatch/capability/archetype edges power blast-radius & lineage. Plus deterministic multi-file refactor (wicked-patch), cross-session memory + knowledge (the mem domain over wicked-estate), multi-model second opinions (fallback seats labelled) (jam:council), portable expertise as on-demand skill-refs, and evidence-gated testing (the in-catalog qe domain). It reads the shape of your work to apply the right rigor \u2014 steering, not a pipeline \u2014 then gets out of the way. The compiler stamps a self-contained evidence gate into any repo that runs with no wicked-garden installed. Don't fight the harness; fill its gaps. The evidence gate requires wicked-vault, a self-contained infra peer wicked-garden installs directly; wicked-bus is an opt-in layer \u2014 install what you'll use, the toolkit works without the rest.",
|
|
5
5
|
"wicked_vault_version": "^0.5.0",
|
|
6
6
|
"wicked_ledger_version": "^0.6.0",
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [12.53.1] — 2026-10-11
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
- **One wicked-ledger resolver, `$WICKED_LEDGER_PKG_DIR` first (PR #1284, crew#951).** `wicked-garden-qe` accept, the gate and the campaign scoreboard resolve wicked-ledger through one resolver that honours `$WICKED_LEDGER_PKG_DIR` first (wicked-crew 0.9.7 sets it for a governed run), so a governed QE unit records its verdict without the repository installing wicked-ledger.
|
|
9
|
+
- **Learn: the author computes claim ids (PR #1288, E2E F-LEARN-1);** synthesize leaves them.
|
|
10
|
+
|
|
11
|
+
## [12.53.0] — 2026-10-11
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
- **Learned code facts are filed as knowledge, not memory (PR #1285).** repo-learn submits code facts as knowledge proposals, and the shim lifts its refusal of `kind_type: "knowledge"` and requires each proposal's `source`. Needs wicked-estate 0.29.2+ (estate K3, the knowledge-proposal type); an older estate refuses the proposal.
|
|
15
|
+
|
|
5
16
|
## [12.52.1] — 2026-10-11
|
|
6
17
|
|
|
7
18
|
### Changed
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wicked-garden",
|
|
3
|
-
"version": "12.
|
|
3
|
+
"version": "12.53.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Curated toolkit for what AI coding agents can't do alone: evidence-gated work, codegraph relationships, deterministic multi-file refactor, multi-model second opinions, and cross-session memory. Installs as a Claude Code plugin.",
|
|
6
6
|
"keywords": [
|
|
@@ -1102,13 +1102,10 @@ def propose(
|
|
|
1102
1102
|
run's `WICKED_RUN_PROJECT` supplies): an unscoped proposal is refused here
|
|
1103
1103
|
with the shape-error code, so it never lands project-less in the queue.
|
|
1104
1104
|
"""
|
|
1105
|
-
if kind_type == "knowledge":
|
|
1106
|
-
#
|
|
1107
|
-
# so a knowledge proposal would strand in the queue. Lift when estate ships the type.
|
|
1105
|
+
if kind_type == "knowledge" and not (isinstance(payload, dict) and str(payload.get("source") or "").strip()):
|
|
1106
|
+
# DES-memory-vs-knowledge K3 (estate 0.29.2): knowledge is acquired, so it names its source.
|
|
1108
1107
|
return {"ok": False, "code": -32602,
|
|
1109
|
-
"reason": '
|
|
1110
|
-
'memory and policy:*): keep the object in your report under '
|
|
1111
|
-
'"knowledge (pending)"; do not re-file it as a memory'}
|
|
1108
|
+
"reason": 'a knowledge proposal needs payload.source (where it was read, e.g. "<repo>:<path>")'}
|
|
1112
1109
|
facets = _scope_facets_to_run_project(facets)
|
|
1113
1110
|
project = (facets or {}).get("project")
|
|
1114
1111
|
if not isinstance(project, str) or not project.strip():
|
|
@@ -93,6 +93,7 @@
|
|
|
93
93
|
import { existsSync, readdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
94
94
|
import { join, dirname, resolve, isAbsolute } from "node:path";
|
|
95
95
|
import { pathToFileURL } from "node:url";
|
|
96
|
+
import { resolveLedgerModule } from "./ledger-pkg.mjs";
|
|
96
97
|
import { parseArgs } from "node:util";
|
|
97
98
|
|
|
98
99
|
import {
|
|
@@ -168,54 +169,9 @@ export function resolveLedgerRootLocal(repoRoot, env = process.env) {
|
|
|
168
169
|
return current;
|
|
169
170
|
}
|
|
170
171
|
|
|
171
|
-
// --- wicked-ledger resolution (
|
|
172
|
-
|
|
173
|
-
function esmEntryForPackageDir(pkgDir) {
|
|
174
|
-
const pj = join(pkgDir, "package.json");
|
|
175
|
-
if (!existsSync(pj)) return null;
|
|
176
|
-
const pkg = readJsonSafe(pj);
|
|
177
|
-
if (!pkg) return null;
|
|
178
|
-
const dot = pkg.exports && pkg.exports["."] !== undefined ? pkg.exports["."] : pkg.exports;
|
|
179
|
-
const rel =
|
|
180
|
-
(dot && typeof dot === "object" && (dot.import || dot.default)) ||
|
|
181
|
-
(typeof dot === "string" ? dot : null) ||
|
|
182
|
-
pkg.module ||
|
|
183
|
-
pkg.main ||
|
|
184
|
-
"index.js";
|
|
185
|
-
return join(pkgDir, rel);
|
|
186
|
-
}
|
|
172
|
+
// --- wicked-ledger resolution: the shared resolver (./ledger-pkg.mjs) -----------
|
|
187
173
|
|
|
188
|
-
export
|
|
189
|
-
// 1. explicit override (tests, TH-6 wiring, unpublished-floor installs)
|
|
190
|
-
if (env.WICKED_LEDGER_PKG_DIR) {
|
|
191
|
-
const entry = esmEntryForPackageDir(env.WICKED_LEDGER_PKG_DIR);
|
|
192
|
-
if (entry && existsSync(entry)) return await import(pathToFileURL(entry).href);
|
|
193
|
-
return null;
|
|
194
|
-
}
|
|
195
|
-
// 2. bare import (global / hoisted install)
|
|
196
|
-
try {
|
|
197
|
-
return await import("wicked-ledger");
|
|
198
|
-
} catch {
|
|
199
|
-
/* fall through */
|
|
200
|
-
}
|
|
201
|
-
// 3. walk up from the target repo root
|
|
202
|
-
let dir = resolve(repoRoot);
|
|
203
|
-
for (let i = 0; i < 10; i++) {
|
|
204
|
-
const cand = join(dir, "node_modules", "wicked-ledger");
|
|
205
|
-
const entry = esmEntryForPackageDir(cand);
|
|
206
|
-
if (entry && existsSync(entry)) {
|
|
207
|
-
try {
|
|
208
|
-
return await import(pathToFileURL(entry).href);
|
|
209
|
-
} catch {
|
|
210
|
-
return null;
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
const parent = dirname(dir);
|
|
214
|
-
if (parent === dir) break;
|
|
215
|
-
dir = parent;
|
|
216
|
-
}
|
|
217
|
-
return null;
|
|
218
|
-
}
|
|
174
|
+
export { resolveLedgerModule } from "./ledger-pkg.mjs";
|
|
219
175
|
|
|
220
176
|
// --- evidence extraction ------------------------------------------------------
|
|
221
177
|
|
package/scripts/qe/lib/gate.mjs
CHANGED
|
@@ -83,50 +83,15 @@ import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
|
83
83
|
import { join, dirname, isAbsolute } from "node:path";
|
|
84
84
|
import { spawnSync } from "node:child_process";
|
|
85
85
|
import { createHash } from "node:crypto";
|
|
86
|
-
import { createRequire } from "node:module";
|
|
87
86
|
import { pathToFileURL } from "node:url";
|
|
88
87
|
import { parseArgs } from "node:util";
|
|
89
88
|
|
|
90
89
|
import { buildExclusionsClause } from "./flake-policy.mjs";
|
|
91
90
|
import { resolveVaultModule, applyVaultIntegrity, VaultEvidenceError } from "./vault-evidence.mjs";
|
|
92
91
|
import { crewRunStamp } from "./crew-run.mjs";
|
|
92
|
+
import { resolveLedgerModule } from "./ledger-pkg.mjs";
|
|
93
93
|
|
|
94
|
-
// --- wicked-ledger resolution
|
|
95
|
-
|
|
96
|
-
function esmEntryForPackage(resolvedFile) {
|
|
97
|
-
let dir = dirname(resolvedFile);
|
|
98
|
-
for (let i = 0; i < 10; i++) {
|
|
99
|
-
const pj = join(dir, "package.json");
|
|
100
|
-
if (existsSync(pj)) {
|
|
101
|
-
let pkg;
|
|
102
|
-
try { pkg = JSON.parse(readFileSync(pj, "utf8")); } catch { return null; }
|
|
103
|
-
const dot = pkg.exports && pkg.exports["."] !== undefined ? pkg.exports["."] : pkg.exports;
|
|
104
|
-
const rel =
|
|
105
|
-
(dot && typeof dot === "object" && (dot.import || dot.default)) ||
|
|
106
|
-
(typeof dot === "string" ? dot : null) ||
|
|
107
|
-
pkg.module || pkg.main || "index.js";
|
|
108
|
-
return join(dir, rel);
|
|
109
|
-
}
|
|
110
|
-
const parent = dirname(dir);
|
|
111
|
-
if (parent === dir) break;
|
|
112
|
-
dir = parent;
|
|
113
|
-
}
|
|
114
|
-
return null;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
async function resolveLedgerModule(cwd) {
|
|
118
|
-
try {
|
|
119
|
-
return await import("wicked-ledger");
|
|
120
|
-
} catch { /* fall through */ }
|
|
121
|
-
try {
|
|
122
|
-
const require = createRequire(join(cwd, "__qe_gate_anchor__.js"));
|
|
123
|
-
const located = require.resolve("wicked-ledger");
|
|
124
|
-
const esm = esmEntryForPackage(located) || located;
|
|
125
|
-
return await import(pathToFileURL(esm).href);
|
|
126
|
-
} catch {
|
|
127
|
-
return null;
|
|
128
|
-
}
|
|
129
|
-
}
|
|
94
|
+
// --- wicked-ledger resolution: the shared resolver (./ledger-pkg.mjs, $WICKED_LEDGER_PKG_DIR first) ---
|
|
130
95
|
|
|
131
96
|
/**
|
|
132
97
|
* Resolve the ledger root the gate writes to (TH-6). MUST mirror the TH-2
|
|
@@ -357,7 +322,7 @@ export async function runGate({ projectId, runId, verdict, verdictSummary, ratio
|
|
|
357
322
|
process.stderr.write(
|
|
358
323
|
JSON.stringify({
|
|
359
324
|
error: "LEDGER_UNRESOLVABLE",
|
|
360
|
-
detail: "wicked-ledger is not resolvable
|
|
325
|
+
detail: "wicked-ledger is not resolvable — set WICKED_LEDGER_PKG_DIR (a governed crew run sets it) or npm i --no-save wicked-ledger",
|
|
361
326
|
}) + "\n"
|
|
362
327
|
);
|
|
363
328
|
process.exit(3);
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The ONE wicked-ledger resolver of garden's QE pipeline (accept, the gate, the campaign
|
|
3
|
+
* scoreboard). wicked-ledger is resolved for the TARGET repo — the plugin ships no node_modules —
|
|
4
|
+
* in this order:
|
|
5
|
+
*
|
|
6
|
+
* 1. `$WICKED_LEDGER_PKG_DIR` — an explicit package dir. wicked-crew exports its OWN bundled
|
|
7
|
+
* wicked-ledger here (wicked-crew#951), so a governed run's QE unit records its verdict with
|
|
8
|
+
* the very package crew's acceptance check reads it with, and needs no install in the
|
|
9
|
+
* worktree (a fenced governed seat cannot `npm i`, and an install would change the tree).
|
|
10
|
+
* Set but unusable ⇒ `null` (an explicit pin never falls back to a different package).
|
|
11
|
+
* 2. a bare `import("wicked-ledger")` (a global / hoisted install);
|
|
12
|
+
* 3. a walk up from the target repo for `node_modules/wicked-ledger`.
|
|
13
|
+
*
|
|
14
|
+
* `null` when none resolves; callers say so (never a silent no-op).
|
|
15
|
+
*/
|
|
16
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
17
|
+
import { dirname, join, resolve } from "node:path";
|
|
18
|
+
import { pathToFileURL } from "node:url";
|
|
19
|
+
|
|
20
|
+
export const LEDGER_PKG_ENV = "WICKED_LEDGER_PKG_DIR";
|
|
21
|
+
|
|
22
|
+
/** The ESM entry file of a package dir (its `exports["."]` import/default, else module/main). */
|
|
23
|
+
export function esmEntryForPackageDir(pkgDir) {
|
|
24
|
+
const pj = join(pkgDir, "package.json");
|
|
25
|
+
if (!existsSync(pj)) return null;
|
|
26
|
+
let pkg;
|
|
27
|
+
try {
|
|
28
|
+
pkg = JSON.parse(readFileSync(pj, "utf8"));
|
|
29
|
+
} catch {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
const dot = pkg.exports && pkg.exports["."] !== undefined ? pkg.exports["."] : pkg.exports;
|
|
33
|
+
const rel =
|
|
34
|
+
(dot && typeof dot === "object" && (dot.import || dot.default)) ||
|
|
35
|
+
(typeof dot === "string" ? dot : null) ||
|
|
36
|
+
pkg.module ||
|
|
37
|
+
pkg.main ||
|
|
38
|
+
"index.js";
|
|
39
|
+
return join(pkgDir, rel);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** The resolved wicked-ledger module for `repoRoot`, or `null`. */
|
|
43
|
+
export async function resolveLedgerModule(repoRoot = process.cwd(), env = process.env) {
|
|
44
|
+
const pinned = env[LEDGER_PKG_ENV]?.trim();
|
|
45
|
+
if (pinned) {
|
|
46
|
+
const entry = esmEntryForPackageDir(pinned);
|
|
47
|
+
if (!entry || !existsSync(entry)) return null;
|
|
48
|
+
try {
|
|
49
|
+
return await import(pathToFileURL(entry).href);
|
|
50
|
+
} catch {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
try {
|
|
55
|
+
return await import("wicked-ledger");
|
|
56
|
+
} catch {
|
|
57
|
+
/* fall through */
|
|
58
|
+
}
|
|
59
|
+
let dir = resolve(repoRoot);
|
|
60
|
+
for (let i = 0; i < 10; i++) {
|
|
61
|
+
const entry = esmEntryForPackageDir(join(dir, "node_modules", "wicked-ledger"));
|
|
62
|
+
if (entry && existsSync(entry)) {
|
|
63
|
+
try {
|
|
64
|
+
return await import(pathToFileURL(entry).href);
|
|
65
|
+
} catch {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const parent = dirname(dir);
|
|
70
|
+
if (parent === dir) break;
|
|
71
|
+
dir = parent;
|
|
72
|
+
}
|
|
73
|
+
return null;
|
|
74
|
+
}
|
package/skills/learn/SKILL.md
CHANGED
|
@@ -43,9 +43,9 @@ Relative paths in this skill are relative to the directory that contains this SK
|
|
|
43
43
|
|---|---|---|---|
|
|
44
44
|
| `scope` | neutral | nothing | Name the slug (kebab-case, at most 64 characters), the kind (`topic` or `event`), 3 to 7 questions to answer, what is out of scope, and the source policy: primary sources first (specs, official docs, release notes, the project's own site), dated reporting for events. Read `.wicked/knowledge/<slug>/` if it exists: then this run is a **refresh** (see refs/refresh.md). |
|
|
45
45
|
| `research` | neutral | nothing | Fetch sources with your web tools (or `curl -sL`). For each source, record the URL, title, published date when the page states one, and `observed_at` = now in UTC. Draft candidate claims, each tied to the sources that support it. No network: write `research: no web access` and stop; never answer from memory as if it were sourced. |
|
|
46
|
-
| `synthesize` | neutral | nothing | Turn the candidates into the claims ledger (refs/claims.md): one atomic, checkable statement per claim, deduplicated
|
|
46
|
+
| `synthesize` | neutral | nothing | Turn the candidates into the claims ledger (refs/claims.md): one atomic, checkable statement per claim, deduplicated. Leave new claim ids to the author (a neutral seat may not run scripts); on a refresh keep each existing id. Keep only claims that would help a fresh session in 3 months. On a refresh, output the diff against the existing ledger. |
|
|
47
47
|
| `walkthrough` | neutral | nothing | Teach it in the run thread: a 5-line summary, a worked example, what changed (on a refresh), the open questions, and 3 to 5 check questions. The operator answers, asks or corrects by sending the step back; answer each point, re-teach what was unclear, and mark which corrections you verified against a source. |
|
|
48
|
-
| `author` | creator | `.wicked/knowledge/<slug>/`, skills |
|
|
48
|
+
| `author` | creator | `.wicked/knowledge/<slug>/`, skills | Compute each new claim's id (`wicked-garden run scripts/learn/check.py --claim-id "<text>"`), write the files (refs/claims.md), then run the check below and paste its JSON and exit code. |
|
|
49
49
|
| `review` | evaluator | nothing | Re-run the check yourself; re-fetch and spot-check at least 3 claims (every retirement, too); judge the durability test; last line `VERDICT: PASS` or `VERDICT: FAIL`. |
|
|
50
50
|
| `check` | any | nothing | `wicked-garden run scripts/learn/check.py --repo . [--slug <slug>]` |
|
|
51
51
|
| `index` | human or daemon only | estate knowledge | `wicked-garden run scripts/learn/index.py --repo <default-branch checkout>` after the PR merged. It refuses inside a governed run. |
|
package/skills/qe/refs/accept.md
CHANGED
|
@@ -123,7 +123,15 @@ the run's canonical UUID. This serves three goals at once:
|
|
|
123
123
|
// Resolve the ledger root (wicked-ledger >= 0.6.0): WICKED_QE_LEDGER_DIR when set — inside a
|
|
124
124
|
// governed wicked-crew run, the run's own ledger OUTSIDE the worktree (crew#951) — else dual-read
|
|
125
125
|
// (Phase 6c): '.wicked-qe', or a legacy '.wicked-testing' root written before the rename. <!-- historical -->
|
|
126
|
-
|
|
126
|
+
// wicked-ledger through the ONE resolver ($WICKED_LEDGER_PKG_DIR — set by a governed crew run —,
|
|
127
|
+
// else an install the target repo resolves); see § wicked-ledger resolution.
|
|
128
|
+
import { pathToFileURL } from 'node:url';
|
|
129
|
+
import { join as joinPath } from 'node:path';
|
|
130
|
+
// {WT_LIB} is a native path (Windows too): import it as a file URL, never a bare string.
|
|
131
|
+
const { resolveLedgerModule } = await import(pathToFileURL(joinPath(String.raw`{WT_LIB}`, 'ledger-pkg.mjs')).href);
|
|
132
|
+
const ledger = await resolveLedgerModule(process.cwd());
|
|
133
|
+
if (!ledger) throw new Error("wicked-ledger is not resolvable: set WICKED_LEDGER_PKG_DIR or npm i --no-save wicked-ledger");
|
|
134
|
+
const { createDomainStore, resolveLedgerRoot } = ledger;
|
|
127
135
|
import { join } from 'node:path';
|
|
128
136
|
const LEDGER_ROOT = resolveLedgerRoot(process.cwd());
|
|
129
137
|
const store = createDomainStore({ root: LEDGER_ROOT });
|
|
@@ -394,7 +402,7 @@ const verdictRecord = store.create('verdicts', {
|
|
|
394
402
|
});
|
|
395
403
|
|
|
396
404
|
// 3. Materialize the public manifest at the contract path
|
|
397
|
-
|
|
405
|
+
const { buildManifest, emitBusEvent } = ledger; // the same resolved wicked-ledger as step 0
|
|
398
406
|
import { readFileSync } from 'node:fs';
|
|
399
407
|
const pkgVersion = JSON.parse(readFileSync('package.json','utf8')).version;
|
|
400
408
|
const runAfter = store.get('runs', run.id);
|
|
@@ -475,7 +483,13 @@ WT_LIB="$(wicked-garden path scripts/qe/lib)"
|
|
|
475
483
|
## wicked-ledger resolution
|
|
476
484
|
|
|
477
485
|
`wicked-ledger` (npm) is the QE data layer — DomainStore, oracle queries, and
|
|
478
|
-
manifest building.
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
`.
|
|
486
|
+
manifest building. The snippets above load it through `{WT_LIB}/ledger-pkg.mjs`,
|
|
487
|
+
the one resolver the gate shares:
|
|
488
|
+
|
|
489
|
+
1. `$WICKED_LEDGER_PKG_DIR`. Inside a governed wicked-crew run it is set to crew's
|
|
490
|
+
own wicked-ledger, the package crew's acceptance check reads the verdict with.
|
|
491
|
+
Do not `npm i` in a governed run: a fenced seat is refused the install, and it
|
|
492
|
+
would change the tree under review.
|
|
493
|
+
2. otherwise, an install the target repo resolves (`npm i --no-save wicked-ledger`).
|
|
494
|
+
|
|
495
|
+
The pinned range lives in `.claude-plugin/plugin.json` → `wicked_ledger_version`.
|
|
@@ -138,11 +138,9 @@ when the proposal is approved, so the learning is lost):
|
|
|
138
138
|
- **Knowledge** — how the code works, read from the code (*acquired*, so it is
|
|
139
139
|
knowledge, not memory: DES-memory-vs-knowledge). `kind_type: "knowledge"`; payload
|
|
140
140
|
`{"content": "<1–3 sentences>", "class": "concept", "source": "<repo>:<path>",
|
|
141
|
-
"source_rev": "<commit sha>"}`. Most repo-learn findings are this kind.
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
in your report's fenced `json` block under `knowledge (pending)` and leave them out
|
|
145
|
-
of the `wicked-capture-report` counts. Never propose a graph metric (PageRank rank,
|
|
141
|
+
"source_rev": "<commit sha>"}`. Most repo-learn findings are this kind. Submit it
|
|
142
|
+
like any proposal (estate 0.29.2+ approves it into the knowledge store); count it in
|
|
143
|
+
the `wicked-capture-report` like the rest. Never propose a graph metric (PageRank rank,
|
|
146
144
|
churn count, blast-radius size): estate's tools re-derive those on demand.
|
|
147
145
|
- **Memory** — only something *witnessed* while studying (a gotcha you hit, with
|
|
148
146
|
why) or *told* by the operator. Split a mixed finding: "we chose fail-closed
|
|
@@ -73,12 +73,10 @@ estate/steering types — pick the one the rule governs, not a freeform tag.
|
|
|
73
73
|
What you learn by reading code is **acquired**, so it is knowledge, not memory
|
|
74
74
|
(DES-memory-vs-knowledge §3).
|
|
75
75
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
refuses
|
|
79
|
-
|
|
80
|
-
`knowledge (pending)`, and leave them out of the `wicked-capture-report` counts. Do
|
|
81
|
-
not re-file a code fact as a `memory` to get it through. The shape is:
|
|
76
|
+
Submit it through the shim's `propose` like a memory. Estate 0.29.2+ approves a
|
|
77
|
+
knowledge proposal into the knowledge store, keeping its `source`, `observed_at` and
|
|
78
|
+
`source_rev`. The shim refuses one with no `source` (`-32602`). Never re-file a code fact as a
|
|
79
|
+
`memory`. The shape is:
|
|
82
80
|
|
|
83
81
|
```json
|
|
84
82
|
{
|