pan-wizard 3.25.0 → 3.27.0
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 +1 -1
- package/bin/install-lib.cjs +283 -1
- package/bin/install.js +127 -0
- package/commands/pan/hygiene.md +14 -8
- package/commands/pan/milestone-audit.md +10 -4
- package/hooks/dist/pan-cost-logger.js +69 -5
- package/hooks/dist/pan-stop-guard.js +32 -1
- package/hooks/dist/pan-trace-logger.js +35 -2
- package/package.json +3 -2
- package/pan-wizard-core/bin/lib/bridge.cjs +0 -1
- package/pan-wizard-core/bin/lib/bus.cjs +0 -1
- package/pan-wizard-core/bin/lib/campaign.cjs +3 -2
- package/pan-wizard-core/bin/lib/commands-learnings.cjs +8 -8
- package/pan-wizard-core/bin/lib/commands.cjs +15 -14
- package/pan-wizard-core/bin/lib/config.cjs +5 -5
- package/pan-wizard-core/bin/lib/constants.cjs +27 -0
- package/pan-wizard-core/bin/lib/context-budget.cjs +28 -0
- package/pan-wizard-core/bin/lib/core.cjs +190 -26
- package/pan-wizard-core/bin/lib/cost.cjs +0 -1
- package/pan-wizard-core/bin/lib/distill.cjs +3 -3
- package/pan-wizard-core/bin/lib/focus.cjs +16 -16
- package/pan-wizard-core/bin/lib/hud.cjs +1 -1
- package/pan-wizard-core/bin/lib/hygiene.cjs +397 -37
- package/pan-wizard-core/bin/lib/init.cjs +90 -13
- package/pan-wizard-core/bin/lib/knowledge.cjs +0 -1
- package/pan-wizard-core/bin/lib/memory.cjs +1 -1
- package/pan-wizard-core/bin/lib/milestone.cjs +3 -3
- package/pan-wizard-core/bin/lib/optimize.cjs +3 -3
- package/pan-wizard-core/bin/lib/phase.cjs +4 -4
- package/pan-wizard-core/bin/lib/planning-root.cjs +327 -0
- package/pan-wizard-core/bin/lib/preview.cjs +0 -1
- package/pan-wizard-core/bin/lib/review-deep.cjs +0 -1
- package/pan-wizard-core/bin/lib/roadmap.cjs +1 -1
- package/pan-wizard-core/bin/lib/state-compact.cjs +339 -0
- package/pan-wizard-core/bin/lib/state.cjs +0 -1
- package/pan-wizard-core/bin/lib/suggest.cjs +141 -0
- package/pan-wizard-core/bin/lib/template.cjs +1 -1
- package/pan-wizard-core/bin/lib/utils.cjs +39 -11
- package/pan-wizard-core/bin/lib/verify-deploy.cjs +113 -2
- package/pan-wizard-core/bin/lib/verify.cjs +4 -3
- package/pan-wizard-core/bin/lib/whatif.cjs +0 -1
- package/pan-wizard-core/bin/pan-tools.cjs +97 -7
- package/pan-wizard-core/mcp/native-tools.cjs +159 -0
- package/pan-wizard-core/mcp/orchestrator.cjs +179 -0
- package/{pan-zcode → pan-wizard-core}/mcp/server.cjs +35 -6
- package/{pan-zcode → pan-wizard-core}/mcp/tool-registry.cjs +60 -3
- package/pan-wizard-core/workflows/milestone-audit.md +35 -6
- package/pan-wizard-core/workflows/verify-phase.md +25 -6
- package/pan-zcode/README.md +17 -9
- package/pan-zcode/bin/install-zcode.js +4 -1
- package/scripts/build-plugin.js +35 -3
- package/scripts/deprecate-old-versions.js +225 -0
- package/scripts/plugin-path.js +84 -0
- package/pan-wizard-core/learnings/internal/.gitkeep +0 -2
- package/pan-wizard-core/learnings/internal/experiment-runner.md +0 -81
- package/pan-wizard-core/learnings/internal/external-research.md +0 -105
- package/pan-wizard-core/learnings/internal/loop-design.md +0 -33
- package/pan-wizard-core/learnings/internal/pan-dev-bugs.md +0 -181
- package/pan-zcode/mcp/native-tools.cjs +0 -63
- package/pan-zcode/mcp/orchestrator.cjs +0 -66
- /package/{pan-zcode → pan-wizard-core}/mcp/merge-gate.cjs +0 -0
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Deprecate published versions that have fallen far enough behind.
|
|
4
|
+
*
|
|
5
|
+
* WHY. Old releases stay installable forever, and `npm install pan-wizard@3.20.0`
|
|
6
|
+
* silently gives someone a build from several cycles ago with none of the fixes
|
|
7
|
+
* since. Deprecation is the honest signal: the version keeps working, keeps
|
|
8
|
+
* resolving, and anyone installing it sees a warning telling them what to move to.
|
|
9
|
+
*
|
|
10
|
+
* WHY DEPRECATE AND NEVER UNPUBLISH. Unpublishing removes a tarball other people
|
|
11
|
+
* may depend on and is refused by npm outside a 72-hour window anyway. Deprecation
|
|
12
|
+
* is additive, reversible (`npm deprecate <pkg>@<ver> ""` clears it), and breaks
|
|
13
|
+
* nobody. **This script must never gain an unpublish path.**
|
|
14
|
+
*
|
|
15
|
+
* THE RULE. Keep the newest N stable releases (default 3 — the one just published
|
|
16
|
+
* plus the two behind it) and deprecate every stable release older than those.
|
|
17
|
+
* Prereleases are never counted as "kept": once a stable release exists that
|
|
18
|
+
* supersedes them they are deprecated too, since an rc is not something anyone
|
|
19
|
+
* should be installing after the real release shipped.
|
|
20
|
+
*
|
|
21
|
+
* SAFETY, in the order it matters:
|
|
22
|
+
* - DRY RUN BY DEFAULT. `--apply` is required to change anything.
|
|
23
|
+
* - The version being released is never deprecated, even if the arithmetic
|
|
24
|
+
* somehow selects it — an explicit guard, not a consequence.
|
|
25
|
+
* - Already-deprecated versions are skipped, so re-running is a no-op.
|
|
26
|
+
* - A failure to deprecate NEVER fails the build. By the time this runs the
|
|
27
|
+
* publish has already succeeded; turning a housekeeping failure into a red
|
|
28
|
+
* release would be strictly worse than leaving an old version undeprecated.
|
|
29
|
+
*
|
|
30
|
+
* Usage:
|
|
31
|
+
* node scripts/deprecate-old-versions.js # dry run, keep 3
|
|
32
|
+
* node scripts/deprecate-old-versions.js --apply # actually deprecate
|
|
33
|
+
* node scripts/deprecate-old-versions.js --keep 5 --apply
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
'use strict';
|
|
37
|
+
|
|
38
|
+
const { execFileSync } = require('child_process');
|
|
39
|
+
|
|
40
|
+
const PKG = 'pan-wizard';
|
|
41
|
+
const DEFAULT_KEEP = 3;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Parse a semver string into comparable parts. Returns null for anything that is
|
|
45
|
+
* not `major.minor.patch[-prerelease]`, so junk sorts out rather than throwing.
|
|
46
|
+
*/
|
|
47
|
+
function parse(v) {
|
|
48
|
+
const m = /^(\d+)\.(\d+)\.(\d+)(?:-(.+))?$/.exec(String(v || '').trim());
|
|
49
|
+
if (!m) return null;
|
|
50
|
+
return {
|
|
51
|
+
version: v,
|
|
52
|
+
nums: [Number(m[1]), Number(m[2]), Number(m[3])],
|
|
53
|
+
pre: m[4] || null,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Compare two parsed versions, ascending. Prerelease-aware: 3.26.0-rc.1 sorts
|
|
59
|
+
* BELOW 3.26.0, which the update-check hook's comparator deliberately does not do
|
|
60
|
+
* (it ignores the suffix). Getting this backwards would deprecate a real release
|
|
61
|
+
* in favour of its own release candidate, so it is implemented here rather than
|
|
62
|
+
* reused.
|
|
63
|
+
*/
|
|
64
|
+
function compare(a, b) {
|
|
65
|
+
for (let i = 0; i < 3; i++) {
|
|
66
|
+
if (a.nums[i] !== b.nums[i]) return a.nums[i] - b.nums[i];
|
|
67
|
+
}
|
|
68
|
+
if (a.pre === b.pre) return 0;
|
|
69
|
+
if (a.pre === null) return 1; // release > prerelease
|
|
70
|
+
if (b.pre === null) return -1;
|
|
71
|
+
return a.pre < b.pre ? -1 : 1; // lexical is good enough for rc.1 < rc.2
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Decide what to deprecate. PURE — no network, no process — so the rule is
|
|
76
|
+
* testable without touching a registry.
|
|
77
|
+
*
|
|
78
|
+
* @param {string[]} published every version on the registry
|
|
79
|
+
* @param {string} current the version just released (never deprecated)
|
|
80
|
+
* @param {number} keep how many newest STABLE releases to leave alone
|
|
81
|
+
* @param {string[]} [already] versions already carrying a deprecation message
|
|
82
|
+
* @returns {{deprecate:string[], keep:string[], reason:Object<string,string>}}
|
|
83
|
+
*/
|
|
84
|
+
function selectVersionsToDeprecate(published, current, keep = DEFAULT_KEEP, already = []) {
|
|
85
|
+
const parsed = (published || []).map(parse).filter(Boolean).sort(compare);
|
|
86
|
+
const skip = new Set(already || []);
|
|
87
|
+
const stable = parsed.filter((p) => !p.pre);
|
|
88
|
+
// The newest `keep` stable releases are protected.
|
|
89
|
+
const kept = new Set(stable.slice(-keep).map((p) => p.version));
|
|
90
|
+
// The current release is protected regardless of where the arithmetic lands it.
|
|
91
|
+
kept.add(current);
|
|
92
|
+
|
|
93
|
+
const reason = {};
|
|
94
|
+
const deprecate = [];
|
|
95
|
+
for (const p of parsed) {
|
|
96
|
+
if (kept.has(p.version)) continue;
|
|
97
|
+
if (skip.has(p.version)) continue;
|
|
98
|
+
reason[p.version] = p.pre
|
|
99
|
+
? `prerelease superseded by ${current}`
|
|
100
|
+
: `more than ${keep - 1} releases behind ${current}`;
|
|
101
|
+
deprecate.push(p.version);
|
|
102
|
+
}
|
|
103
|
+
return { deprecate, keep: [...kept].sort(), reason };
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** Message a deprecated version carries. Points at what to install instead. */
|
|
107
|
+
function buildMessage(current) {
|
|
108
|
+
return `No longer maintained — install pan-wizard@${current} or later (npm i pan-wizard@latest).`;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// ─── IO layer ───────────────────────────────────────────────────────────────
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Run npm.
|
|
115
|
+
*
|
|
116
|
+
* WINDOWS: `npm` is a `.cmd` shim, so `execFileSync('npm', …)` fails ENOENT and
|
|
117
|
+
* `'npm.cmd'` fails EINVAL — the shim can only be launched through a shell. This
|
|
118
|
+
* is the same scar `runner.cjs` carries as its `shell: 'win32'` opt-in, and the
|
|
119
|
+
* first version of this script reproduced the bug: a local dry run reported
|
|
120
|
+
* "could not read the registry" and returned, so the fail-open path made a real
|
|
121
|
+
* platform bug look like a benign skip.
|
|
122
|
+
*
|
|
123
|
+
* QUOTING: with `shell: true` node CONCATENATES arguments rather than escaping
|
|
124
|
+
* them, so anything containing a space must be quoted or it arrives as several
|
|
125
|
+
* arguments — which matters here because the deprecation message is a sentence.
|
|
126
|
+
* Every argument is program-controlled (package name, versions read from the
|
|
127
|
+
* registry, our own message), so this is a correctness problem rather than an
|
|
128
|
+
* injection one, but it still has to be right. `assertQuotable` refuses a value
|
|
129
|
+
* carrying a double quote instead of emitting a broken command line.
|
|
130
|
+
*/
|
|
131
|
+
function assertQuotable(a) {
|
|
132
|
+
if (String(a).includes('"')) {
|
|
133
|
+
throw new Error(`refusing to shell-quote an argument containing a double quote: ${a}`);
|
|
134
|
+
}
|
|
135
|
+
return a;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function runNpm(args, opts = {}) {
|
|
139
|
+
const win = process.platform === 'win32';
|
|
140
|
+
const argv = win ? args.map((a) => (/\s/.test(a) ? `"${assertQuotable(a)}"` : a)) : args;
|
|
141
|
+
return execFileSync('npm', argv, {
|
|
142
|
+
encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'], shell: win, ...opts,
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* `npm view <pkg> <field> --json` prints NOTHING when the field is unset across
|
|
148
|
+
* every version — which is exactly the healthy starting state for `deprecated`
|
|
149
|
+
* (nothing deprecated yet). `JSON.parse('')` throws, and the fail-open handler
|
|
150
|
+
* then reported "could not read the registry", turning the normal case into an
|
|
151
|
+
* apparent failure. Empty means absent, not broken.
|
|
152
|
+
*/
|
|
153
|
+
function npmJson(args, fallback = null) {
|
|
154
|
+
const out = runNpm(args);
|
|
155
|
+
if (!out || !out.trim()) return fallback;
|
|
156
|
+
return JSON.parse(out);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function main() {
|
|
160
|
+
const args = process.argv.slice(2);
|
|
161
|
+
const apply = args.includes('--apply');
|
|
162
|
+
const keepIdx = args.indexOf('--keep');
|
|
163
|
+
const keep = keepIdx > -1 ? Number(args[keepIdx + 1]) : DEFAULT_KEEP;
|
|
164
|
+
const current = require('../package.json').version;
|
|
165
|
+
|
|
166
|
+
if (!Number.isInteger(keep) || keep < 1) {
|
|
167
|
+
console.error(`deprecate: --keep must be a positive integer, got ${keep}`);
|
|
168
|
+
process.exit(1);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// A prerelease must never trigger a deprecation sweep: it is not the thing
|
|
172
|
+
// users are being pointed at, and treating it as "the new release" would
|
|
173
|
+
// deprecate the current stable one.
|
|
174
|
+
if (parse(current) && parse(current).pre) {
|
|
175
|
+
console.log(`deprecate: ${current} is a prerelease — skipping (sweeps run for stable releases only).`);
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
let published = [];
|
|
180
|
+
let deprecatedAlready = [];
|
|
181
|
+
try {
|
|
182
|
+
published = npmJson(['view', PKG, 'versions', '--json'], []);
|
|
183
|
+
if (!Array.isArray(published)) published = [published];
|
|
184
|
+
const map = npmJson(['view', PKG, 'deprecated', '--json'], {});
|
|
185
|
+
// npm returns a bare string for a single version, or {version: message}.
|
|
186
|
+
deprecatedAlready = (map && typeof map === 'object') ? Object.keys(map) : [];
|
|
187
|
+
} catch (e) {
|
|
188
|
+
console.error(`deprecate: could not read the registry (${String(e.message).split('\n')[0]}). Nothing changed.`);
|
|
189
|
+
return; // never fail the build over housekeeping
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const { deprecate, keep: kept, reason } = selectVersionsToDeprecate(published, current, keep, deprecatedAlready);
|
|
193
|
+
const message = buildMessage(current);
|
|
194
|
+
|
|
195
|
+
console.log(`deprecate: current=${current} keep=${keep}`);
|
|
196
|
+
console.log(` protected: ${kept.join(', ')}`);
|
|
197
|
+
if (deprecate.length === 0) {
|
|
198
|
+
console.log(' nothing to deprecate.');
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
console.log(` ${apply ? 'deprecating' : 'WOULD deprecate (dry run — pass --apply)'}: ${deprecate.length}`);
|
|
202
|
+
for (const v of deprecate) console.log(` ${v} — ${reason[v]}`);
|
|
203
|
+
|
|
204
|
+
if (!apply) return;
|
|
205
|
+
|
|
206
|
+
let failed = 0;
|
|
207
|
+
for (const v of deprecate) {
|
|
208
|
+
try {
|
|
209
|
+
runNpm(['deprecate', `${PKG}@${v}`, message]);
|
|
210
|
+
console.log(` ✓ ${v}`);
|
|
211
|
+
} catch (e) {
|
|
212
|
+
failed++;
|
|
213
|
+
console.error(` ✗ ${v}: ${String(e.stderr || e.message).split('\n')[0]}`);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
if (failed) {
|
|
217
|
+
// Reported, not fatal. The publish already succeeded; a red build here would
|
|
218
|
+
// imply the release failed, which is false and worse than the omission.
|
|
219
|
+
console.error(`deprecate: ${failed} of ${deprecate.length} failed — release is unaffected.`);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
if (require.main === module) main();
|
|
224
|
+
|
|
225
|
+
module.exports = { selectVersionsToDeprecate, buildMessage, parse, compare, assertQuotable };
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Print the absolute path of the built PAN plugin directory — the contract a
|
|
4
|
+
* Claude Code plugin-marketplace `command` source requires (v2.1.229+).
|
|
5
|
+
*
|
|
6
|
+
* WHY THIS EXISTS. PAN builds a plugin (`npm run build:plugin`) and has shipped
|
|
7
|
+
* it nowhere, because marketplace publishing is gated on one unverified
|
|
8
|
+
* question: does `${CLAUDE_PLUGIN_ROOT}` expand inside *command markdown*? It is
|
|
9
|
+
* documented as substituted in hook and MCP configs, not in content. A `command`
|
|
10
|
+
* source needs no hosting, so it turns that question into a local experiment —
|
|
11
|
+
* install the plugin from this script's output and run `/pan-plugin-selftest`.
|
|
12
|
+
*
|
|
13
|
+
* THE CONTRACT, verbatim from code.claude.com/docs/en/plugin-marketplaces:
|
|
14
|
+
* - Claude Code runs the command "through the platform shell, `sh` on macOS and
|
|
15
|
+
* Linux or `cmd.exe` on Windows, from the user's home directory". So NOTHING
|
|
16
|
+
* here may depend on the working directory; every path is derived from
|
|
17
|
+
* __dirname.
|
|
18
|
+
* - "The command must print exactly one line on stdout and exit with code 0."
|
|
19
|
+
* The plugin build is chatty, so its stdout is relayed to STDERR and only the
|
|
20
|
+
* path reaches stdout. A stray console.log here breaks the install.
|
|
21
|
+
* - The printed directory must hold plugin content at its top level, must not
|
|
22
|
+
* be the directory Claude Code started in or one of its parents, and on
|
|
23
|
+
* Windows must not be a UNC path.
|
|
24
|
+
*
|
|
25
|
+
* Rebuilding on every run is deliberate: Claude Code re-runs the command once per
|
|
26
|
+
* session in the background, so a source edit is picked up without reinstalling.
|
|
27
|
+
* In `copy` mode the version is a hash of the directory contents, so an unchanged
|
|
28
|
+
* build counts as up to date.
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
'use strict';
|
|
32
|
+
|
|
33
|
+
const path = require('path');
|
|
34
|
+
const fs = require('fs');
|
|
35
|
+
const { execFileSync } = require('child_process');
|
|
36
|
+
|
|
37
|
+
const ROOT = path.join(__dirname, '..');
|
|
38
|
+
const PLUGIN_DIR = path.join(ROOT, 'dist', 'pan-wizard-plugin');
|
|
39
|
+
|
|
40
|
+
// Top-level markers Claude Code accepts as proof of plugin content.
|
|
41
|
+
const PLUGIN_MARKERS = ['.claude-plugin', 'skills', 'commands', 'agents', 'hooks'];
|
|
42
|
+
|
|
43
|
+
function fail(message) {
|
|
44
|
+
// stderr only — stdout is reserved for the single path line.
|
|
45
|
+
process.stderr.write(`plugin-path: ${message}\n`);
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function build() {
|
|
50
|
+
try {
|
|
51
|
+
// Relay the builder's stdout to stderr so stdout stays single-line.
|
|
52
|
+
const out = execFileSync(process.execPath, [path.join(ROOT, 'scripts', 'build-plugin.js')], {
|
|
53
|
+
cwd: ROOT, encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'],
|
|
54
|
+
});
|
|
55
|
+
if (out) process.stderr.write(out);
|
|
56
|
+
} catch (err) {
|
|
57
|
+
const detail = (err.stderr || err.stdout || err.message || '').toString().trim();
|
|
58
|
+
fail(`plugin build failed: ${detail.split('\n').slice(-3).join(' | ')}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function main() {
|
|
63
|
+
build();
|
|
64
|
+
|
|
65
|
+
if (!fs.existsSync(PLUGIN_DIR)) fail(`build produced no directory at ${PLUGIN_DIR}`);
|
|
66
|
+
|
|
67
|
+
const top = fs.readdirSync(PLUGIN_DIR);
|
|
68
|
+
if (!PLUGIN_MARKERS.some((m) => top.includes(m))) {
|
|
69
|
+
fail(`no plugin content at the top level of ${PLUGIN_DIR} (need one of ${PLUGIN_MARKERS.join(', ')})`);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const resolved = path.resolve(PLUGIN_DIR);
|
|
73
|
+
|
|
74
|
+
// Windows UNC paths are refused by Claude Code; catch it here with a clear
|
|
75
|
+
// message rather than letting the install fail opaquely.
|
|
76
|
+
if (process.platform === 'win32' && /^\\\\/.test(resolved)) {
|
|
77
|
+
fail(`refusing a UNC path (Claude Code rejects it): ${resolved}`);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Exactly one line, nothing else.
|
|
81
|
+
process.stdout.write(`${resolved}\n`);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
main();
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
topic: experiment-runner
|
|
3
|
-
last_updated: 2026-05-03T03:30:13.038Z
|
|
4
|
-
patterns:
|
|
5
|
-
- id: P-EXP-001
|
|
6
|
-
summary: new-project --auto can finish all artifacts but never commit if the run ends before the workflow's commit step (1 of 5 experiments hit this)
|
|
7
|
-
promoted_at: 2026-05-02T14:35:52.700Z
|
|
8
|
-
source_experiments: [whoocache]
|
|
9
|
-
- id: P-EXP-002
|
|
10
|
-
summary: claude -p exits at phase boundaries despite --auto and prose-based DO NOT exit (v3.7.6 cross-phase YOLO continuation fix), so multi-phase autonomous runs need one invocation per phase
|
|
11
|
-
promoted_at: 2026-05-02T14:35:59.399Z
|
|
12
|
-
source_experiments: [whoolog, whoocache, whooflow, whooschema, whoodb]
|
|
13
|
-
- id: P-EXP-003
|
|
14
|
-
summary: state.md YAML frontmatter is the authoritative truth; body prose may lag after phase completion
|
|
15
|
-
promoted_at: 2026-05-02T14:36:04.863Z
|
|
16
|
-
source_experiments: [whooschema, whoolog, whoocache]
|
|
17
|
-
- id: P-EXP-004
|
|
18
|
-
summary: 30-min DEFAULT_TIMEOUT_MS is too short for typical 3-plan phases; recommend 60+ min default
|
|
19
|
-
promoted_at: 2026-05-02T14:36:15.357Z
|
|
20
|
-
source_experiments: [whoolog]
|
|
21
|
-
- id: P-EXP-005
|
|
22
|
-
summary: 4 concurrent claude -p experiment sessions run cleanly on a single machine; no TTY contention or rate-limit issues
|
|
23
|
-
promoted_at: 2026-05-02T14:36:22.170Z
|
|
24
|
-
source_experiments: [whoolog, whoocache, whooflow, whooschema, whoodb]
|
|
25
|
-
- id: P-NPRS-005
|
|
26
|
-
summary: Single experiment can ship a 24-plan / 5-phase / 346-test / 1.46MB binary milestone in ~6h cumulative agent runtime when the planner emits decision-trace + the executor honors per-plan file ownership
|
|
27
|
-
promoted_at: 2026-05-03T03:30:13.038Z
|
|
28
|
-
source_experiments: [notepadrs]
|
|
29
|
-
---
|
|
30
|
-
|
|
31
|
-
# Experiment Runner (AI-derived)
|
|
32
|
-
|
|
33
|
-
> Auto-maintained by `pan-tools learn promote`. Each pattern was extracted from one or more experiment runs (see source_experiments). Patterns are **advisory** — orchestrators should weight them against current context.
|
|
34
|
-
|
|
35
|
-
## P-EXP-001 — Missing git identity in fresh experiment folder causes silent commit failures (whoocache root cause)
|
|
36
|
-
|
|
37
|
-
**Evidence:** whoocache: 24 min of work produced project.md, requirements.md, roadmap.md, src/{cache,atomic-write,lock,...}.js — but git log empty. **Root cause** found in summary.md: "Git identity was not configured in this environment; per environment_notes the commits returned `committed: false` with `reason: 'commit_failed'`. File outputs landed on disk (the contract). Commits can be re-run later by the user once `git config user.email / user.name` are set." `pan-tools commit` returns exit-0 with `{committed: false, reason: 'commit_failed'}` — the autonomous loop sees no error and keeps going. State.md showed Phase 1 ready. Resumed phase commands committed normally from then on, after identity was set.
|
|
38
|
-
|
|
39
|
-
**Rule:** experiment scaffolding (`pan-tools experiment new`) MUST `git init` the folder AND configure `user.email` / `user.name` (inherited from PAN source repo, falling back to placeholders) so the autonomous loop's commits don't silently fail. Fixed in `experiment.cjs initExperimentGit()` v3.7.9. As a defensive layer, `new-project.md` section 8.9 also adds an end-of-workflow safety-net commit. As a hardening item, consider making `pan-tools commit` exit non-zero on `commit_failed` so callers detect the failure mode.
|
|
40
|
-
|
|
41
|
-
**Applies in:** experiment.cjs scaffolder, new-project workflow, any tooling that wraps `pan-tools commit` in a fresh git environment
|
|
42
|
-
|
|
43
|
-
## P-EXP-002 — claude -p exits at phase boundaries despite --auto and prose-based DO NOT exit (v3.7.6 cross-phase YOLO continuation fix), so multi-phase autonomous runs need one invocation per phase
|
|
44
|
-
|
|
45
|
-
**Evidence:** All 5 experiments (whoolog, whoocache, whooflow, whooschema, whoodb) exited cleanly with exit_code=0 status=incomplete at every Phase N -> Phase N+1 boundary. Each phase needed a separate experiment run --prompt invocation. Even though state.md shows current_phase advanced and last_activity says transitioned to Phase N+1, the spawned claude session ends.
|
|
46
|
-
|
|
47
|
-
**Rule:** Treat the autonomous cross-phase chain as best-effort, not guaranteed. Scripts/CI/runners should plan for one /pan:plan-phase N --auto invocation per phase. Single-invocation multi-phase runs are a stretch goal, not the contract.
|
|
48
|
-
|
|
49
|
-
**Applies in:** any autonomous multi-phase run via claude -p, codex exec, gemini -p, opencode
|
|
50
|
-
|
|
51
|
-
## P-EXP-003 — state.md YAML frontmatter is the authoritative truth; body prose may lag after phase completion
|
|
52
|
-
|
|
53
|
-
**Evidence:** whooschema after Phase 3 completion: frontmatter showed completed_phases=3 status=completed, but body still showed Current phase 1 - Foundation, Phase 1 Executed. Same pattern observed in whoolog and whoocache to lesser degree.
|
|
54
|
-
|
|
55
|
-
**Rule:** When reading state.md programmatically (from runner.cjs, status checks, harvest scripts), parse the YAML frontmatter fields (completed_phases, current_phase, status). The body's Current Position / Phase Status sections sometimes do not re-render after phase completion. Prefer frontmatter parsers over markdown text scans.
|
|
56
|
-
|
|
57
|
-
**Applies in:** runner.cjs status checks, state.md consumers, anything reading state programmatically
|
|
58
|
-
|
|
59
|
-
## P-EXP-004 — 30-min DEFAULT_TIMEOUT_MS is too short for typical 3-plan phases; recommend 60+ min default
|
|
60
|
-
|
|
61
|
-
**Evidence:** whoolog Phase 1 first run: timed out at 30:00 after Phase 1 research only (9 commits). Resumed with 90-min timeout and finished Phase 1 fully in 26 minutes. Same pattern would have killed whooflow new-project (~60 min) if that timeout had been the default.
|
|
62
|
-
|
|
63
|
-
**Rule:** DEFAULT_TIMEOUT_MS in runner.cjs should be raised from 30 min to 60 min, OR the experiment new command should set a per-experiment timeout based on roadmap.phase_count * 8 min after the new-project run. Phase 1 of whoolog (3 plans) took 26 min; whooflow (5 plans per phase) was at 35 min when killed by 30-min cap on first run. The default cuts off real work mid-phase.
|
|
64
|
-
|
|
65
|
-
**Applies in:** runner.cjs DEFAULT_TIMEOUT_MS, experiment run --timeout default
|
|
66
|
-
|
|
67
|
-
## P-EXP-005 — 4 concurrent claude -p experiment sessions run cleanly on a single machine; no TTY contention or rate-limit issues
|
|
68
|
-
|
|
69
|
-
**Evidence:** Ran whoolog Phase 2 + whoocache Phase 1 + whooflow new-project + whooschema new-project + whoodb new-project all in parallel for ~60 minutes. All 4 concurrent sessions made independent progress, no failures, no missed commits attributable to concurrency. Wall-clock time for full 5-experiment run: ~3 hours (vs ~9 hours sequential).
|
|
70
|
-
|
|
71
|
-
**Rule:** The experiment runner can safely fan out to N=4 concurrent autonomous experiments on a single workstation. The runner's stdio ['inherit', 'pipe', 'pipe'] design holds up because claude -p does not actually CONSUME stdin (only probes for TTY). API rate limits at this concurrency are not hit on Anthropic Claude Opus 4.7. Beyond N=4, untested.
|
|
72
|
-
|
|
73
|
-
**Applies in:** experiment runner, automated multi-experiment campaigns, CI
|
|
74
|
-
|
|
75
|
-
## P-NPRS-005 — Single experiment can ship a 24-plan / 5-phase / 346-test / 1.46MB binary milestone in ~6h cumulative agent runtime when the planner emits decision-trace + the executor honors per-plan file ownership
|
|
76
|
-
|
|
77
|
-
**Evidence:** notepadrs experiment 2026-05-02→03: Phase 1 (4 plans, 18 tests) ran clean; Phase 2 (4 plans, 109 tests cumulative) ran clean; Phase 3 (5 plans, multi-tab + find/replace + worker thread + epoch cancellation) timed out at 90 min on first attempt at 77% — resumed cleanly with /pan:exec-phase 3 --auto and finished in 45 min; Phase 4 (5 plans split mid-run from 4 to handle wave-2 collision) took 50 min; Phase 5 (5 plans + dogfood + ship gate) took 55 min plan + 7 min finish wrap. Total cumulative: ~6h agent time including 1 timeout. Final binary: 1.46 MB (6.86× under the 10MB ship gate); 346 tests (11.5× the 30-test floor). Plan-checker iteration revisions caught wave-2 file collisions BEFORE execution; reasoning-trace handoff via Plan Decisions / Implementation Decisions sections kept context coherent across plan-checker → executor → verifier.
|
|
78
|
-
|
|
79
|
-
**Rule:** Auto-mode multi-phase experiments DO complete v1-shippable software in roughly 1 hour per phase IF: (a) phase plan-phase produces explicit per-plan files_modified ownership AND a decisions buckets section; (b) plan-checker is allowed to iterate (split plans, revise files_modified) BEFORE execution starts; (c) timeouts are 90 min per command, not 60 min; (d) when a phase times out at >70% complete, resume with /pan:exec-phase N --auto rather than restarting plan-phase; (e) final phase wrap (write missing summary.md + verification.md, advance state) sometimes needs a separate short prompt because the auto-runner exits when state.md says 'verifying'. The 'incomplete' status with exit_code 0 means the agent left work mid-state, not that anything failed.
|
|
80
|
-
|
|
81
|
-
**Applies in:** PAN experiment-runner orchestration; the experiment.cjs runner; auto-mode workflow guidance; planner/executor handoff design
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
topic: external-research
|
|
3
|
-
last_updated: 2026-07-09T14:04:40.520Z
|
|
4
|
-
patterns:
|
|
5
|
-
- id: P-RES-001
|
|
6
|
-
summary: ACE (Zhang et al, arXiv:2510.04618, Oct 2025): summary-based context chains have brevity bias and context collapse. Treat memory as append-and-curate playbook, not paraphrase chain
|
|
7
|
-
promoted_at: 2026-05-02T18:15:25.976Z
|
|
8
|
-
source_experiments: [external]
|
|
9
|
-
- id: P-RES-002
|
|
10
|
-
summary: Chroma context-rot (July 2025): a single semantically-similar-but-irrelevant distractor degrades performance even at modest context sizes. Distractor density matters more than token count
|
|
11
|
-
promoted_at: 2026-05-02T18:15:32.003Z
|
|
12
|
-
source_experiments: [external]
|
|
13
|
-
- id: P-RES-003
|
|
14
|
-
summary: Cognition (June 2025) anti-multi-agent argument: parallel sub-agents fail because every action carries unstated decisions; downstream agents reconcile contradictions blindly when they only see artifacts
|
|
15
|
-
promoted_at: 2026-05-02T18:15:39.391Z
|
|
16
|
-
source_experiments: [external]
|
|
17
|
-
- id: P-RES-004
|
|
18
|
-
summary: Specification Gap paper (arXiv:2603.24284, early 2026): two-agent integration accuracy collapses 58 to 25 percent as spec detail is removed; coordination is quadratically sensitive to spec completeness
|
|
19
|
-
promoted_at: 2026-05-02T18:15:50.213Z
|
|
20
|
-
source_experiments: [external]
|
|
21
|
-
- id: P-RES-005
|
|
22
|
-
summary: GitHub PR audit (arXiv:2601.15195, Jan 2026): agent PRs fail mostly from spec/intent mismatch, design fit, and repo-norm violation — not buggy code. Code that compiles and tests still gets rejected
|
|
23
|
-
promoted_at: 2026-05-02T18:15:58.959Z
|
|
24
|
-
source_experiments: [external]
|
|
25
|
-
- id: P-RES-006
|
|
26
|
-
summary: S2R / RLVR (ACL 2025): naive self-critique is largely ineffective; verification gains come from FRESH-CONTEXT RESTART and FILE-MEDIATED STRUCTURE forcing re-reading, not from the judging itself. Verbose self-review can hurt via overthinking
|
|
27
|
-
promoted_at: 2026-05-02T18:16:09.893Z
|
|
28
|
-
source_experiments: [external]
|
|
29
|
-
- id: P-RES-007
|
|
30
|
-
summary: Sakana DGM (2025): in self-improvement loops, AGENT-DESIGN changes generalize across models and languages; PROMPT-FRAGMENT tweaks do not. Promote structural changes, not phrasing tweaks
|
|
31
|
-
promoted_at: 2026-05-02T18:16:19.459Z
|
|
32
|
-
source_experiments: [external]
|
|
33
|
-
- id: P-RES-008
|
|
34
|
-
summary: Enterprise "train on our data" asks are retrieval problems, not fine-tuning problems: schema/context LINKING is the bottleneck (BEAVER: SOTA ~10.8% on real enterprise schemas vs 80%+ on public benchmarks, ~68% of failures are schema-linking), and plain BM25 RAG beats fine-tuning alone (Tencent 160k-file study: 53.8% vs 44.2% EM; FT alone caused catastrophic forgetting; FT+RAG best at 57.4%)
|
|
35
|
-
promoted_at: 2026-07-09T14:04:40.520Z
|
|
36
|
-
source_experiments: [spec-factory]
|
|
37
|
-
---
|
|
38
|
-
|
|
39
|
-
# External Research (AI-derived)
|
|
40
|
-
|
|
41
|
-
> Auto-maintained by `pan-tools learn promote`. Each pattern was extracted from one or more experiment runs (see source_experiments). Patterns are **advisory** — orchestrators should weight them against current context.
|
|
42
|
-
|
|
43
|
-
## P-RES-001 — ACE (Zhang et al, arXiv:2510.04618, Oct 2025): summary-based context chains have brevity bias and context collapse. Treat memory as append-and-curate playbook, not paraphrase chain
|
|
44
|
-
|
|
45
|
-
**Evidence:** https://arxiv.org/abs/2510.04618 — ACE: Agentic Context Engineering. Empirical: iterative summarization monotonically loses detail on agent and finance benchmarks; structured playbook curation outperforms across runs.
|
|
46
|
-
|
|
47
|
-
**Rule:** Reframe memory/<agent>.md and per-phase summary.md as a structured DELTA-LOG (curated by an explicit reviewer step) rather than a paraphrase of the prior phase. Each entry is an addition or amendment to a structured field, not a fresh re-summarization. Curation is its own step, distinct from generation. The pan-optimizer's accrual model should be re-examined under this lens — does it append signal, or summarize away signal?
|
|
48
|
-
|
|
49
|
-
**Applies in:** pan-optimizer accrual loop, memory.cjs, summary.md template design, retro --write-memory
|
|
50
|
-
|
|
51
|
-
## P-RES-002 — Chroma context-rot (July 2025): a single semantically-similar-but-irrelevant distractor degrades performance even at modest context sizes. Distractor density matters more than token count
|
|
52
|
-
|
|
53
|
-
**Evidence:** https://www.trychroma.com/research/context-rot — Hong & Huber, July 2025. Single-distractor experiments showed degradation begins well before 200K, and is non-linear with arrangement and similarity.
|
|
54
|
-
|
|
55
|
-
**Rule:** Per-phase context budgets currently track tokens. Add a notion of distractor density: how much of context.md / research.md is plausibly-related-but-off-topic. Codebase mapper and phase researcher should optimize for relevance ratio, not coverage. The phase-budget command should warn when the relevance ratio is low even if token count is healthy.
|
|
56
|
-
|
|
57
|
-
**Applies in:** phase-budget, codebase scan filtering, research agent guidance
|
|
58
|
-
|
|
59
|
-
## P-RES-003 — Cognition (June 2025) anti-multi-agent argument: parallel sub-agents fail because every action carries unstated decisions; downstream agents reconcile contradictions blindly when they only see artifacts
|
|
60
|
-
|
|
61
|
-
**Evidence:** https://cognition.ai/blog/dont-build-multi-agents — Walden Yan, Cognition. Contrast https://www.anthropic.com/engineering/multi-agent-research-system which argues breadth-first reads parallelize fine but writes/decisions need a single coherent trace.
|
|
62
|
-
|
|
63
|
-
**Rule:** PAN's serial pipeline (planner -> researcher -> executor -> verifier) is what Cognition endorses, but file-mediated handoff passes only OUTPUTS, not reasoning traces. Consider: should plan.md include an explicit decisions-and-rationale section that the executor reads, beyond just the task list? Should summary.md include a deviations log that the verifier reads? The signal is: when an agent is briefed for a downstream phase, the upstream agent's reasoning trace should be available, not just the artifacts.
|
|
64
|
-
|
|
65
|
-
**Applies in:** plan.md template, summary.md template, executor briefing, conductor briefing
|
|
66
|
-
|
|
67
|
-
## P-RES-004 — Specification Gap paper (arXiv:2603.24284, early 2026): two-agent integration accuracy collapses 58 to 25 percent as spec detail is removed; coordination is quadratically sensitive to spec completeness
|
|
68
|
-
|
|
69
|
-
**Evidence:** https://arxiv.org/abs/2603.24284v1 — The Specification Gap. Two-agent integration: 58 percent accuracy with full spec, 25 percent with stripped spec. Single-agent baseline: 89 to 56 percent. Coordination cost of incomplete specs is quadratic.
|
|
70
|
-
|
|
71
|
-
**Rule:** pan-plan-checker currently verifies plan COHERENCE across 8 dimensions. Add a 9th: spec-sufficiency-for-handoff. Question to answer: does this plan contain enough detail that the executor cannot make a divergent decision in the implicit space the plan does not constrain. The check is not is-the-plan-good but is-the-plan-complete-enough-to-survive-the-context-boundary. Specifically: every task has explicit Files, explicit Action, explicit Verify, explicit Done; every architectural choice is locked vs flexible; every assumption is named.
|
|
72
|
-
|
|
73
|
-
**Applies in:** agents/pan-plan-checker.md (existing 8 verification dimensions), plan.md template (forcing locked-vs-flexible markers)
|
|
74
|
-
|
|
75
|
-
## P-RES-005 — GitHub PR audit (arXiv:2601.15195, Jan 2026): agent PRs fail mostly from spec/intent mismatch, design fit, and repo-norm violation — not buggy code. Code that compiles and tests still gets rejected
|
|
76
|
-
|
|
77
|
-
**Evidence:** https://arxiv.org/abs/2601.15195 — Where Do AI Coding Agents Fail. 33K-PR audit. Primary failure modes: spec/intent mismatch (32 percent), design fit (24 percent), repo-norm violation (19 percent). Buggy code is a minority cause of rejection.
|
|
78
|
-
|
|
79
|
-
**Rule:** pan-verifier currently checks code-against-plan. The dominant external-world failure is fit-against-repo-norms (style, naming, prior-PR conventions, framework idioms). Verifier should treat codebase/CONVENTIONS.md and codebase/STRUCTURE.md (when they exist from /pan:map-codebase) as first-class verification inputs, not advisory context. project.md and requirements.md may need a Norms section the verifier explicitly tests against. The verification dimensions should add: does this code follow the conventions evident in adjacent files.
|
|
80
|
-
|
|
81
|
-
**Applies in:** agents/pan-verifier.md, agents/pan-reviewer.md, codebase/CONVENTIONS.md consumption, project.md template
|
|
82
|
-
|
|
83
|
-
## P-RES-006 — S2R / RLVR (ACL 2025): naive self-critique is largely ineffective; verification gains come from FRESH-CONTEXT RESTART and FILE-MEDIATED STRUCTURE forcing re-reading, not from the judging itself. Verbose self-review can hurt via overthinking
|
|
84
|
-
|
|
85
|
-
**Evidence:** https://aclanthology.org/2025.acl-long.1104.pdf — S2R. https://magazine.sebastianraschka.com/p/state-of-llms-2025 — Raschka summary. Untrained self-critique provides little gain on reasoning; verification helps when verifier has training or runs against verifiable rewards.
|
|
86
|
-
|
|
87
|
-
**Rule:** PAN has multiple judgment-style verification roles: pan-plan-checker (judges plan coherence), pan-meta-reviewer (judges other reviewers), pan-hardener (judges security risk by inspection). The S2R finding suggests these roles' value is mostly the FRESH-CONTEXT structural reset, not the judgment per se. Implication: lean these agents harder on VERIFIABLE signals (test cmd, lint cmd, schema check, type check, dep cycle scan, regex anti-pattern detection) and reduce prose-only verdicts. Where a verifiable check exists, use it instead of prose review. Where one doesn't, ask whether the role earns its compute.
|
|
88
|
-
|
|
89
|
-
**Applies in:** agents/pan-plan-checker.md, agents/pan-verifier.md, agents/pan-reviewer.md, agents/pan-meta-reviewer.md, agents/pan-hardener.md, references/verification-patterns.md
|
|
90
|
-
|
|
91
|
-
## P-RES-007 — Sakana DGM (2025): in self-improvement loops, AGENT-DESIGN changes generalize across models and languages; PROMPT-FRAGMENT tweaks do not. Promote structural changes, not phrasing tweaks
|
|
92
|
-
|
|
93
|
-
**Evidence:** https://sakana.ai/dgm/ — Darwin Godel Machine. Population-based self-improvement showed structural changes transferred across models; specific prompt tweaks did not. The same generalization curve likely holds for human-mediated promote gates.
|
|
94
|
-
|
|
95
|
-
**Rule:** When pan-tools learn promote runs (manual gate today, possibly auto-promote in v3.8+), the promote criterion should distinguish: 1) STRUCTURAL pattern (a new agent role, a new file in .planning/, a new verification gate, a new tool-use idiom, an architectural decision) vs 2) PROMPT-FRAGMENT (specific phrasing, a worded instruction, a stylistic preference). Universal scope should be reserved for structural patterns. Prompt fragments belong in internal scope at most — they don't generalize across models or languages, so shipping them to all 5 runtimes is a bet that won't pay.
|
|
96
|
-
|
|
97
|
-
**Applies in:** pan-tools learn promote --scope universal gate, optimize.cjs promotePattern criteria, future auto-promote rules
|
|
98
|
-
|
|
99
|
-
## P-RES-008 — Enterprise "train on our data" asks are retrieval problems, not fine-tuning problems: schema/context LINKING is the bottleneck (BEAVER: SOTA ~10.8% on real enterprise schemas vs 80%+ on public benchmarks, ~68% of failures are schema-linking), and plain BM25 RAG beats fine-tuning alone (Tencent 160k-file study: 53.8% vs 44.2% EM; FT alone caused catastrophic forgetting; FT+RAG best at 57.4%)
|
|
100
|
-
|
|
101
|
-
**Evidence:** The the tech-spec factory tech-spec factory research roadmap (adversarially verified, with citations) synthesized: on BEAVER (real enterprise schemas) SOTA agents collapse to ~10.8%; roughly 68% of failures are schema-linking, not generation. The Tencent 160k-file study showed plain BM25 retrieval beating fine-tuning alone (53.8 vs 44.2 EM) with fine-tuning alone causing catastrophic forgetting. Design consequence adopted there: never dump a full schema into context — decompose into semantic units, hybrid-retrieve a small candidate set (~50), then resolve to physical names.
|
|
102
|
-
|
|
103
|
-
**Rule:** When a project asks to "train the model on our data/schema": default to retrieval-first (decompose corpus into semantic units, hybrid lexical+semantic retrieval of a small candidate set, then resolve). Treat fine-tuning as an additive step at most, never the substitute. Size context by retrieved candidates, not by dumping the schema. Expect public-benchmark performance claims to overstate enterprise reality by up to an order of magnitude.
|
|
104
|
-
|
|
105
|
-
**Applies in:** Research/planning phases for RAG or fine-tune decisions, enterprise schema tooling, context-budget design.
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
topic: loop-design
|
|
3
|
-
last_updated: 2026-05-03T05:00:00.000Z
|
|
4
|
-
patterns:
|
|
5
|
-
- id: P-1303
|
|
6
|
-
summary: Exercising PAN's actual surfaces (autonomous run) produces orders-of-magnitude more PAN-relevant signal than building parallel tools — even when shorter
|
|
7
|
-
promoted_at: 2026-04-27T11:21:36.814Z
|
|
8
|
-
source_experiments: [panloop]
|
|
9
|
-
- id: P-1403
|
|
10
|
-
summary: Track wall-clock-per-commit and tokens-per-commit as autonomous-overhead metrics
|
|
11
|
-
promoted_at: 2026-04-27T12:01:14.269Z
|
|
12
|
-
source_experiments: [panloop]
|
|
13
|
-
---
|
|
14
|
-
|
|
15
|
-
# Loop Design (PAN-internal)
|
|
16
|
-
|
|
17
|
-
> Auto-maintained by `pan-tools learn promote`. Each pattern was extracted from one or more experiment runs (see source_experiments). Internal-scope patterns are PAN-specific and stay in the source repo (stripped at install). Patterns are **advisory** — orchestrators should weight them against current context.
|
|
18
|
-
|
|
19
|
-
## P-1303 — Exercising PAN's actual surfaces (autonomous run) produces orders-of-magnitude more PAN-relevant signal than building parallel tools — even when shorter
|
|
20
|
-
|
|
21
|
-
**Evidence:** Single 25-second autonomous run (panloop) surfaced 2 critical real PAN bugs (P-1301 AskUserQuestion gap, P-1302 runner permissions gap). Compare: 8 prior hand-built mock experiments (whoocsv, whoojson, whooemoji, whoocron, whoohash, whoouuid, whoodag, whoofreq) totaling many hours produced 0 PAN-internal findings — only generic engineering patterns. The autonomous loop validates its own design hypothesis: hitting real surfaces > simulating them.
|
|
22
|
-
|
|
23
|
-
**Rule:** When designing self-improvement loops or eval frameworks, the experiments must EXERCISE the system being optimized, not BUILD PARALLEL artifacts. A 25-second real run beats hours of mock work for surfacing system-internal bugs. For PAN specifically: future experiments should run /pan:new-project, /pan:plan-phase, /pan:exec-phase, /pan:focus-* against fresh test projects via the runner, not build standalone CLIs alongside. The mock builds have value for promoting GENERIC patterns; only autonomous runs surface PAN-INTERNAL ones.
|
|
24
|
-
|
|
25
|
-
**Applies in:** self-improvement loop design (ADR-0026 update); v3.8+ planning; promote-step heuristics
|
|
26
|
-
|
|
27
|
-
## P-1403 — Track wall-clock-per-commit and tokens-per-commit as autonomous-overhead metrics
|
|
28
|
-
|
|
29
|
-
**Evidence:** panloop: 25 commits in 29 min = 1.16 min/commit. Cost $12.84 / 25 commits = $0.51/commit. Useful baseline for future optimization.
|
|
30
|
-
|
|
31
|
-
**Rule:** PAN's /pan:learn report should compute and surface (a) commits_per_minute, (b) cost_usd_per_commit, (c) cost_usd_per_phase, (d) cost_usd_per_test, by reading harvest.json + git log + harvested cost data. Trend over experiments shows whether autonomous overhead is improving as patterns saturate.
|
|
32
|
-
|
|
33
|
-
**Applies in:** v3.8+ pan-optimizer agent prompt; harvest.json schema extension
|