inventory: list the evidence table's other names and its unmapped rows

Ledger rows carry aliases (the name GEVA-2's table uses where it differs from the key, such as upgrade for gstack-upgrade), and docs/inventory.md lists them beside the installed-name rule. Unmapped rows are labeled as evidence-table rows, and the ranking notes that a skill's on-demand files can also be a shared row's.

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
garrytanandcapy-ai[bot] committed 2026-11-02 05:06:04 +00:00
1 parent 6566d5e284
commit dc218faa68
2 files changed
+42 -12

No files matched your search

+34 -7
View File
@@ -151,13 +151,19 @@
"status": "untested",
"grandfathered": true,
"plan": "none",
"seed": "GEVA-2, 2026-11-02: gstack (root skill): untested (never measured)"
"seed": "GEVA-2, 2026-11-02: gstack (root skill): untested (never measured)",
"aliases": [
"gstack (root skill)"
]
},
"gstack-upgrade": {
"status": "untested",
"grandfathered": true,
"plan": "none",
"seed": "GEVA-2, 2026-11-02: upgrade: untested (never measured)"
"seed": "GEVA-2, 2026-11-02: upgrade: untested (never measured)",
"aliases": [
"upgrade"
]
},
"guard": {
"status": "safety",
@@ -535,7 +541,10 @@
"verdict": "CUT-CANDIDATE",
"ref": "org-gstack-gbrain/research/why-null-stacks-r1.md (GEVA-100); taken by Garry as the I1 ceremony-cut eval"
},
"seed": "GEVA-2, 2026-11-02: preamble (ceremony): measurement under way (I1, ceremony-cut eval)"
"seed": "GEVA-2, 2026-11-02: preamble (ceremony): measurement under way (I1, ceremony-cut eval)",
"aliases": [
"preamble (ceremony)"
]
},
"catalog": {
"status": "untested",
@@ -552,13 +561,19 @@
"note": "untold skill opened in 0 of 180 gstack-arm trials; Opus gstack minus none +5 [-3, +17]"
}
],
"seed": "GEVA-2, 2026-11-02: always-on skill catalog (descriptions): measurement under way (Run D)"
"seed": "GEVA-2, 2026-11-02: always-on skill catalog (descriptions): measurement under way (Run D)",
"aliases": [
"always-on skill catalog (descriptions)"
]
},
"capy-skill": {
"status": "untested",
"grandfathered": true,
"plan": "none",
"seed": "GEVA-2, 2026-11-02: capy/skill/gstack/SKILL.md (Capy context): untested (never measured)",
"aliases": [
"capy/skill/gstack/SKILL.md (Capy context)"
],
"note": "loads only in Capy sessions, which the claude_code preset fair test cannot reach yet; needs a Captain call on how to test it"
},
"capy-factory": {
@@ -566,6 +581,9 @@
"grandfathered": true,
"plan": "none",
"seed": "GEVA-2, 2026-11-02: capy/skill/gstack/factory.md (Capy context): untested (never measured)",
"aliases": [
"capy/skill/gstack/factory.md (Capy context)"
],
"note": "loads only in Capy sessions, which the claude_code preset fair test cannot reach yet; needs a Captain call on how to test it"
},
"ship-review-panel": {
@@ -591,19 +609,28 @@
"note": "arm D vs pooled arm C, no no-gstack arm"
}
],
"seed": "GEVA-2, 2026-11-02: ship: review panel (specialist, adversarial, targeted, outside voice, red team): untested (unfair test: none arm on the SDK stub; arms from different harnesses and gstack versions; cohort mined from gstack's own catches)"
"seed": "GEVA-2, 2026-11-02: ship: review panel (specialist, adversarial, targeted, outside voice, red team): untested (unfair test: none arm on the SDK stub; arms from different harnesses and gstack versions; cohort mined from gstack's own catches)",
"aliases": [
"ship: review panel (specialist, adversarial, targeted, outside voice, red team)"
]
},
"ship-docs-audit": {
"status": "untested",
"grandfathered": true,
"plan": "folded into GEVA-2 registry row R56-4 (ship); proposed, not yet preregistered",
"seed": "GEVA-2, 2026-11-02: ship: docs audit (Step 14.5): untested (never measured)"
"seed": "GEVA-2, 2026-11-02: ship: docs audit (Step 14.5): untested (never measured)",
"aliases": [
"ship: docs audit (Step 14.5)"
]
},
"autoplan-phases": {
"status": "untested",
"grandfathered": true,
"plan": "folded into GEVA-2 registry row R56-3 (autoplan); proposed, not yet preregistered",
"seed": "GEVA-2, 2026-11-02: autoplan: CEO, design, DX and eng phases, outside voice: untested (never measured)"
"seed": "GEVA-2, 2026-11-02: autoplan: CEO, design, DX and eng phases, outside voice: untested (never measured)",
"aliases": [
"autoplan: CEO, design, DX and eng phases, outside voice"
]
}
},
"unmapped": [
+8 -5
View File
@@ -64,7 +64,7 @@ export const PRIOR_WHY: Record<string, string> = {
'not-claude-code': 'ran outside Claude Code (Messages API, Codex or Capy)',
'variant-only': 'variant against variant, no no-gstack arm',
};
const FIELDS = ['status', 'grandfathered', 'plan', 'prior', 'reason', 'owner', 'measure_by', 'sources', 'models', 'prompt', 'scope', 'masked', 'r48', 'seed', 'note'];
const FIELDS = ['status', 'grandfathered', 'plan', 'prior', 'reason', 'owner', 'measure_by', 'sources', 'models', 'prompt', 'scope', 'masked', 'r48', 'seed', 'aliases', 'note'];
export type LedgerCode =
| 'LEDGER_PARSE' | 'LEDGER_KEY_MISSING' | 'LEDGER_KEY_EXTRA' | 'LEDGER_STATUS_INVALID' | 'LEDGER_FIELD_UNKNOWN'
@@ -73,7 +73,7 @@ export type LedgerCode =
| 'LEDGER_REASON_MISSING' | 'LEDGER_OWNER_MISSING' | 'LEDGER_MEASURE_BY_MISSING' | 'LEDGER_PRIOR_INVALID'
| 'INVENTORY_SOURCE_MISSING' | 'INVENTORY_PART_MISSING';
export interface LedgerProblem { key: string; code: LedgerCode; message: string }
export interface LedgerEntry { status: Status; grandfathered?: boolean; plan?: string; prior?: Array<{ ref: string; why: string[]; note?: string }>; reason?: string; owner?: string; measure_by?: string; sources?: string[]; models?: string[]; prompt?: string; scope?: string; masked?: boolean; r48?: { verdict: string; ref: string }; seed?: string; note?: string }
export interface LedgerEntry { status: Status; grandfathered?: boolean; plan?: string; prior?: Array<{ ref: string; why: string[]; note?: string }>; reason?: string; owner?: string; measure_by?: string; sources?: string[]; models?: string[]; prompt?: string; scope?: string; masked?: boolean; r48?: { verdict: string; ref: string }; seed?: string; aliases?: string[]; note?: string }
export interface Ledger { parts: Record<string, LedgerEntry>; unmapped?: Array<{ row: string; why: string }>; [k: string]: unknown }
const isObj = (v: unknown): v is Record<string, unknown> => typeof v === 'object' && v !== null && !Array.isArray(v);
@@ -192,6 +192,7 @@ export interface Inventory {
commit: string; date: string; tokenSource: string; keys: string[]; parts: PartRow[];
tiers: Array<{ tier: string; skills: string[] }>; dispatches: CitedDispatch[];
prior: Array<{ key: string; ref: string; why: string[]; note?: string }>;
aliases: Array<{ key: string; names: string[] }>;
unmapped: Array<{ row: string; why: string }>; problems: LedgerProblem[];
}
@@ -245,6 +246,7 @@ export function buildInventory(root: string): Inventory {
tiers: [...tiers].sort(([a], [b]) => a.localeCompare(b)).map(([tier, skills]) => ({ tier, skills })),
dispatches: checked.dispatches,
prior: checked.keys.flatMap(key => (parts[key]?.prior ?? []).map(p => ({ key, ...p }))),
aliases: checked.keys.filter(k => parts[k]?.aliases?.length).map(k => ({ key: k, names: parts[k]!.aliases! })),
unmapped: checked.ledger?.unmapped ?? [],
problems: checked.problems,
};
@@ -254,7 +256,7 @@ const n = (v: number | null) => (v === null ? 'n/a' : v.toLocaleString('en-US'))
const cell = (s: string) => s.replace(/\|/g, '\\|').replace(/\n/g, ' ');
function renderRanking(inv: Inventory): string[] {
const out = ['## Parts by load per run', '', 'Load per run: a skill\'s SKILL.md plus the files it must read on every use (`perInvocationTokens` in lib/context-bill.ts); a shared part\'s files. Tier 2+ skills also read the shared preamble once per session (its own row). On demand: the skill\'s other sections/ and references/ files, read when a step asks for them. Always-on: frontmatter every session\'s skill scanner reads.', '',
const out = ['## Parts by load per run', '', 'Load per run: a skill\'s SKILL.md plus the files it must read on every use (`perInvocationTokens` in lib/context-bill.ts); a shared part\'s files. Tier 2+ skills also read the shared preamble once per session (its own row). On demand: the skill\'s other sections/ and references/ files, read when a step asks for them; files a shared row also counts, such as /ship\'s review sections, appear in both. Always-on: frontmatter every session\'s skill scanner reads.', '',
'| Rank | Part | Kind | Load per run (tokens) | On demand (tokens) | Always-on (tokens) | Loads | Status | Source, plan or reason |', '|---|---|---|---|---|---|---|---|---|'];
inv.parts.forEach((p, i) => out.push(`| ${i + 1} | ${p.key} | ${p.kind} | ${n(p.loadTokens)} | ${n(p.onDemandTokens)} | ${n(p.alwaysOnTokens)} | ${cell(p.loads)} | ${p.status} | ${cell(p.ref)} |`));
return out;
@@ -291,13 +293,14 @@ function renderKeys(inv: Inventory): string[] {
const skills = inv.keys.filter(k => !SHARED_KEYS.includes(k));
return ['## Key list and aliases', '', `${inv.keys.length} keys: ${skills.length} skills (the folders \`discoverTemplates()\` finds, the root skill as \`gstack\`) and ${SHARED_KEYS.length} shared parts.`, '',
`- Skills: ${skills.join(', ')}.`, `- Shared: ${SHARED_KEYS.join(', ')}.`,
'- Installed names: `gstack-<name>` is key `<name>` (`gstack-ship` is `ship`); `gstack-upgrade` keeps its name; the root skill installs as `gstack`.'];
'- Installed names: `gstack-<name>` is key `<name>` (`gstack-ship` is `ship`); `gstack-upgrade` keeps its name; the root skill installs as `gstack`.',
...(inv.aliases.length ? [`- Other names (the ledger's \`aliases\`): ${inv.aliases.map(a => `${a.names.join(', ')} → ${a.key}`).join('; ')}.`] : [])];
}
function renderNotHere(inv: Inventory): string[] {
return ['## Not in this inventory', '',
'- Out of scope: openclaw/skills/* and browser-skills/* (not gstack skills an agent loads from this checkout), and connect-chrome (a symlink to open-gstack-browser, counted once).',
...inv.unmapped.map(u => `- ${u.row}: ${u.why}`)];
...inv.unmapped.map(u => `- Evidence-table row "${u.row}": ${u.why}.`)];
}
export function renderInventory(inv: Inventory): string {