@kontextmind/kxm 0.6.0 → 0.7.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.
Files changed (117) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.kxm/agents/coordinator.yaml +9 -0
  3. package/.kxm/agents/critic-arch.yaml +13 -0
  4. package/.kxm/agents/critic-cli.yaml +13 -0
  5. package/.kxm/agents/implementer.yaml +13 -0
  6. package/.kxm/gates.yaml +8 -0
  7. package/.kxm/producers.yaml +22 -0
  8. package/.kxm/project.yaml +15 -0
  9. package/.kxm/roles/writer.yaml +5 -0
  10. package/.kxm/workflows/default.yaml +47 -0
  11. package/CHANGELOG.md +39 -7
  12. package/README.md +1 -0
  13. package/docs/README.md +2 -0
  14. package/docs/agent-skills.md +118 -0
  15. package/docs/architecture.md +1 -1
  16. package/docs/assignment-runner.md +21 -8
  17. package/docs/configuration.md +2 -2
  18. package/docs/kxm-handbook.md +3 -3
  19. package/docs/operator-pi-packages.md +63 -0
  20. package/docs/skills/repo-work-delivery.md +102 -0
  21. package/docs/test-matrix.md +4 -3
  22. package/docs/troubleshooting.md +19 -0
  23. package/docs/vnext/validation.md +9 -0
  24. package/docs/webhook-workflows.md +2 -2
  25. package/examples/README.md +1 -1
  26. package/package.json +16 -17
  27. package/plugins/kxm/.claude-plugin/plugin.json +1 -1
  28. package/plugins/kxm/README.md +1 -1
  29. package/plugins/kxm/dist/cli.js +6875 -3672
  30. package/plugins/kxm/dist/core.js +214 -34
  31. package/plugins/kxm/dist/extension.js +7721 -85
  32. package/plugins/kxm/dist/mcp-server.js +75 -21
  33. package/plugins/kxm/dist/runtime.js +5403 -1014
  34. package/plugins/kxm/dist/server.js +3008 -2268
  35. package/plugins/kxm/dist/vnext-runtime-supervisor.js +5751 -631
  36. package/plugins/kxm/package.json +1 -1
  37. package/plugins/kxm/skills/SUITE.md +5 -0
  38. package/plugins/kxm/skills/hints.json +73 -0
  39. package/plugins/kxm/skills/kxm/SKILL.md +30 -83
  40. package/plugins/kxm/skills/kxm-context-memory/SKILL.md +69 -0
  41. package/plugins/kxm/skills/kxm-definitions/SKILL.md +65 -0
  42. package/plugins/kxm/skills/kxm-harness-auth/SKILL.md +34 -0
  43. package/plugins/kxm/skills/kxm-harvest/SKILL.md +48 -0
  44. package/plugins/kxm/skills/kxm-hub-ops/SKILL.md +34 -0
  45. package/plugins/kxm/skills/kxm-insights/SKILL.md +48 -0
  46. package/plugins/kxm/skills/kxm-mind/SKILL.md +59 -0
  47. package/plugins/kxm/skills/kxm-peer/SKILL.md +110 -0
  48. package/plugins/kxm/skills/kxm-project-setup/SKILL.md +35 -0
  49. package/plugins/kxm/skills/kxm-projects/SKILL.md +43 -0
  50. package/plugins/kxm/skills/kxm-protocol/SKILL.md +66 -0
  51. package/plugins/kxm/skills/kxm-query/SKILL.md +45 -0
  52. package/plugins/kxm/skills/kxm-routing-improve/SKILL.md +30 -0
  53. package/plugins/kxm/skills/kxm-runs/SKILL.md +29 -0
  54. package/plugins/kxm/skills/kxm-setup/SKILL.md +55 -0
  55. package/plugins/kxm/skills/kxm-skill-lifecycle/SKILL.md +31 -0
  56. package/plugins/kxm/skills/kxm-tasks/SKILL.md +33 -0
  57. package/plugins/kxm/skills/kxm-triage/SKILL.md +47 -0
  58. package/plugins/kxm/skills/kxm-work/SKILL.md +44 -0
  59. package/plugins/kxm/skills/kxm-workflow/SKILL.md +45 -0
  60. package/plugins/kxm/src/autocomplete.ts +9 -3
  61. package/plugins/kxm/src/cli.ts +1077 -11
  62. package/plugins/kxm/src/commands.ts +150 -8
  63. package/plugins/kxm/src/config.ts +7 -4
  64. package/plugins/kxm/src/context-packet.ts +172 -0
  65. package/plugins/kxm/src/extension.ts +36 -1
  66. package/plugins/kxm/src/external-effects.ts +356 -7
  67. package/plugins/kxm/src/hub.ts +2 -4
  68. package/plugins/kxm/src/improve.ts +72 -0
  69. package/plugins/kxm/src/mcp-server.ts +1 -1
  70. package/plugins/kxm/src/model-inventory.ts +127 -0
  71. package/plugins/kxm/src/policy-draft.d.mts +55 -0
  72. package/plugins/kxm/src/policy-draft.mjs +565 -0
  73. package/plugins/kxm/src/price-calc.ts +17 -18
  74. package/plugins/kxm/src/prices.ts +32 -16
  75. package/plugins/kxm/src/producers.ts +71 -0
  76. package/plugins/kxm/src/restricted-yaml.d.mts +31 -0
  77. package/plugins/kxm/src/restricted-yaml.mjs +145 -0
  78. package/plugins/kxm/src/role.ts +375 -0
  79. package/plugins/kxm/src/routing.ts +99 -1
  80. package/plugins/kxm/src/session-work.ts +9 -2
  81. package/plugins/kxm/src/studio-layout.ts +660 -17
  82. package/plugins/kxm/src/suggest.ts +7 -13
  83. package/plugins/kxm/src/telemetry.ts +82 -0
  84. package/plugins/kxm/src/tui.ts +140 -0
  85. package/plugins/kxm/src/vnext-config.ts +15 -110
  86. package/plugins/kxm/src/vnext-engine.ts +198 -62
  87. package/plugins/kxm/src/vnext-harness.ts +263 -81
  88. package/plugins/kxm/src/vnext-oneshot-evidence.ts +85 -0
  89. package/plugins/kxm/src/vnext-oneshot-process.ts +149 -0
  90. package/plugins/kxm/src/vnext-oneshot-producer.ts +170 -233
  91. package/plugins/kxm/src/vnext-runtime-store.ts +35 -1
  92. package/plugins/kxm/src/vnext-runtime-supervisor.ts +120 -5
  93. package/plugins/kxm/src/vnext-runtime.ts +14 -0
  94. package/plugins/kxm/src/workflow-manager.ts +392 -0
  95. package/plugins/kxm/src/workflow-tui.ts +255 -0
  96. package/schemas/policy-draft/README.md +17 -0
  97. package/schemas/policy-draft/model.v2.schema.json +140 -0
  98. package/schemas/policy-draft/role.v2.schema.json +91 -0
  99. package/schemas/vnext/role.schema.json +76 -0
  100. package/schemas/vnext/run-event.schema.json +1 -0
  101. package/scripts/assignment-run.d.mts +1 -1
  102. package/scripts/assignment-run.mjs +44 -35
  103. package/scripts/check-generated.mjs +33 -9
  104. package/scripts/emit-codex-artifacts.mjs +255 -11
  105. package/scripts/harness-run.d.mts +12 -4
  106. package/scripts/harness-run.mjs +65 -17
  107. package/scripts/kxm-hub.mjs +6 -0
  108. package/scripts/native-critic.d.mts +5 -0
  109. package/scripts/native-critic.mjs +60 -0
  110. package/.kxm/config/README.md +0 -5
  111. package/.kxm/config/agents.json +0 -43
  112. package/.kxm/config/env.example +0 -56
  113. package/.kxm/config/update.example.yaml +0 -9
  114. package/.kxm/config/workflows/fix.json +0 -160
  115. package/.kxm/config/workflows/jira-development.json +0 -116
  116. package/.kxm/config/workflows/provenance-quorum.json +0 -150
  117. package/.kxm/config/workflows/v04-dogfood.json +0 -72
@@ -269,7 +269,15 @@ function isAbsoluteOn(path, platform) {
269
269
  return path.startsWith("/");
270
270
  }
271
271
 
272
- export function resolveLauncher(cliId, options = {}) {
272
+ /** Allowlisted npm-global inner launchers, relative to the directory that contains `name.cmd`. */
273
+ export const WIN_NPM_INNER_EXE = Object.freeze({
274
+ claude: Object.freeze(["node_modules", "@anthropic-ai", "claude-code", "bin", "claude.exe"]),
275
+ });
276
+ export const WIN_NPM_INNER_NODE_SCRIPT = Object.freeze({
277
+ pi: Object.freeze(["node_modules", "@earendil-works", "pi-coding-agent", "dist", "bundle", "cli.js"]),
278
+ });
279
+
280
+ export function resolveLaunch(cliId, options = {}) {
273
281
  const platform = options.platform ?? process.platform;
274
282
  const pathEnv = options.pathEnv ?? process.env.PATH ?? "";
275
283
  const exists = options.existsSync ?? existsSync;
@@ -282,25 +290,57 @@ export function resolveLauncher(cliId, options = {}) {
282
290
  if (cliId.includes("\0")) throw failClosed("launcher id is invalid");
283
291
 
284
292
  const explicit = cliId.includes("/") || cliId.includes("\\") || isAbsoluteOn(cliId, platform);
285
- if (explicit) return assertWinExecutable(cliId, platform, options);
293
+ if (explicit) return { command: assertWinExecutable(cliId, platform, options), args: [] };
286
294
 
287
295
  const dirs = pathEnv.split(delim).filter(Boolean);
288
296
  let rejectedShim;
289
- for (const dir of dirs) {
290
- if (platform === "win32") {
291
- const exeName = cliId.toLowerCase().endsWith(".exe") ? cliId : `${cliId}.exe`;
297
+ if (platform === "win32") {
298
+ const exeName = cliId.toLowerCase().endsWith(".exe") ? cliId : `${cliId}.exe`;
299
+ for (const dir of dirs) {
292
300
  const exe = path.join(dir, exeName);
293
- if (exists(exe)) return canonicalize(exe, { ...options, platform });
294
- for (const ext of [".cmd", ".bat", ".ps1", ""]) {
295
- const shim = path.join(dir, `${cliId}${ext}`);
296
- if (exists(shim)) {
297
- rejectedShim = shim;
298
- break;
301
+ if (exists(exe)) return { command: canonicalize(exe, { ...options, platform }), args: [] };
302
+ }
303
+ for (const dir of dirs) {
304
+ const cmdShim = path.join(dir, `${cliId}.cmd`);
305
+ if (!exists(cmdShim)) continue;
306
+ const exeSegs = WIN_NPM_INNER_EXE[cliId];
307
+ if (exeSegs) {
308
+ const inner = path.join(dir, ...exeSegs);
309
+ if (exists(inner)) {
310
+ return { command: assertWinExecutable(inner, platform, options), args: [] };
311
+ }
312
+ }
313
+ const scriptSegs = WIN_NPM_INNER_NODE_SCRIPT[cliId];
314
+ if (scriptSegs) {
315
+ const script = path.join(dir, ...scriptSegs);
316
+ const nodeExe = options.execPath ?? process.execPath;
317
+ if (exists(script) && exists(nodeExe)) {
318
+ return {
319
+ command: canonicalize(nodeExe, { ...options, platform }),
320
+ args: [canonicalize(script, { ...options, platform })],
321
+ };
299
322
  }
300
323
  }
301
- if (rejectedShim) break;
302
- } else if (exists(path.join(dir, cliId))) {
303
- return canonicalize(path.join(dir, cliId), { ...options, platform });
324
+ rejectedShim = cmdShim;
325
+ break;
326
+ }
327
+ if (!rejectedShim) {
328
+ for (const dir of dirs) {
329
+ for (const ext of [".bat", ".ps1", ""]) {
330
+ const shim = path.join(dir, `${cliId}${ext}`);
331
+ if (exists(shim)) {
332
+ rejectedShim = shim;
333
+ break;
334
+ }
335
+ }
336
+ if (rejectedShim) break;
337
+ }
338
+ }
339
+ } else {
340
+ for (const dir of dirs) {
341
+ if (exists(path.join(dir, cliId))) {
342
+ return { command: canonicalize(path.join(dir, cliId), { ...options, platform }), args: [] };
343
+ }
304
344
  }
305
345
  }
306
346
  if (rejectedShim) {
@@ -309,6 +349,10 @@ export function resolveLauncher(cliId, options = {}) {
309
349
  throw failClosed(`missing binary ${cliId}; install and authenticate the native CLI`);
310
350
  }
311
351
 
352
+ export function resolveLauncher(cliId, options = {}) {
353
+ return resolveLaunch(cliId, options).command;
354
+ }
355
+
312
356
  function canonicalize(target, options = {}) {
313
357
  const platform = options.platform ?? process.platform;
314
358
  if (platform === "win32" && process.platform !== "win32") return target;
@@ -510,6 +554,7 @@ export function buildArgv(request, ctx = {}) {
510
554
  "--sandbox",
511
555
  "read-only",
512
556
  "--ignore-user-config",
557
+ "-c", 'approval_policy="never"',
513
558
  ...(schemaPath ? ["--output-schema", schemaPath] : []),
514
559
  "--json",
515
560
  "-",
@@ -1572,19 +1617,22 @@ export async function runHarness(request, deps = {}) {
1572
1617
  schemaText: schemaInput?.text,
1573
1618
  });
1574
1619
  const cliId = request.harness;
1575
- const resolved = resolveLauncher(cliId, {
1620
+ const launch = resolveLaunch(cliId, {
1576
1621
  platform,
1577
1622
  pathEnv: env.PATH,
1578
1623
  existsSync: exists,
1579
1624
  realpathSync: deps.realpathSync,
1625
+ execPath: deps.execPath ?? process.execPath,
1580
1626
  });
1627
+ const resolved = launch.command;
1628
+ const launchArgs = launch.args;
1581
1629
 
1582
1630
  const authArgs = request.harness === "claude"
1583
1631
  ? [...claudeIsolationArgs(mcpConfigPath), ...route.auth.args]
1584
1632
  : request.harness === "pi"
1585
1633
  ? piAuthCheckArgs(request)
1586
1634
  : [...route.auth.args];
1587
- const auth = spawnSyncImpl(resolved, authArgs, {
1635
+ const auth = spawnSyncImpl(resolved, [...launchArgs, ...authArgs], {
1588
1636
  cwd,
1589
1637
  env,
1590
1638
  encoding: "utf8",
@@ -1628,7 +1676,7 @@ export async function runHarness(request, deps = {}) {
1628
1676
  let killRequest;
1629
1677
  let child;
1630
1678
  try {
1631
- child = spawnImpl(resolved, argv, {
1679
+ child = spawnImpl(resolved, [...launchArgs, ...argv], {
1632
1680
  cwd,
1633
1681
  env,
1634
1682
  shell: false,
@@ -50,6 +50,12 @@ function claimPidFile() {
50
50
  if (existing?.version === 1 && existing.role === "hub" && Number.isInteger(existing.pid) && processExists(existing.pid)) {
51
51
  throw new Error(`KXM hub is already managed by PID ${existing.pid}`);
52
52
  }
53
+ // A well-formed claim whose owner is dead is safe to reclaim. Keep
54
+ // malformed claims fail-closed because they may belong to another tool.
55
+ if (existing?.version === 1 && existing.role === "hub" && Number.isInteger(existing.pid) && !processExists(existing.pid)) {
56
+ rmSync(pidPath, { force: true });
57
+ continue;
58
+ }
53
59
  throw new Error(
54
60
  `KXM hub PID claim is stale at ${pidPath}; remove it only after verifying no hub process is running`,
55
61
  );
@@ -0,0 +1,5 @@
1
+ export function nativeCriticLaunch(harness: string): {
2
+ model: string;
3
+ command: string;
4
+ args: string[];
5
+ };
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env node
2
+ import { spawn } from "node:child_process";
3
+ import { mkdirSync, writeFileSync } from "node:fs";
4
+ import { join, resolve } from "node:path";
5
+ import { pathToFileURL } from "node:url";
6
+ import { HubClient } from "../plugins/kxm/dist/client.js";
7
+ import { buildArgv } from "./harness-run.mjs";
8
+
9
+ // Launch intent only: these labels are not observed model identity or admission.
10
+ export function nativeCriticLaunch(harness) {
11
+ if (!["fable", "astra"].includes(harness)) {
12
+ throw new Error("usage: native-critic.mjs <fable|astra> <prompt>");
13
+ }
14
+ const model = harness === "fable" ? "fable" : "gpt-6-astra";
15
+ const command = harness === "fable" ? "claude" : "codex";
16
+ const args = harness === "fable"
17
+ ? ["-p", "--model", model, "--output-format", "json", "--no-session-persistence", "--tools", "Read,Glob,Grep", "--setting-sources", "user"]
18
+ : buildArgv({ harness: "codex", model, effort: "low", permission: "read-only", prompt_file: "-" });
19
+ return { model, command, args };
20
+ }
21
+
22
+ async function main() {
23
+ const [harness, ...promptParts] = process.argv.slice(2);
24
+ let launch;
25
+ try {
26
+ launch = nativeCriticLaunch(harness);
27
+ } catch (error) {
28
+ console.error(error.message);
29
+ process.exitCode = 2;
30
+ return;
31
+ }
32
+ const { model, command, args } = launch;
33
+ const env = process.env;
34
+ const serverUrl = env.KXM_SERVER_URL || "http://127.0.0.1:7331";
35
+ const outDir = env.KXM_CRITIC_DIR || join(process.cwd(), ".kxm", "assets", "critic-reviews");
36
+ mkdirSync(outDir, { recursive: true });
37
+ const client = new HubClient({ serverUrl, authToken: env.KXM_AUTH_TOKEN, name: `${harness}-critic`, purpose: "independent CLI critic", project: env.KXM_PROJECT || ".kxm", model });
38
+ const prompt = promptParts.join(" ");
39
+ const agent = await client.start(() => {});
40
+ const result = await new Promise((resolve) => {
41
+ const child = spawn(command, args, { env, stdio: ["pipe", "pipe", "pipe"], shell: false });
42
+ let stdout = "", stderr = "";
43
+ child.stdout.on("data", (chunk) => { stdout += chunk; });
44
+ child.stderr.on("data", (chunk) => { stderr += chunk; });
45
+ child.on("error", (error) => resolve({ code: null, stdout, stderr: String(error) }));
46
+ child.on("close", (code, signal) => resolve({ code, signal, stdout, stderr }));
47
+ child.stdin.end(prompt);
48
+ });
49
+ const stamp = new Date().toISOString().replace(/[:.]/g, "-");
50
+ const path = join(outDir, `${harness}-${stamp}.json`);
51
+ writeFileSync(path, JSON.stringify({ schema: "kxm.native-critic-review.v1", harness, model, agentId: agent.id, completedAt: new Date().toISOString(), ...result }, null, 2) + "\n", { mode: 0o600 });
52
+ try { await client.send({ target: env.KXM_REVIEW_TARGET || agent.id, content: `${harness} review completed; artifact=${path}; exit=${String(result.code)}`, delivery: "followUp", idempotencyKey: `critic:${harness}:${stamp}` }); } catch { /* Transport artifact remains, not approval or hub peer-reply evidence. */ }
53
+ await client.stop();
54
+ if (result.code !== 0) process.exit(result.code ?? 1);
55
+ console.log(path);
56
+ }
57
+
58
+ if (process.argv[1] && import.meta.url === pathToFileURL(resolve(process.argv[1])).href) {
59
+ await main();
60
+ }
@@ -1,5 +0,0 @@
1
- # Workspace configuration
2
-
3
- Store reviewable, repository-specific harness and workflow configuration here. `env.example` documents supported environment settings. `workflows/` contains the complete Jira development lifecycle, the v0.4 dogfood workflow, and the provenance/quorum workflow used by parser and evidence-policy tests.
4
-
5
- Configuration files may reference secret environment-variable names such as `JIRA_WEBHOOK_SECRET`; they must never contain the secret values. Set `KXM_WEBHOOK_WORKFLOWS_FILE` to the chosen workflow file.
@@ -1,43 +0,0 @@
1
- {
2
- "schema": "kxm.agents.v1",
3
- "project": "kxm",
4
- "host": "local",
5
- "agents": [
6
- {
7
- "name": "grok",
8
- "kind": "agent",
9
- "driver": "ai",
10
- "model": "xai/grok-4.6",
11
- "thinking": "xhigh",
12
- "purpose": "Sole writer; independent critic of kxm CLI and envelopes"
13
- },
14
- {
15
- "name": "fable",
16
- "kind": "agent",
17
- "driver": "ai",
18
- "model": "anthropic/claude-fable-5-1",
19
- "thinking": "xhigh",
20
- "purpose": "Independent critic: architecture and permissions"
21
- },
22
- {
23
- "name": "gpt-sol",
24
- "kind": "agent",
25
- "driver": "ai",
26
- "model": "openai-codex/gpt-5.6-sol",
27
- "thinking": "xhigh",
28
- "purpose": "Independent critic: CLI contracts and documentation"
29
- },
30
- {
31
- "name": "kimi",
32
- "kind": "agent",
33
- "driver": "ai",
34
- "model": "kimi-coding/kimi-for-coding",
35
- "thinking": "max",
36
- "purpose": "Independent critic: mapping gaps and portability"
37
- }
38
- ],
39
- "ownership": {
40
- "writeAgent": "grok",
41
- "peerAgents": ["fable", "gpt-sol", "kimi"]
42
- }
43
- }
@@ -1,56 +0,0 @@
1
- KXM_HOST=127.0.0.1
2
- KXM_PORT=7331
3
- KXM_AUTH_TOKEN=replace-with-a-long-random-token
4
- KXM_WORKSPACE_DIR=.kxm
5
- # KXM_CONFIG_DIR=.kxm/config
6
- # KXM_LOGS_DIR=.kxm/logs
7
- # KXM_ASSETS_DIR=.kxm/assets
8
- # KXM_STATE_DIR=.kxm/state
9
- # KXM_DATA_PATH=.kxm/state/kxm.db
10
- # KXM_LOG_PATH=.kxm/logs/kxm-hub.jsonl
11
- KXM_PROJECT_TOKENS={"my-project":"replace-with-a-project-token"}
12
- KXM_MESSAGE_TTL_MS=86400000
13
- KXM_MESSAGE_RETENTION_MS=604800000
14
- KXM_RATE_LIMIT_MAX=600
15
- KXM_RATE_LIMIT_WINDOW_MS=60000
16
- KXM_WEBHOOK_WORKFLOWS_FILE=.kxm/config/workflows/jira-development.json
17
- JIRA_WEBHOOK_SECRET=replace-with-a-high-entropy-webhook-secret
18
- WORKFLOW_SIGNAL_SECRET=replace-with-a-separate-callback-secret
19
-
20
- # Client / Pi extension settings
21
- KXM_SERVER_URL=http://127.0.0.1:7331
22
- KXM_PROJECT=my-project
23
- KXM_AGENT_NAME=planner
24
- KXM_AGENT_PURPOSE=Plans work and reviews architecture
25
-
26
- # Long-lived headless Pi worker
27
- KXM_WORKDIR=C:\path\to\project
28
- KXM_WORKER_CONTINUE=true
29
- # Opt in after reviewing the fresh scoped-history upgrade behavior:
30
- # workflow = stable default Pi session plus one session per durable workflow run
31
- # KXM_WORKER_SESSION_ISOLATION=workflow
32
- # KXM_WORKER_MAX_RUN_SESSIONS=128
33
- # KXM_WORKER_INITIAL_CONTINUE=false
34
- # KXM_WORKER_LOG_PATH=.kxm/logs/kxm-worker-planner.jsonl
35
- # KXM_AGENT_LOG_PATH=.kxm/logs/pi-agent-planner.log
36
- # KXM_WORKER_MAX_RESTARTS=20
37
- # KXM_WORKER_MODEL=provider/model
38
- # KXM_WORKER_FALLBACK_MODELS=provider/fallback-one,provider/fallback-two
39
- # KXM_WORKER_PROVIDER_RETRY_MS=60000
40
- # KXM_WORKER_TOOL_TIMEOUT_MS=1860000
41
- # KXM_WORKER_ACTIVATION_TIMEOUT_MS=60000
42
- # KXM_WORKER_TOOLS=read,grep,find,ls,kxm_fanout,kxm_workflow_get
43
- # KXM_WORKER_EXTENSION_PATHS=plugins/kxm/src/extension.ts;C:\path\to\provider\extension.ts
44
- # KXM_WORKER_SKILL_PATHS=plugins/kxm/skills/kxm
45
-
46
- # Optional proposed-improvement telemetry classification override: cli or project
47
- # KXM_IMPROVE_TARGET=project
48
-
49
- # Opt-in Nous Pi providers (unset = no fetch, no registration)
50
- # KXM_NOUS_PROVIDERS=direct
51
- # KXM_NOUS_PROVIDERS=proxy
52
- # KXM_NOUS_PROVIDERS=direct,proxy
53
- # NOUS_API_KEY=
54
- # KXM_NOUS_PROXY_URL=http://127.0.0.1:8645/v1
55
- # KXM_NOUS_DISCOVERY_TIMEOUT_MS=5000
56
- # KXM_NOUS_CATALOG_FILE=
@@ -1,9 +0,0 @@
1
- # Copy this file to the per-user state root. kxm never reads a project
2
- # .kxm/update.yaml (it prints a warning and continues). Locations:
3
- # Windows: %LOCALAPPDATA%\KXM\update.yaml
4
- # macOS: ~/Library/Application Support/KXM/update.yaml
5
- # Linux: ${XDG_STATE_HOME:-~/.local/state}/kxm/update.yaml
6
- # Override the state root with an absolute KXM_STATE_HOME for tests.
7
- schema: kxm.update.v1
8
- auto: false
9
- source: github
@@ -1,160 +0,0 @@
1
- [
2
- {
3
- "id": "fix",
4
- "source": "generic",
5
- "project": "kxm",
6
- "target": "coordinator",
7
- "secretEnv": "FIX_WEBHOOK_SECRET",
8
- "signalSecretEnv": "WORKFLOW_SIGNAL_SECRET",
9
- "delivery": "followUp",
10
- "maxTransitions": 28,
11
- "reproOracle": { "stageId": "repro-review", "evidenceKey": "repro" },
12
- "planHash": { "stageId": "final-plan", "evidenceKey": "plan" },
13
- "requirePlanHash": ["implement", "local-verify", "delivery"],
14
- "promptTemplate": "Bug report: {{task}}\n\nRun the /fix workflow: two-phase reproduction before any production edit, approved plan before implementation, bounded rework on failure. The confirmed reproduction is an immutable oracle.\n\nHard rules: (1) The oracle must invoke the diagnosis-named production callables on the reporter path — a sibling API or newer stack is invalid even if it fails. (2) After repro_invalidated, rewrite the draft against that named seam; never checkpoint blocked because the previous seam was wrong or because a method news its own DbContext. (3) Search existing test hosts (controller fixtures, HttpContext helpers, TransactionScope, read-only call against existing data) before declaring a seam untestable.",
15
- "stages": [
16
- {
17
- "id": "intake",
18
- "label": "Intake",
19
- "area": "workflow",
20
- "instructions": "Classify the bug report: expected vs actual behavior, affected surface, severity, and reproduction hints. Record a journal 'plan' entry with the classification. If the report is not actionable, checkpoint with outcome 'blocked'.",
21
- "requiredEvidence": ["classification"],
22
- "maxAttempts": 2,
23
- "on": { "passed": "repro-explore", "blocked": "$terminal" }
24
- },
25
- {
26
- "id": "repro-explore",
27
- "label": "Repro explore (read-only)",
28
- "area": "implementation",
29
- "instructions": "Read and search only: locate the bug, note prior reproductions, test conventions, and similar incidents via kxm context. No source or test edits. Produce a diagnosis that names the exact production callables on the reporter path (handler, data method, or rendered component), root-cause hypothesis, expected/actual behavior, reproduction strategy, reference tests in existing area folders, and target assertions. Secondary surfaces (other API versions, other tabs) are notes only — they are not substitute oracles. Record the diagnosis with journal category 'hypothesis'.",
30
- "requiredEvidence": ["diagnosis"],
31
- "maxAttempts": 3,
32
- "on": { "passed": "repro-write", "blocked": "$terminal" }
33
- },
34
- {
35
- "id": "repro-write",
36
- "label": "Repro write (tests only)",
37
- "area": "implementation",
38
- "instructions": "Write and execute the failing reproduction. Tests and test helpers only — production and configuration stay byte-for-byte unchanged. Every target assertion must call the diagnosis-named production handler, production seam, or rendered production component and fail for the reported reason rather than compilation/setup. A sibling API, newer stack, or 'also used by some admins' handler is invalid even if it fails. A method that news its own DbContext is not grounds for blocked: use existing test hosts (controller fixtures, HttpContext helpers, TransactionScope so a new context still rolls back) or a read-only call against existing data with no seed. After repro_invalidated, write a new draft against the named seam; do not checkpoint outcome blocked because the previous draft was the wrong seam. Checkpoint failed (outcome failed) to consume an attempt and rewrite. blocked is only when the ticket is not a code defect. Cite evidence key 'repro' with every test path, sha256, exact command, and failed/passed counts. This is a reviewable draft; it is not immutable until independent repro-review passes.",
39
- "requiredEvidence": ["repro"],
40
- "maxAttempts": 3,
41
- "on": { "passed": "repro-review", "failed": "repro-write", "blocked": "$terminal" }
42
- },
43
- {
44
- "id": "repro-review",
45
- "label": "Independent reproduction review",
46
- "area": "gates",
47
- "instructions": "Before the oracle is captured, send the diagnosis, test files/hashes, exact failing results, and production/config git status to both independent critics. They must verify production coupling to the diagnosis-named reporter-path seam (a sibling API is invalid), full expected-behavior coverage, failure causality, immutability feasibility, and absence of production/config edits. Caller-authored evidence cannot satisfy peer review. If either critic finds an omission or invalid test, checkpoint status 'failed' with outcome 'repro_invalidated' and return to repro-write. Only unanimous validation may pass; cite the unchanged draft under evidence key 'repro'. Passing this stage captures the immutable oracle.",
48
- "requiredEvidence": ["repro", "review"],
49
- "maxAttempts": 3,
50
- "evidencePolicies": {
51
- "review": {
52
- "kind": "peer-reply",
53
- "minProducers": 2,
54
- "eligibleAgents": ["critic-1", "critic-2"],
55
- "acceptedStatuses": ["replied"]
56
- }
57
- },
58
- "on": { "passed": "plan", "repro_invalidated": "repro-write", "blocked": "$terminal" }
59
- },
60
- {
61
- "id": "plan",
62
- "label": "Plan",
63
- "area": "workflow",
64
- "instructions": "Using the diagnosis and the confirmed reproduction, write the implementation plan: changed files, approach, risks, and how the reproduction proves the fix. Cite evidence key 'plan' with the plan artifact path and content hash.",
65
- "requiredEvidence": ["plan"],
66
- "maxAttempts": 3,
67
- "on": { "passed": "critics", "blocked": "$terminal" }
68
- },
69
- {
70
- "id": "critics",
71
- "label": "Independent critics",
72
- "area": "gates",
73
- "instructions": "Two independent critics review the plan for correctness, scope creep, and risk. Both must reply through the mesh; caller-authored evidence cannot satisfy this policy. If the plan is invalidated, checkpoint with outcome 'plan_invalidated'.",
74
- "requiredEvidence": ["critique"],
75
- "maxAttempts": 3,
76
- "evidencePolicies": {
77
- "critique": {
78
- "kind": "peer-reply",
79
- "minProducers": 2,
80
- "eligibleAgents": ["critic-1", "critic-2"],
81
- "acceptedStatuses": ["replied"]
82
- }
83
- },
84
- "on": { "passed": "final-plan", "plan_invalidated": "plan", "blocked": "$terminal" }
85
- },
86
- {
87
- "id": "final-plan",
88
- "label": "Final plan",
89
- "area": "workflow",
90
- "instructions": "Fold critic feedback into the final plan. Re-cite evidence key 'plan' with the final artifact path and content hash. The hash of this stage's plan evidence becomes the approved plan hash required by implementation.",
91
- "requiredEvidence": ["plan"],
92
- "maxAttempts": 2,
93
- "on": { "passed": "approval", "plan_invalidated": "plan", "blocked": "$terminal" }
94
- },
95
- {
96
- "id": "approval",
97
- "label": "Human approval",
98
- "area": "security",
99
- "instructions": "Human operator approves the plan. Cite evidence key 'signoff' with the approver identity and approval reference. A 'rejected' outcome routes back to planning; this stage cannot be bypassed by any transition.",
100
- "requiredEvidence": ["signoff"],
101
- "maxAttempts": 8,
102
- "on": { "passed": "implement", "rejected": "plan", "blocked": "$terminal" }
103
- },
104
- {
105
- "id": "implement",
106
- "label": "Implement",
107
- "area": "implementation",
108
- "instructions": "Implement the approved plan. The reproduction oracle is immutable: local verification must fail before the fix and pass after it. Cite evidence keys 'diff' and 'repro' (same value as the oracle).",
109
- "requiredEvidence": ["diff"],
110
- "maxAttempts": 4,
111
- "on": { "passed": "local-verify", "blocked": "$terminal" }
112
- },
113
- {
114
- "id": "local-verify",
115
- "label": "Local verify",
116
- "area": "gates",
117
- "instructions": "Run the repo-defined gates: unit, lint, typecheck, build, and the confirmed reproduction test. Cite evidence key 'gates' with per-gate results. 'implementation_failure' reworks implementation; 'plan_invalidated' routes back to planning rather than expanding scope.",
118
- "requiredEvidence": ["gates"],
119
- "maxAttempts": 4,
120
- "on": {
121
- "passed": "delivery",
122
- "implementation_failure": "implement",
123
- "plan_invalidated": "plan",
124
- "blocked": "$terminal"
125
- }
126
- },
127
- {
128
- "id": "delivery",
129
- "label": "Delivery",
130
- "area": "workflow",
131
- "instructions": "Create and push the branch and merge request with the reproduction, plan, and diff references. Delivery never auto-merges: CI and review outcomes are watched in the next stage.",
132
- "requiredEvidence": ["mr"],
133
- "maxAttempts": 2,
134
- "on": { "passed": "ci-watch", "blocked": "$terminal" }
135
- },
136
- {
137
- "id": "ci-watch",
138
- "label": "CI and review watch",
139
- "area": "gates",
140
- "instructions": "Watch required CI checks and review status. On failure, checkpoint with outcome 'failure' to rework through bounded transitions. On success, continue to human acceptance.",
141
- "requiredEvidence": ["ci"],
142
- "maxAttempts": 6,
143
- "on": {
144
- "passed": "ready-for-human-acceptance",
145
- "failure": "implement",
146
- "blocked": "$terminal"
147
- }
148
- },
149
- {
150
- "id": "ready-for-human-acceptance",
151
- "label": "Ready for human acceptance",
152
- "area": "workflow",
153
- "instructions": "Summarize the fix: reproduction (immutable oracle), approved plan hash, diff, gate results, CI outcome, and the full claim-to-evidence trail from the run journal. Checkpoint 'passed' to complete the run; a human performs final acceptance outside the workflow.",
154
- "requiredEvidence": ["summary"],
155
- "maxAttempts": 2,
156
- "on": { "passed": "$terminal", "blocked": "$terminal" }
157
- }
158
- ]
159
- }
160
- ]
@@ -1,116 +0,0 @@
1
- [
2
- {
3
- "id": "jira-development",
4
- "source": "jira",
5
- "project": "product",
6
- "target": "coordinator",
7
- "secretEnv": "JIRA_WEBHOOK_SECRET",
8
- "signalSecretEnv": "WORKFLOW_SIGNAL_SECRET",
9
- "event": "jira:issue_updated",
10
- "filter": {
11
- "path": "issue.fields.status.name",
12
- "equals": "In Progress"
13
- },
14
- "delivery": "followUp",
15
- "ttlMs": 604800000,
16
- "promptTemplate": "Take ownership of Jira issue {{issue.key}} — {{issue.fields.summary}}.\n\nDescription:\n{{issue.fields.description}}\n\nIssue URL: {{issue.self}}\n\nUse the kxm workflow tools as the durable record. Preserve Jira issue {{issue.key}} as the correlation key. Only perform push, merge, or Jira mutations when the current harness permissions and repository policy authorize them.",
17
- "stages": [
18
- {
19
- "id": "intake",
20
- "area": "workflow",
21
- "label": "Intake and ownership",
22
- "instructions": "Validate the webhook context, repository, scope, permissions, and acceptance criteria. Confirm that the issue is actually In Progress.",
23
- "requiredEvidence": ["issue key", "acceptance criteria", "repository and branch", "authorization boundary"],
24
- "maxAttempts": 2
25
- },
26
- {
27
- "id": "reproduce",
28
- "area": "implementation",
29
- "label": "Reproduce the issue",
30
- "instructions": "Reproduce the defect before changing production code. Prefer a deterministic failing automated test and capture environment details.",
31
- "requiredEvidence": ["reproduction steps", "observed failure", "expected behavior", "failing test or diagnostic artifact"],
32
- "maxAttempts": 3
33
- },
34
- {
35
- "id": "plan-moa",
36
- "area": "workflow",
37
- "label": "Plan with single-agent or three-agent mixture of agents",
38
- "instructions": "For simple work, produce one plan. For ambiguous or high-risk work, ask three strong planning peers independently, compare assumptions and tradeoffs, record contradictions, and synthesize the best evidence-backed plan.",
39
- "requiredEvidence": ["candidate plans", "contradictions and resolutions", "selected plan", "ownership boundaries"],
40
- "maxAttempts": 3
41
- },
42
- {
43
- "id": "plan-review",
44
- "area": "workflow",
45
- "label": "Review the plan",
46
- "instructions": "Have an independent reviewer challenge correctness, security, migration, test, and rollback assumptions. Revise the plan when findings are material.",
47
- "requiredEvidence": ["review findings", "accepted and rejected feedback", "revised plan"],
48
- "maxAttempts": 3
49
- },
50
- {
51
- "id": "implementation",
52
- "area": "implementation",
53
- "label": "Implementation",
54
- "instructions": "Implement the reviewed plan with explicit file ownership. Keep changes focused and preserve unrelated user work.",
55
- "requiredEvidence": ["changed paths", "implementation decisions", "tests added or updated"],
56
- "maxAttempts": 3
57
- },
58
- {
59
- "id": "local-gates",
60
- "area": "gates",
61
- "label": "Local code checks",
62
- "instructions": "Run the repository-defined lint, build/typecheck, security scan, and Playwright suite. A warning or failure must be recorded, corrected, and rerun; do not downgrade a gate silently.",
63
- "requiredEvidence": ["lint result", "build or typecheck result", "security result", "Playwright result"],
64
- "maxAttempts": 5
65
- },
66
- {
67
- "id": "repository-gates",
68
- "area": "gates",
69
- "label": "Repository and CodeRabbit gates",
70
- "instructions": "Reproduce required repository checks locally where possible. Address CodeRabbit or equivalent review findings by evidence and rerun affected gates.",
71
- "requiredEvidence": ["repository gate results", "review findings", "resolutions or justified dismissals"],
72
- "maxAttempts": 5
73
- },
74
- {
75
- "id": "documentation",
76
- "area": "documentation",
77
- "label": "Documentation",
78
- "instructions": "Update user, operator, architecture, changelog, and test-matrix material affected by the change.",
79
- "requiredEvidence": ["documentation paths", "behavior and operational changes", "examples updated"],
80
- "maxAttempts": 3
81
- },
82
- {
83
- "id": "push-watch",
84
- "area": "gates",
85
- "label": "Push, open review, and watch",
86
- "instructions": "When authorized, push the branch and open or update the review. Call kxm_workflow_wait with commit, pull-request, and resolved-warning evidence, then watch the example `ci` check with `kxm gate github watch --run-id <id> --stage-id push-watch --signal-key <key> --repo <owner/name> --pr <n> --required ci` so the durable wait receives exact `github.check:ci` evidence. Replace `ci` in this template and command with the repository's real required check names. Record every warning or failure, fix it, push again, and continue watching until required checks pass.",
87
- "requiredEvidence": ["commit", "pull request", "resolved warnings and failures", "github.check:ci"],
88
- "maxAttempts": 10
89
- },
90
- {
91
- "id": "merge",
92
- "area": "security",
93
- "label": "Merge",
94
- "instructions": "Merge only when approvals, required checks, branch policy, and user authorization permit it. Capture the resulting merge commit.",
95
- "requiredEvidence": ["approval state", "required checks", "merge commit"],
96
- "maxAttempts": 3
97
- },
98
- {
99
- "id": "jira-update",
100
- "area": "workflow",
101
- "label": "Update Jira",
102
- "instructions": "Update the Jira issue through an authorized integration with the outcome, implementation and test evidence, pull request, merge commit, and any follow-up risk. Transition it according to team policy.",
103
- "requiredEvidence": ["Jira transition", "Jira comment or fields", "links to pull request and merge"],
104
- "maxAttempts": 3
105
- },
106
- {
107
- "id": "retrospective",
108
- "area": "workflow",
109
- "label": "Continuous-improvement retrospective",
110
- "instructions": "Review the run journal. Turn recurring errors, contradictions, delays, flaky gates, and harness friction into an evidence-linked improvement backlog. Do not apply policy changes automatically.",
111
- "requiredEvidence": ["lessons by area", "prioritized improvements", "owner or next action", "success measure"],
112
- "maxAttempts": 3
113
- }
114
- ]
115
- }
116
- ]