selftune 0.2.30 → 0.2.32

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 (102) hide show
  1. package/README.md +83 -56
  2. package/apps/local-dashboard/dist/assets/index-B-ut4w0B.js +15 -0
  3. package/apps/local-dashboard/dist/assets/index-BFGfCVrL.css +1 -0
  4. package/apps/local-dashboard/dist/assets/vendor-ui-DfowE3Hu.js +1 -0
  5. package/apps/local-dashboard/dist/index.html +3 -3
  6. package/cli/selftune/command-surface.ts +613 -2
  7. package/cli/selftune/create/baseline.ts +429 -0
  8. package/cli/selftune/create/check.ts +35 -0
  9. package/cli/selftune/create/init.ts +115 -0
  10. package/cli/selftune/create/package-candidate-state.ts +771 -0
  11. package/cli/selftune/create/package-evaluator.ts +710 -0
  12. package/cli/selftune/create/package-fingerprint.ts +142 -0
  13. package/cli/selftune/create/package-search.ts +377 -0
  14. package/cli/selftune/create/publish.ts +431 -0
  15. package/cli/selftune/create/readiness.ts +495 -0
  16. package/cli/selftune/create/replay.ts +330 -0
  17. package/cli/selftune/create/report.ts +74 -0
  18. package/cli/selftune/create/scaffold.ts +121 -0
  19. package/cli/selftune/create/skills-ref-adapter.ts +177 -0
  20. package/cli/selftune/create/status.ts +33 -0
  21. package/cli/selftune/create/templates.ts +249 -0
  22. package/cli/selftune/cron/setup.ts +1 -1
  23. package/cli/selftune/dashboard-action-events.ts +4 -1
  24. package/cli/selftune/dashboard-action-result.ts +789 -24
  25. package/cli/selftune/dashboard-action-stream.ts +80 -0
  26. package/cli/selftune/dashboard-contract.ts +146 -3
  27. package/cli/selftune/dashboard-server.ts +5 -4
  28. package/cli/selftune/eval/hooks-to-evals.ts +58 -35
  29. package/cli/selftune/eval/synthetic-evals.ts +145 -17
  30. package/cli/selftune/evolution/bounded-mutations.ts +1045 -0
  31. package/cli/selftune/evolution/evolve-body.ts +9 -36
  32. package/cli/selftune/evolution/evolve.ts +8 -72
  33. package/cli/selftune/evolution/stopping-criteria.ts +5 -13
  34. package/cli/selftune/evolution/unblock-suggestions.ts +0 -16
  35. package/cli/selftune/evolution/validate-host-replay.ts +115 -15
  36. package/cli/selftune/improve.ts +206 -0
  37. package/cli/selftune/index.ts +123 -6
  38. package/cli/selftune/init.ts +1 -1
  39. package/cli/selftune/localdb/queries/dashboard.ts +30 -0
  40. package/cli/selftune/localdb/schema.ts +52 -0
  41. package/cli/selftune/monitoring/watch.ts +257 -23
  42. package/cli/selftune/orchestrate/execute.ts +300 -1
  43. package/cli/selftune/orchestrate/finalize.ts +14 -0
  44. package/cli/selftune/orchestrate/plan.ts +22 -5
  45. package/cli/selftune/orchestrate/prepare.ts +59 -4
  46. package/cli/selftune/orchestrate/report.ts +1 -1
  47. package/cli/selftune/orchestrate.ts +34 -1
  48. package/cli/selftune/publish.ts +35 -0
  49. package/cli/selftune/registry/github-install.ts +256 -0
  50. package/cli/selftune/registry/index.ts +1 -1
  51. package/cli/selftune/registry/install.ts +58 -7
  52. package/cli/selftune/routes/actions.ts +81 -15
  53. package/cli/selftune/routes/overview.ts +1 -1
  54. package/cli/selftune/routes/skill-report.ts +147 -2
  55. package/cli/selftune/run.ts +18 -0
  56. package/cli/selftune/schedule.ts +3 -3
  57. package/cli/selftune/search-run.ts +703 -0
  58. package/cli/selftune/status.ts +35 -11
  59. package/cli/selftune/testing-readiness.ts +431 -40
  60. package/cli/selftune/types.ts +316 -0
  61. package/cli/selftune/utils/eval-readiness.ts +1 -0
  62. package/cli/selftune/utils/json-output.ts +11 -0
  63. package/cli/selftune/utils/lifecycle-surface.ts +48 -0
  64. package/cli/selftune/utils/query-filter.ts +82 -1
  65. package/cli/selftune/utils/tui.ts +85 -2
  66. package/cli/selftune/verify.ts +205 -0
  67. package/cli/selftune/workflows/proposals.ts +1 -1
  68. package/cli/selftune/workflows/skill-scaffold.ts +141 -63
  69. package/cli/selftune/workflows/workflows.ts +4 -4
  70. package/package.json +1 -1
  71. package/packages/dashboard-core/src/routes/manifest.ts +2 -2
  72. package/packages/ui/src/components/SkillReportPanels.tsx +7 -7
  73. package/packages/ui/src/primitives/button.tsx +5 -0
  74. package/skill/SKILL.md +148 -85
  75. package/skill/references/cli-quick-reference.md +16 -1
  76. package/skill/references/creator-playbook.md +31 -10
  77. package/skill/workflows/Baseline.md +8 -9
  78. package/skill/workflows/Contributions.md +4 -4
  79. package/skill/workflows/Create.md +173 -0
  80. package/skill/workflows/CreateTestDeploy.md +34 -30
  81. package/skill/workflows/Cron.md +2 -2
  82. package/skill/workflows/Dashboard.md +3 -3
  83. package/skill/workflows/Evals.md +13 -7
  84. package/skill/workflows/Evolve.md +75 -32
  85. package/skill/workflows/EvolveBody.md +22 -15
  86. package/skill/workflows/Hook.md +1 -1
  87. package/skill/workflows/Improve.md +168 -0
  88. package/skill/workflows/Initialize.md +3 -3
  89. package/skill/workflows/Orchestrate.md +49 -12
  90. package/skill/workflows/Publish.md +100 -0
  91. package/skill/workflows/Registry.md +19 -13
  92. package/skill/workflows/Run.md +72 -0
  93. package/skill/workflows/Schedule.md +2 -2
  94. package/skill/workflows/SearchRun.md +89 -0
  95. package/skill/workflows/SignalsDashboard.md +2 -2
  96. package/skill/workflows/UnitTest.md +13 -4
  97. package/skill/workflows/Verify.md +136 -0
  98. package/skill/workflows/Watch.md +114 -47
  99. package/skill/workflows/Workflows.md +13 -8
  100. package/apps/local-dashboard/dist/assets/index-BcXquWFB.css +0 -1
  101. package/apps/local-dashboard/dist/assets/index-Coq42hE4.js +0 -15
  102. package/apps/local-dashboard/dist/assets/vendor-ui-B0H8s1mP.js +0 -1
@@ -0,0 +1,206 @@
1
+ import { existsSync } from "node:fs";
2
+ import { basename, dirname, join } from "node:path";
3
+
4
+ import { selectAcceptedPackageFrontierCandidate } from "./create/package-candidate-state.js";
5
+ import { readCanonicalPackageEvaluationArtifact } from "./testing-readiness.js";
6
+ import { PUBLIC_COMMAND_SURFACES, renderCommandHelp } from "./command-surface.js";
7
+ import { CLIError, handleCLIError } from "./utils/cli-error.js";
8
+
9
+ type ImproveScope = "auto" | "description" | "routing" | "body" | "package";
10
+
11
+ export interface ImproveDeps {
12
+ evolveCliMain?: () => Promise<void>;
13
+ evolveBodyCliMain?: () => Promise<void>;
14
+ searchRunCliMain?: () => Promise<void>;
15
+ }
16
+
17
+ function readOptionValue(args: readonly string[], flag: string): string | undefined {
18
+ for (let index = 0; index < args.length; index += 1) {
19
+ const arg = args[index];
20
+ if (arg === flag) {
21
+ const next = args[index + 1];
22
+ return next && !next.startsWith("-") ? next : undefined;
23
+ }
24
+ if (arg.startsWith(`${flag}=`)) {
25
+ return arg.slice(flag.length + 1);
26
+ }
27
+ }
28
+ return undefined;
29
+ }
30
+
31
+ function stripOption(args: readonly string[], flag: string): string[] {
32
+ const result: string[] = [];
33
+ for (let index = 0; index < args.length; index += 1) {
34
+ const arg = args[index];
35
+ if (arg === flag) {
36
+ const next = args[index + 1];
37
+ if (next && !next.startsWith("-")) {
38
+ index += 1;
39
+ }
40
+ continue;
41
+ }
42
+ if (arg.startsWith(`${flag}=`)) {
43
+ continue;
44
+ }
45
+ result.push(arg);
46
+ }
47
+ return result;
48
+ }
49
+
50
+ function hasOption(args: readonly string[], flag: string): boolean {
51
+ return args.includes(flag) || args.some((arg) => arg.startsWith(`${flag}=`));
52
+ }
53
+
54
+ function replaceOption(args: readonly string[], sourceFlag: string, targetFlag: string): string[] {
55
+ const value = readOptionValue(args, sourceFlag);
56
+ if (value == null) {
57
+ return stripOption(args, sourceFlag);
58
+ }
59
+ const result = stripOption(args, sourceFlag);
60
+ result.push(targetFlag, value);
61
+ return result;
62
+ }
63
+
64
+ function resolveScope(rawScope: string | undefined): ImproveScope {
65
+ const scope = (rawScope ?? "auto") as ImproveScope;
66
+ if (!["auto", "description", "routing", "body", "package"].includes(scope)) {
67
+ throw new CLIError(
68
+ `Invalid --scope value: ${rawScope}`,
69
+ "INVALID_FLAG",
70
+ "Use one of: auto, description, routing, body, package",
71
+ );
72
+ }
73
+ return scope;
74
+ }
75
+
76
+ function inferSkillNameFromArgs(args: readonly string[]): string | null {
77
+ const explicitSkill = readOptionValue(args, "--skill");
78
+ if (explicitSkill) return explicitSkill;
79
+
80
+ const skillPath = readOptionValue(args, "--skill-path");
81
+ if (!skillPath) return null;
82
+ return basename(dirname(skillPath));
83
+ }
84
+
85
+ function shouldAutoSelectPackageScope(args: readonly string[]): boolean {
86
+ const skillPath = readOptionValue(args, "--skill-path");
87
+ if (!skillPath) return false;
88
+
89
+ if (existsSync(join(dirname(skillPath), "selftune.create.json"))) {
90
+ return true;
91
+ }
92
+
93
+ const skillName = inferSkillNameFromArgs(args);
94
+ if (!skillName) return false;
95
+
96
+ return (
97
+ selectAcceptedPackageFrontierCandidate(skillName) != null ||
98
+ readCanonicalPackageEvaluationArtifact(skillName) != null
99
+ );
100
+ }
101
+
102
+ export async function runImprove(
103
+ rawArgs: readonly string[],
104
+ deps: ImproveDeps = {},
105
+ ): Promise<void> {
106
+ const { evolveCliMain, evolveBodyCliMain, searchRunCliMain } = deps;
107
+
108
+ if (rawArgs.includes("--help") || rawArgs.includes("-h")) {
109
+ console.log(renderCommandHelp(PUBLIC_COMMAND_SURFACES.improve));
110
+ process.exit(0);
111
+ }
112
+
113
+ const requestedScope = readOptionValue(rawArgs, "--scope");
114
+ if (rawArgs.includes("--scope") && requestedScope == null) {
115
+ throw new CLIError(
116
+ "--scope requires a value.",
117
+ "MISSING_FLAG",
118
+ "Use one of: auto, description, routing, body, package",
119
+ );
120
+ }
121
+
122
+ const scope = resolveScope(requestedScope);
123
+ const effectiveScope =
124
+ scope === "auto" && shouldAutoSelectPackageScope(rawArgs) ? "package" : scope;
125
+ let delegatedArgs = stripOption(rawArgs, "--scope");
126
+
127
+ if (hasOption(delegatedArgs, "--target")) {
128
+ throw new CLIError(
129
+ "Use --scope on selftune improve instead of passing --target directly.",
130
+ "INVALID_FLAG",
131
+ "selftune improve --skill <name> --skill-path <path> --scope routing|body",
132
+ );
133
+ }
134
+
135
+ if (effectiveScope === "package") {
136
+ const dryRunRequested = hasOption(delegatedArgs, "--dry-run");
137
+ const validationMode = readOptionValue(delegatedArgs, "--validation-mode");
138
+ if (hasOption(delegatedArgs, "--validation-mode")) {
139
+ if (validationMode == null) {
140
+ throw new CLIError(
141
+ "--validation-mode requires a value.",
142
+ "MISSING_FLAG",
143
+ "Use one of: auto, replay",
144
+ );
145
+ }
146
+ if (!["auto", "replay"].includes(validationMode)) {
147
+ throw new CLIError(
148
+ "Package search uses replay-backed package evaluation and does not support judge-only validation.",
149
+ "INVALID_FLAG",
150
+ "Use selftune improve --scope package without --validation-mode, or set --validation-mode replay",
151
+ );
152
+ }
153
+ delegatedArgs = stripOption(delegatedArgs, "--validation-mode");
154
+ }
155
+
156
+ delegatedArgs = stripOption(delegatedArgs, "--dry-run");
157
+
158
+ if (hasOption(delegatedArgs, "--candidates") && !hasOption(delegatedArgs, "--max-candidates")) {
159
+ delegatedArgs = replaceOption(delegatedArgs, "--candidates", "--max-candidates");
160
+ }
161
+ if (!dryRunRequested && !hasOption(delegatedArgs, "--apply-winner")) {
162
+ delegatedArgs.push("--apply-winner");
163
+ }
164
+
165
+ process.argv = [process.argv[0], process.argv[1], ...delegatedArgs];
166
+ const { cliMain: delegatedCliMain } = searchRunCliMain
167
+ ? { cliMain: searchRunCliMain }
168
+ : await import("./search-run.js");
169
+ await delegatedCliMain();
170
+ return;
171
+ }
172
+
173
+ if (effectiveScope === "routing" || effectiveScope === "body") {
174
+ const delegatedAgent = readOptionValue(delegatedArgs, "--agent");
175
+ if (
176
+ delegatedAgent &&
177
+ !hasOption(delegatedArgs, "--teacher-agent") &&
178
+ !hasOption(delegatedArgs, "--student-agent")
179
+ ) {
180
+ delegatedArgs = stripOption(delegatedArgs, "--agent");
181
+ delegatedArgs.push("--teacher-agent", delegatedAgent, "--student-agent", delegatedAgent);
182
+ }
183
+
184
+ delegatedArgs.push("--target", effectiveScope);
185
+ process.argv = [process.argv[0], process.argv[1], ...delegatedArgs];
186
+ const { cliMain: delegatedCliMain } = evolveBodyCliMain
187
+ ? { cliMain: evolveBodyCliMain }
188
+ : await import("./evolution/evolve-body.js");
189
+ await delegatedCliMain();
190
+ return;
191
+ }
192
+
193
+ process.argv = [process.argv[0], process.argv[1], ...delegatedArgs];
194
+ const { cliMain: delegatedCliMain } = evolveCliMain
195
+ ? { cliMain: evolveCliMain }
196
+ : await import("./evolution/evolve.js");
197
+ await delegatedCliMain();
198
+ }
199
+
200
+ export async function cliMain(): Promise<void> {
201
+ await runImprove(process.argv.slice(2));
202
+ }
203
+
204
+ if (import.meta.main) {
205
+ cliMain().catch(handleCLIError);
206
+ }
@@ -6,9 +6,15 @@
6
6
  * selftune ingest <agent> — Ingest agent sessions (claude, codex, opencode, openclaw, pi, wrap-codex)
7
7
  * selftune grade [mode] — Grade skill sessions (auto, baseline)
8
8
  * selftune evolve [target] — Evolve skill descriptions (body, rollback)
9
+ * selftune improve — Simplified alias for evolve / evolve body / search-run
10
+ * selftune search-run — Run bounded package search over routing/body variants
9
11
  * selftune eval <action> — Evaluation tools (generate, unit-test, import, composability, family-overlap)
12
+ * selftune create <sub> — Draft full skill packages
13
+ * selftune verify — Verify a draft skill package
14
+ * selftune publish — Publish a verified draft package
10
15
  * selftune sync — Sync source-truth telemetry across supported agents
11
16
  * selftune orchestrate — Run autonomous core loop (sync → status → evolve → watch)
17
+ * selftune run — Simplified alias for orchestrate
12
18
  * selftune init — Initialize agent identity and config
13
19
  * selftune uninstall — Clean removal of all selftune data and config
14
20
  * selftune status — Show skill health summary
@@ -52,19 +58,27 @@ if (command === "--help" || command === "-h") {
52
58
  Usage:
53
59
  selftune <command> [options]
54
60
 
55
- Commands:
56
- ingest <agent> Ingest agent sessions (claude, codex, opencode, openclaw, pi, wrap-codex)
57
- grade [mode] Grade skill sessions (auto, baseline)
61
+ Primary Lifecycle:
62
+ status Show skill health summary
63
+ verify Verify a draft skill package
64
+ publish Publish a verified draft package
65
+ improve Improve skills with measured evidence
66
+ run Run autonomous improvement loop
67
+ create <sub> Draft full skill packages
68
+ dashboard Open visual data dashboard
69
+
70
+ Advanced / Stage Commands:
58
71
  evolve [target] Evolve skill descriptions (body, rollback)
72
+ search-run Run bounded package search over routing/body variants
59
73
  eval <action> Evaluation tools (generate, unit-test, import, composability, family-overlap)
74
+ grade [mode] Grade skill sessions (auto, baseline)
75
+ watch Monitor post-deploy skill health
60
76
  sync Sync source-truth telemetry across supported agents
61
77
  orchestrate Run autonomous core loop (sync → status → evolve → watch)
78
+ ingest <agent> Ingest agent sessions (claude, codex, opencode, openclaw, pi, wrap-codex)
62
79
  init Initialize agent identity and config
63
80
  uninstall Clean removal of all selftune data and config
64
- status Show skill health summary
65
- watch Monitor post-deploy skill health
66
81
  doctor Run health checks
67
- dashboard Open visual data dashboard
68
82
  last Show last session details
69
83
  cron Scheduling & automation (setup, list, remove)
70
84
  badge Generate skill health badges for READMEs
@@ -276,6 +290,18 @@ Run 'selftune evolve <subcommand> --help' for subcommand-specific options.`);
276
290
  break;
277
291
  }
278
292
 
293
+ case "improve": {
294
+ const { cliMain } = await import("./improve.js");
295
+ await cliMain();
296
+ break;
297
+ }
298
+
299
+ case "search-run": {
300
+ const { cliMain } = await import("./search-run.js");
301
+ await cliMain();
302
+ break;
303
+ }
304
+
279
305
  case "eval": {
280
306
  const sub = process.argv[2];
281
307
  if (!sub || sub === "--help" || sub === "-h") {
@@ -417,6 +443,91 @@ Run 'selftune eval <action> --help' for action-specific options.`);
417
443
  break;
418
444
  }
419
445
 
446
+ case "verify": {
447
+ const { cliMain } = await import("./verify.js");
448
+ await cliMain();
449
+ break;
450
+ }
451
+
452
+ case "publish": {
453
+ const { cliMain } = await import("./publish.js");
454
+ await cliMain();
455
+ break;
456
+ }
457
+
458
+ case "create": {
459
+ const sub = process.argv[2];
460
+ if (!sub || sub === "--help" || sub === "-h") {
461
+ console.log(`selftune create — Draft full skill packages
462
+
463
+ Usage:
464
+ selftune create <subcommand> [options]
465
+
466
+ Subcommands:
467
+ init Initialize a new skill package scaffold
468
+ status Show current draft-package readiness
469
+ scaffold Scaffold a package from an observed workflow
470
+ check Validate package readiness and recommend the next step
471
+ replay Run replay validation for the current draft package
472
+ baseline Measure with-skill vs no-skill lift for the draft package
473
+ report Render a benchmark-style report for the current draft package
474
+ publish Publish a validated draft package and optionally start watch
475
+
476
+ Run 'selftune create <subcommand> --help' for subcommand-specific options.`);
477
+ process.exit(0);
478
+ }
479
+ process.argv = [process.argv[0], process.argv[1], ...process.argv.slice(3)];
480
+ switch (sub) {
481
+ case "init": {
482
+ const { cliMain } = await import("./create/init.js");
483
+ await cliMain();
484
+ break;
485
+ }
486
+ case "status": {
487
+ const { cliMain } = await import("./create/status.js");
488
+ await cliMain();
489
+ break;
490
+ }
491
+ case "scaffold": {
492
+ const { cliMain } = await import("./create/scaffold.js");
493
+ await cliMain();
494
+ break;
495
+ }
496
+ case "check": {
497
+ const { cliMain } = await import("./create/check.js");
498
+ await cliMain();
499
+ break;
500
+ }
501
+ case "replay": {
502
+ const { cliMain } = await import("./create/replay.js");
503
+ await cliMain();
504
+ break;
505
+ }
506
+ case "baseline": {
507
+ const { cliMain } = await import("./create/baseline.js");
508
+ await cliMain();
509
+ break;
510
+ }
511
+ case "report": {
512
+ const { cliMain } = await import("./create/report.js");
513
+ await cliMain();
514
+ break;
515
+ }
516
+ case "publish": {
517
+ const { cliMain } = await import("./create/publish.js");
518
+ await cliMain();
519
+ break;
520
+ }
521
+ default:
522
+ throw new CLIError(
523
+ `Unknown create subcommand: ${sub}`,
524
+ "UNKNOWN_COMMAND",
525
+ "selftune create --help",
526
+ );
527
+ }
528
+ break;
529
+ }
530
+
420
531
  // ── Unchanged commands ────────────────────────────────────────────────
421
532
 
422
533
  case "init": {
@@ -659,6 +770,12 @@ Options:
659
770
  await cliMain();
660
771
  break;
661
772
  }
773
+
774
+ case "run": {
775
+ const { cliMain } = await import("./run.js");
776
+ await cliMain();
777
+ break;
778
+ }
662
779
  case "registry": {
663
780
  const { cliMain } = await import("./registry/index.js");
664
781
  await cliMain();
@@ -959,7 +959,7 @@ export async function cliMain(): Promise<void> {
959
959
  level: "info",
960
960
  code: "alpha_upload_ready",
961
961
  message:
962
- "Alpha enrollment complete. Uploads will run automatically during 'selftune orchestrate'. To enable scheduled background sync (includes evolve + watch + upload), run: selftune cron setup",
962
+ "Alpha enrollment complete. Uploads will run automatically during 'selftune run'. To enable scheduled background sync (includes evolve + watch + upload), run: selftune cron setup",
963
963
  next_command: "selftune alpha upload",
964
964
  optional_autonomy: "selftune cron setup",
965
965
  }),
@@ -14,6 +14,7 @@ import type {
14
14
  SkillUsageRecord,
15
15
  TelemetryRecord,
16
16
  } from "../../dashboard-contract.js";
17
+ import { computeCreateDashboardReadiness, isCreateSkillDraft } from "../../create/readiness.js";
17
18
  import { queryEvolutionEvidence, getPendingProposals } from "./evolution.js";
18
19
  import { safeParseJsonArray } from "./json.js";
19
20
  import { queryTrustedSkillObservationRows } from "./trust.js";
@@ -596,7 +597,29 @@ export function getSkillsList(
596
597
  const testingReadinessBySkill = new Map(
597
598
  testingReadiness.map((row) => [row.skill_name, row] as const),
598
599
  );
600
+ const createReadinessBySkill = new Map(
601
+ testingReadiness
602
+ .flatMap((row) => {
603
+ if (!row.skill_path || !isCreateSkillDraft(row.skill_path)) return [];
604
+ try {
605
+ return [
606
+ [
607
+ row.skill_name,
608
+ computeCreateDashboardReadiness(row.skill_path, {
609
+ getTestingReadiness: () => row,
610
+ }),
611
+ ] as const,
612
+ ];
613
+ } catch {
614
+ return [];
615
+ }
616
+ })
617
+ .filter(Boolean),
618
+ );
599
619
  const knownSkills = new Set<string>(bySkill.keys());
620
+ for (const skillName of createReadinessBySkill.keys()) {
621
+ knownSkills.add(skillName);
622
+ }
600
623
 
601
624
  return [...knownSkills]
602
625
  .map((skillName) => {
@@ -616,13 +639,19 @@ export function getSkillsList(
616
639
  withConfidence.length
617
640
  : null;
618
641
  const readiness = testingReadinessBySkill.get(skillName);
642
+ const createReadiness = createReadinessBySkill.get(skillName);
619
643
  const fallbackScope =
620
644
  readiness?.skill_path != null ? classifySkillPath(readiness.skill_path).skill_scope : null;
645
+ const createScope =
646
+ createReadiness?.skill_path != null
647
+ ? classifySkillPath(createReadiness.skill_path).skill_scope
648
+ : null;
621
649
 
622
650
  return {
623
651
  skill_name: skillName,
624
652
  skill_scope:
625
653
  scopeBySkill.get(skillName) ??
654
+ (createScope && createScope !== "unknown" ? createScope : null) ??
626
655
  (fallbackScope && fallbackScope !== "unknown" ? fallbackScope : null),
627
656
  total_checks: totalChecks,
628
657
  triggered_count: triggeredCount,
@@ -633,6 +662,7 @@ export function getSkillsList(
633
662
  routing_confidence: routingConfidence,
634
663
  confidence_coverage: totalChecks > 0 ? withConfidence.length / totalChecks : 0,
635
664
  testing_readiness: readiness,
665
+ create_readiness: createReadiness,
636
666
  };
637
667
  })
638
668
  .sort(
@@ -272,6 +272,32 @@ CREATE TABLE IF NOT EXISTS unit_test_run_results (
272
272
  result_json TEXT NOT NULL
273
273
  )`;
274
274
 
275
+ export const CREATE_PACKAGE_EVALUATION_REPORTS = `
276
+ CREATE TABLE IF NOT EXISTS package_evaluation_reports (
277
+ skill_name TEXT PRIMARY KEY,
278
+ stored_at TEXT NOT NULL,
279
+ summary_json TEXT NOT NULL
280
+ )`;
281
+
282
+ export const CREATE_PACKAGE_CANDIDATES = `
283
+ CREATE TABLE IF NOT EXISTS package_candidates (
284
+ candidate_id TEXT PRIMARY KEY,
285
+ skill_name TEXT NOT NULL,
286
+ skill_path TEXT NOT NULL,
287
+ package_fingerprint TEXT NOT NULL,
288
+ parent_candidate_id TEXT,
289
+ candidate_generation INTEGER NOT NULL DEFAULT 0,
290
+ evaluation_count INTEGER NOT NULL DEFAULT 0,
291
+ first_evaluated_at TEXT NOT NULL,
292
+ last_evaluated_at TEXT NOT NULL,
293
+ latest_status TEXT NOT NULL,
294
+ latest_evaluation_source TEXT,
295
+ latest_acceptance_decision TEXT,
296
+ artifact_path TEXT,
297
+ summary_json TEXT NOT NULL,
298
+ UNIQUE(skill_name, package_fingerprint)
299
+ )`;
300
+
275
301
  // -- Improvement signal table (from signal_log.jsonl) ------------------------
276
302
 
277
303
  export const CREATE_IMPROVEMENT_SIGNALS = `
@@ -365,6 +391,21 @@ CREATE TABLE IF NOT EXISTS cron_runs (
365
391
  UNIQUE(job_name, started_at)
366
392
  )`;
367
393
 
394
+ // -- Package search run table ------------------------------------------------
395
+
396
+ export const CREATE_PACKAGE_SEARCH_RUNS = `
397
+ CREATE TABLE IF NOT EXISTS package_search_runs (
398
+ search_id TEXT PRIMARY KEY,
399
+ skill_name TEXT NOT NULL,
400
+ parent_candidate_id TEXT,
401
+ winner_candidate_id TEXT,
402
+ winner_rationale TEXT,
403
+ candidates_evaluated INTEGER NOT NULL,
404
+ provenance_json TEXT NOT NULL,
405
+ started_at TEXT NOT NULL,
406
+ completed_at TEXT NOT NULL
407
+ )`;
408
+
368
409
  // -- Metadata table -----------------------------------------------------------
369
410
 
370
411
  export const CREATE_META = `
@@ -419,6 +460,9 @@ export const CREATE_INDEXES = [
419
460
  `CREATE INDEX IF NOT EXISTS idx_canonical_eval_sets_stored_at ON canonical_eval_sets(stored_at)`,
420
461
  `CREATE INDEX IF NOT EXISTS idx_unit_test_files_stored_at ON unit_test_files(stored_at)`,
421
462
  `CREATE INDEX IF NOT EXISTS idx_unit_test_run_results_run_at ON unit_test_run_results(run_at)`,
463
+ `CREATE INDEX IF NOT EXISTS idx_package_evaluation_reports_stored_at ON package_evaluation_reports(stored_at)`,
464
+ `CREATE INDEX IF NOT EXISTS idx_package_candidates_skill_ts ON package_candidates(skill_name, last_evaluated_at)`,
465
+ `CREATE INDEX IF NOT EXISTS idx_package_candidates_parent ON package_candidates(parent_candidate_id)`,
422
466
  // -- Improvement signal indexes ---------------------------------------------
423
467
  `CREATE INDEX IF NOT EXISTS idx_signals_session ON improvement_signals(session_id)`,
424
468
  `CREATE INDEX IF NOT EXISTS idx_signals_consumed ON improvement_signals(consumed)`,
@@ -447,6 +491,9 @@ export const CREATE_INDEXES = [
447
491
  `CREATE UNIQUE INDEX IF NOT EXISTS idx_commit_dedup ON commit_tracking(session_id, commit_sha)`,
448
492
  // -- Cron run indexes -------------------------------------------------------
449
493
  `CREATE INDEX IF NOT EXISTS idx_cron_runs_job_ts ON cron_runs(job_name, started_at)`,
494
+ // -- Package search run indexes ---------------------------------------------
495
+ `CREATE INDEX IF NOT EXISTS idx_pkg_search_skill ON package_search_runs(skill_name)`,
496
+ `CREATE INDEX IF NOT EXISTS idx_pkg_search_ts ON package_search_runs(started_at)`,
450
497
  ];
451
498
 
452
499
  /**
@@ -512,6 +559,8 @@ export const MIGRATIONS = [
512
559
  `ALTER TABLE session_telemetry ADD COLUMN agent_summary TEXT`,
513
560
  // -- SHA256 content hashing for upload dedup --
514
561
  `ALTER TABLE canonical_upload_staging ADD COLUMN content_sha256 TEXT`,
562
+ // -- Package candidate measured acceptance state --
563
+ `ALTER TABLE package_candidates ADD COLUMN latest_acceptance_decision TEXT`,
515
564
  ];
516
565
 
517
566
  /** Indexes that depend on migration columns — must run AFTER MIGRATIONS. */
@@ -540,6 +589,8 @@ export const ALL_DDL = [
540
589
  CREATE_CANONICAL_EVAL_SETS,
541
590
  CREATE_UNIT_TEST_FILES,
542
591
  CREATE_UNIT_TEST_RUN_RESULTS,
592
+ CREATE_PACKAGE_EVALUATION_REPORTS,
593
+ CREATE_PACKAGE_CANDIDATES,
543
594
  CREATE_IMPROVEMENT_SIGNALS,
544
595
  CREATE_UPLOAD_QUEUE,
545
596
  CREATE_CREATOR_CONTRIBUTION_STAGING,
@@ -547,6 +598,7 @@ export const ALL_DDL = [
547
598
  CREATE_CANONICAL_UPLOAD_STAGING,
548
599
  CREATE_COMMIT_TRACKING,
549
600
  CREATE_CRON_RUNS,
601
+ CREATE_PACKAGE_SEARCH_RUNS,
550
602
  CREATE_META,
551
603
  ...CREATE_INDEXES,
552
604
  ];