@ngockhoale/ukit 3.4.47 → 3.4.48

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 (62) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/manifests/documentation.yaml +22 -0
  3. package/manifests/platform.full.yaml +27 -0
  4. package/package.json +4 -1
  5. package/scripts/dev/worktree-preflight.mjs +20 -1
  6. package/src/core/diffPlan.js +38 -12
  7. package/src/core/executionContracts.js +67 -16
  8. package/src/core/metadata.js +4 -0
  9. package/src/core/runInstallPipeline.js +19 -2
  10. package/src/core/runtimeConfig.js +1 -1
  11. package/src/index/playbookRegistry.js +22 -3
  12. package/src/index/taskRouting.js +2 -2
  13. package/template_project/.claude/agents/bug-debugger.md +1 -0
  14. package/template_project/.claude/agents/code-reviewer.md +1 -0
  15. package/template_project/.claude/agents/feature-implementer.md +1 -0
  16. package/template_project/.claude/agents/handoff-planner.md +1 -0
  17. package/template_project/.claude/agents/ukit-small-task-maintainer.md +1 -0
  18. package/template_project/.claude/hooks/completion-gate.sh +1 -1
  19. package/template_project/.claude/hooks/delegation-gate.mjs +343 -0
  20. package/template_project/.claude/hooks/skill-router.sh +147 -6
  21. package/template_project/.claude/settings.json +8 -8
  22. package/template_project/.claude/ukit/index/playbook-registry.mjs +22 -3
  23. package/template_project/.claude/ukit/index/route-resolver.mjs +67 -15
  24. package/template_project/.claude/ukit/index/route-task.mjs +115 -37
  25. package/template_project/.claude/ukit/index/tier-lane.mjs +202 -0
  26. package/template_project/.claude/ukit/runtime/cron-operation-adapter.mjs +3 -1
  27. package/template_project/.claude/ukit/runtime/execution-ledger.mjs +306 -20
  28. package/template_project/.claude/ukit/runtime/hook-chain-runner.mjs +8 -0
  29. package/template_project/.claude/ukit/runtime/loop-state.mjs +3 -1
  30. package/template_project/.claude/ukit/runtime/observability-emit.mjs +38 -0
  31. package/template_project/.claude/ukit/runtime/playbook-execution.mjs +704 -0
  32. package/template_project/.claude/ukit/runtime/stop-coordinator.mjs +79 -3
  33. package/template_project/.omp/agents/bug-debugger.md +1 -0
  34. package/template_project/.omp/agents/code-reviewer.md +1 -0
  35. package/template_project/.omp/agents/feature-implementer.md +1 -0
  36. package/template_project/.omp/agents/handoff-planner.md +1 -0
  37. package/template_project/.omp/agents/ukit-small-task-maintainer.md +1 -0
  38. package/template_project/.omp/hooks/pre/ukit-bridge.js +254 -7
  39. package/template_project/ukit/storage/config.json +1 -1
  40. package/scripts/bench/data-foundation.mjs +0 -929
  41. package/scripts/bench/decision-runtime-baseline.mjs +0 -427
  42. package/scripts/bench/decision-runtime-variant.mjs +0 -626
  43. package/scripts/bench/goldTasks.json +0 -38
  44. package/scripts/bench/memory-ablation.mjs +0 -495
  45. package/scripts/bench/memory-baseline.mjs +0 -596
  46. package/scripts/bench/memory-bench.mjs +0 -661
  47. package/scripts/bench/memory-canary.mjs +0 -331
  48. package/scripts/bench/memory-corpus.mjs +0 -354
  49. package/scripts/bench/memory-gate.mjs +0 -389
  50. package/scripts/bench/memory-metrics.mjs +0 -179
  51. package/scripts/bench/outline-savings.mjs +0 -107
  52. package/scripts/bench/parallel-agents.mjs +0 -224
  53. package/scripts/bench/recorder-overhead.mjs +0 -204
  54. package/scripts/bench/runGold.mjs +0 -238
  55. package/scripts/bench/sqlite-spike.mjs +0 -451
  56. package/scripts/bench/subagent-orchestrator-corpus.mjs +0 -275
  57. package/scripts/bench/subagent-orchestrator-eval.mjs +0 -565
  58. package/scripts/bench/v3-ceremony.mjs +0 -220
  59. package/scripts/perf/audit-perf.mjs +0 -1195
  60. package/scripts/perf/diff-perf-findings.mjs +0 -136
  61. package/scripts/perf/perf-findings.json +0 -474
  62. package/scripts/perf/perf-measure.md +0 -271
@@ -1,220 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * v3-ceremony.mjs — planned-ceremony delta harness (SPEC FR-008, M05.1').
4
- *
5
- * Seeds a fixture project (same shape as seedOrchestrationLadderFixtureProject /
6
- * the corpus test seeder), runs every V3_ROUTE_CORPUS case through
7
- * deriveTaskRoute twice — routing.fastPath.stage 'off' vs 'shadow' (rigor stays
8
- * 'shadow' in both so riskFloor is emitted on both sides) — and prints a report
9
- * of the planned-ceremony surface: skills, helper commands, advisory blocks,
10
- * suppressed ceremony, elapsedMs.
11
- *
12
- * This is a measurement tool, not a gate: it always exits 0. A zero delta is a
13
- * finding, not a failure.
14
- *
15
- * Usage:
16
- * node scripts/bench/v3-ceremony.mjs [--tsv]
17
- */
18
-
19
- import fs from 'node:fs/promises';
20
- import path from 'node:path';
21
- import os from 'node:os';
22
- import { fileURLToPath } from 'node:url';
23
-
24
- import { buildCodeIndex } from '../../src/index/buildIndex.js';
25
- import { deriveTaskRoute } from '../../src/index/taskRouting.js';
26
- import { V3_ROUTE_CORPUS } from '../../tests/fixtures/v3RouteCorpus.js';
27
-
28
- const REPO_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../..');
29
-
30
- // fastPath off vs on; rigor stays 'shadow' in both runs so riskFloor is emitted
31
- // and the only moving part is the Fast Path stage itself.
32
- const CONFIG_OFF = { routing: { rigor: { stage: 'shadow' }, fastPath: { stage: 'off' } } };
33
- const CONFIG_ON = { routing: { rigor: { stage: 'shadow' }, fastPath: { stage: 'shadow' } } };
34
-
35
- async function createFixtureFile(rootDir, relativePath, contents = 'export default true;\n') {
36
- const absolutePath = path.join(rootDir, relativePath);
37
- await fs.mkdir(path.dirname(absolutePath), { recursive: true });
38
- await fs.writeFile(absolutePath, contents, 'utf8');
39
- }
40
-
41
- // Same seeded project shape as the corpus test — the ladder fixture plus the
42
- // db/migrations tree the schema-change cases target.
43
- async function seedFixtureProject(rootDir) {
44
- await fs.mkdir(path.join(rootDir, '.claude', 'skills'), { recursive: true });
45
- await fs.writeFile(
46
- path.join(rootDir, 'package.json'),
47
- JSON.stringify({
48
- packageManager: 'yarn@1.22.22',
49
- scripts: {
50
- test: 'vitest',
51
- lint: 'eslint .',
52
- typecheck: 'tsc --noEmit',
53
- },
54
- }, null, 2),
55
- 'utf8',
56
- );
57
-
58
- await createFixtureFile(rootDir, 'src/core/fileOps.js', 'export function writeFileAtomic(input) { return input; }\n');
59
- await createFixtureFile(rootDir, 'src/core/applyPlan.js', 'export function applyPlan(plan) { return plan; }\n');
60
- await createFixtureFile(rootDir, 'src/pages/AdminHome.js', 'export function AdminHome() { return true; }\n');
61
- await createFixtureFile(rootDir, 'src/api/auth/login.js', 'export async function login() { return { ok: true }; }\n');
62
- await createFixtureFile(rootDir, 'src/db/migrations/001_init.sql', 'CREATE TABLE sessions (id text);\n');
63
- await createFixtureFile(rootDir, 'src/db/migrations/002_drop_sessions.sql', 'DROP TABLE sessions;\n');
64
- await createFixtureFile(rootDir, '.claude/hooks/skill-router.sh', '#!/bin/bash\necho skill-router\n');
65
- await createFixtureFile(rootDir, 'template_project/.claude/ukit/runtime/reinject-context.mjs', 'export function reinject() { return true; }\n');
66
- await createFixtureFile(rootDir, 'template_project/.claude/ukit/index/route-task.mjs', 'export function routeTask() { return true; }\n');
67
- await createFixtureFile(rootDir, 'template_project/ukit/storage/config.json', '{ "version": "1.4.2" }\n');
68
-
69
- await buildCodeIndex({ rootDir });
70
- }
71
-
72
- // The planned-ceremony surface of one route: which skills were activated, which
73
- // helper commands were planned, which advisory blocks were emitted, and what
74
- // Fast Path suppressed.
75
- function measureRoute(route) {
76
- const summary = route?.routeSummary ?? {};
77
- const helperCommands = [
78
- ...(summary.primaryCommands ?? []),
79
- ...(summary.fallbackCommands ?? []),
80
- summary.helperHint,
81
- summary.nextActionCommand,
82
- ].filter(Boolean);
83
- const advisoryBlocks = [
84
- summary.workflowPolicy ? 'workflowPolicy' : null,
85
- summary.principleIndex ? 'principleIndex' : null,
86
- summary.modelRolesBlock ? 'modelRolesBlock' : null,
87
- ].filter(Boolean);
88
- return {
89
- executionMode: summary.executionMode ?? route?.routingContext?.executionMode ?? null,
90
- riskFloor: summary.riskFloor?.floor ?? null,
91
- skills: (route?.activeSkills ?? []).map((entry) => entry.id),
92
- helperCommands: [...new Set(helperCommands)],
93
- advisoryBlocks,
94
- eligible: summary.fastPath?.eligible ?? null,
95
- suppressed: summary.fastPath?.suppressed ?? [],
96
- };
97
- }
98
-
99
- async function measureCase(rootDir, entry, runtimeConfig) {
100
- const started = performance.now();
101
- const route = await deriveTaskRoute({
102
- rootDir,
103
- promptText: entry.prompt,
104
- commandText: entry.commandText ?? '',
105
- targetFile: entry.targetFile,
106
- commandNamespace: '.codex',
107
- runtimeConfig,
108
- });
109
- return { ...measureRoute(route), elapsedMs: Math.round(performance.now() - started) };
110
- }
111
-
112
- async function runCase(rootDir, entry) {
113
- const row = { name: entry.name, lang: entry.lang, targetFile: entry.targetFile ?? null };
114
- try {
115
- row.fastPathOff = await measureCase(rootDir, entry, CONFIG_OFF);
116
- } catch (error) {
117
- row.fastPathOff = { error: error?.message ?? String(error) };
118
- }
119
- try {
120
- row.fastPathOn = await measureCase(rootDir, entry, CONFIG_ON);
121
- } catch (error) {
122
- row.fastPathOn = { error: error?.message ?? String(error) };
123
- }
124
- if (row.fastPathOff.error || row.fastPathOn.error) {
125
- row.error = row.fastPathOff.error ?? row.fastPathOn.error;
126
- }
127
- return row;
128
- }
129
-
130
- function sumMetric(cases, side, metric) {
131
- return cases.reduce((total, entry) => total + (entry[side]?.[metric]?.length ?? 0), 0);
132
- }
133
-
134
- function buildSummary(cases) {
135
- const totals = {};
136
- for (const side of ['fastPathOff', 'fastPathOn']) {
137
- totals[side] = {
138
- skills: sumMetric(cases, side, 'skills'),
139
- helperCommands: sumMetric(cases, side, 'helperCommands'),
140
- advisoryBlocks: sumMetric(cases, side, 'advisoryBlocks'),
141
- suppressed: sumMetric(cases, side, 'suppressed'),
142
- elapsedMs: cases.reduce((total, entry) => total + (entry[side]?.elapsedMs ?? 0), 0),
143
- };
144
- }
145
- const fastPathEligibleCount = cases.filter((entry) => entry.fastPathOn?.eligible === true).length;
146
- return {
147
- caseCount: cases.length,
148
- fastPathOff: totals.fastPathOff,
149
- fastPathOn: totals.fastPathOn,
150
- delta: {
151
- skills: totals.fastPathOn.skills - totals.fastPathOff.skills,
152
- helperCommands: totals.fastPathOn.helperCommands - totals.fastPathOff.helperCommands,
153
- advisoryBlocks: totals.fastPathOn.advisoryBlocks - totals.fastPathOff.advisoryBlocks,
154
- suppressed: totals.fastPathOn.suppressed - totals.fastPathOff.suppressed,
155
- elapsedMs: totals.fastPathOn.elapsedMs - totals.fastPathOff.elapsedMs,
156
- fastPathEligibleCount,
157
- },
158
- };
159
- }
160
-
161
- function renderTsv(report) {
162
- const header = [
163
- 'name', 'mode', 'riskFloor', 'eligible',
164
- 'off.skills', 'off.helpers', 'off.advisory', 'off.suppressed', 'off.ms',
165
- 'on.skills', 'on.helpers', 'on.advisory', 'on.suppressed', 'on.ms',
166
- ];
167
- const cell = (value) => String(value ?? '').replaceAll('\t', ' ');
168
- const rows = report.cases.map((entry) => {
169
- const off = entry.fastPathOff ?? {};
170
- const on = entry.fastPathOn ?? {};
171
- return [
172
- entry.name,
173
- on.executionMode ?? off.executionMode,
174
- on.riskFloor ?? off.riskFloor,
175
- on.eligible,
176
- off.skills?.length, off.helperCommands?.length, off.advisoryBlocks?.length, off.suppressed?.length, off.elapsedMs,
177
- on.skills?.length, on.helperCommands?.length, on.advisoryBlocks?.length, on.suppressed?.length, on.elapsedMs,
178
- ].map(cell).join('\t');
179
- });
180
- const d = report.summary.delta;
181
- rows.push([
182
- 'SUMMARY', `${report.summary.caseCount} cases`, '', `eligible=${d.fastPathEligibleCount}`,
183
- report.summary.fastPathOff.skills, report.summary.fastPathOff.helperCommands,
184
- report.summary.fastPathOff.advisoryBlocks, report.summary.fastPathOff.suppressed,
185
- report.summary.fastPathOff.elapsedMs,
186
- report.summary.fastPathOn.skills, report.summary.fastPathOn.helperCommands,
187
- report.summary.fastPathOn.advisoryBlocks, report.summary.fastPathOn.suppressed,
188
- report.summary.fastPathOn.elapsedMs,
189
- ].map(cell).join('\t'));
190
- return [header.join('\t'), ...rows].join('\n');
191
- }
192
-
193
- async function main() {
194
- const args = process.argv.slice(2);
195
- const unknown = args.filter((arg) => arg !== '--tsv');
196
- if (unknown.length > 0) {
197
- console.error(`usage: v3-ceremony.mjs [--tsv]\nunknown argument: ${unknown[0]}`);
198
- process.exit(2);
199
- }
200
- const tsv = args.includes('--tsv');
201
- const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'ukit-v3-ceremony-'));
202
- try {
203
- await seedFixtureProject(tmpDir);
204
- const cases = [];
205
- for (const entry of V3_ROUTE_CORPUS) {
206
- cases.push(await runCase(tmpDir, entry));
207
- }
208
- const report = { cases, summary: buildSummary(cases) };
209
- console.log(tsv ? renderTsv(report) : JSON.stringify(report, null, 2));
210
- } finally {
211
- await fs.rm(tmpDir, { recursive: true, force: true });
212
- }
213
- }
214
-
215
- // Measurement tool, not a gate: even a catastrophic failure reports and exits 0.
216
- try {
217
- await main();
218
- } catch (error) {
219
- console.log(JSON.stringify({ cases: [], summary: null, fatal: error?.message ?? String(error) }));
220
- }