@kontextmind/kxm 0.7.94 → 0.7.96
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/.claude-plugin/marketplace.json +1 -1
- package/.kxm/README.md +39 -9
- package/CHANGELOG.md +1 -1
- package/README.md +147 -257
- package/SECURITY.md +21 -12
- package/docs/README.md +133 -54
- package/docs/adr/ADR-0002-browser-automation-steel-doks.md +24 -18
- package/docs/adr/ADR-0003-sqlite-only-store.md +100 -0
- package/docs/adr/ADR-0004-edge-identity-authentik.md +99 -0
- package/docs/adr/README.md +33 -0
- package/docs/concepts/architecture.md +262 -0
- package/docs/concepts/data-and-storage.md +194 -0
- package/docs/concepts/trust-model.md +152 -0
- package/docs/contracts/README.md +22 -14
- package/docs/contracts/effects-and-recovery.md +3 -0
- package/docs/contracts/migration.md +2 -2
- package/docs/contracts/routing.md +6 -5
- package/docs/contributing/assignment-runner.md +388 -0
- package/docs/contributing/ci-and-release.md +231 -0
- package/docs/contributing/development.md +362 -0
- package/docs/contributing/harness-routing-internals.md +192 -0
- package/docs/{packages.md → contributing/packages.md} +13 -15
- package/docs/{skills → contributing}/repo-work-delivery.md +20 -21
- package/docs/contributing/test-matrix.md +208 -0
- package/docs/{tui-components.md → contributing/tui-components.md} +30 -22
- package/docs/contributing/writing-docs.md +340 -0
- package/docs/glossary.md +471 -0
- package/docs/guides/agent-skills.md +137 -0
- package/docs/guides/browser-automation.md +160 -0
- package/docs/guides/context-and-memory.md +352 -0
- package/docs/guides/continuous-improvement.md +228 -0
- package/docs/guides/governed-skills.md +173 -0
- package/docs/guides/nous-providers.md +186 -0
- package/docs/guides/peer-messaging.md +304 -0
- package/docs/guides/pi-workers.md +219 -0
- package/docs/guides/provenance-gates.md +313 -0
- package/docs/guides/webhook-workflows.md +364 -0
- package/docs/kb/how-credentials-retrieved-safely.md +38 -12
- package/docs/kb/how-to-capture-and-annotate-section.md +15 -13
- package/docs/kb/how-to-connect-playwright-to-steel.md +16 -11
- package/docs/kb/how-to-recover-expired-session-or-orphan.md +26 -16
- package/docs/kb/how-to-resume-after-mfa.md +19 -11
- package/docs/kb/how-to-take-over-session.md +17 -13
- package/docs/kb/why-authentication-disappeared.md +22 -14
- package/docs/kb/why-automation-opened-different-browser.md +23 -14
- package/docs/kb/why-session-viewer-cannot-control.md +13 -12
- package/docs/operations/backup-and-restore.md +248 -0
- package/docs/operations/deploy.md +307 -0
- package/docs/operations/monitoring.md +209 -0
- package/docs/operations/runtime-sync.md +192 -0
- package/docs/operations/troubleshooting.md +265 -0
- package/docs/operations/upgrade.md +124 -0
- package/docs/prompts/browser-annotate-feedback.md +7 -7
- package/docs/prompts/browser-diagnose-recover.md +11 -10
- package/docs/prompts/browser-explore.md +7 -7
- package/docs/prompts/browser-repro-fix.md +7 -7
- package/docs/prompts/browser-start.md +12 -11
- package/docs/prompts/browser-takeover.md +8 -8
- package/docs/{cli-reference.md → reference/cli-reference.md} +83 -41
- package/docs/{config-reference.md → reference/config-reference.md} +159 -148
- package/docs/reference/configuration.md +299 -0
- package/docs/reference/harness-routing.md +508 -0
- package/docs/reference/http-api.md +203 -0
- package/docs/reference/tools.md +370 -0
- package/docs/{workflow-guide.md → reference/workflow-catalog.md} +92 -153
- package/docs/reference/workflow-definitions.md +286 -0
- package/docs/start/first-workflow.md +287 -0
- package/docs/start/install.md +146 -0
- package/docs/start/quickstart-claude-code.md +405 -0
- package/docs/start/quickstart-pi.md +213 -0
- package/docs/templates/README.md +78 -73
- package/docs/templates/adr.md +13 -13
- package/docs/templates/architecture.md +55 -71
- package/docs/templates/bug-fix.md +13 -16
- package/docs/templates/feature.md +14 -19
- package/docs/templates/handoff.md +44 -46
- package/docs/templates/postmortem.md +30 -43
- package/docs/templates/research.md +15 -20
- package/docs/templates/review.md +49 -50
- package/docs/templates/runbook.md +38 -30
- package/docs/templates/test-plan.md +16 -23
- package/docs/templates/test-report.md +14 -17
- package/examples/README.md +9 -5
- package/examples/provenance-workflow.json +1 -1
- package/examples/webhook-workflows/jira-development.json +59 -0
- package/examples/webhook-workflows/jira-issue-updated.json +12 -0
- package/package.json +2 -2
- package/packages/core/tui/README.md +1 -1
- package/plugins/kxm/.claude-plugin/plugin.json +1 -1
- package/plugins/kxm/README.md +31 -32
- package/plugins/kxm/dist/cli.js +5 -5
- package/plugins/kxm/dist/mcp-server.js +1 -1
- package/plugins/kxm/dist/runtime.js +1 -1
- package/plugins/kxm/package.json +1 -1
- package/plugins/kxm/skills/kxm/references/protocol.md +3 -1
- package/plugins/kxm/skills/kxm-browser-auth/SKILL.md +1 -1
- package/plugins/kxm/skills/kxm-browser-diagnostics/SKILL.md +5 -5
- package/plugins/kxm/skills/kxm-browser-explore/SKILL.md +2 -2
- package/plugins/kxm/skills/kxm-browser-session/SKILL.md +10 -13
- package/plugins/kxm/skills/kxm-browser-takeover/SKILL.md +1 -1
- package/plugins/kxm/skills/kxm-browser-verify/SKILL.md +1 -1
- package/plugins/kxm/skills/kxm-context-memory/SKILL.md +13 -4
- package/plugins/kxm/skills/kxm-hub-ops/SKILL.md +3 -1
- package/plugins/kxm/skills/kxm-mind-setup/SKILL.md +2 -1
- package/plugins/kxm/skills/kxm-project-setup/SKILL.md +31 -54
- package/plugins/kxm/skills/kxm-projects/SKILL.md +1 -1
- package/plugins/kxm/skills/kxm-protocol/SKILL.md +1 -1
- package/plugins/kxm/skills/kxm-routing-improve/SKILL.md +15 -7
- package/plugins/kxm/skills/kxm-runs/SKILL.md +11 -5
- package/plugins/kxm/skills/kxm-session/SKILL.md +1 -1
- package/plugins/kxm/skills/kxm-tasks/SKILL.md +9 -7
- package/plugins/kxm/skills/kxm-workflow/SKILL.md +10 -2
- package/plugins/kxm/src/cli/system.ts +1 -1
- package/plugins/kxm/src/cli.ts +3 -3
- package/plugins/kxm/src/init-guide-setup.ts +1 -1
- package/plugins/kxm/src/mcp-server.ts +1 -1
- package/plugins/kxm/src/modes.ts +1 -1
- package/schemas/README.md +1 -1
- package/docs/agent-communication-envelopes-and-gates.md +0 -553
- package/docs/agent-skills.md +0 -198
- package/docs/architecture.md +0 -245
- package/docs/assignment-runner.md +0 -264
- package/docs/browser-automation.md +0 -139
- package/docs/configuration.md +0 -437
- package/docs/continuous-improvement.md +0 -226
- package/docs/getting-started.md +0 -277
- package/docs/harness-routing.md +0 -616
- package/docs/kb/qa-authentik-authentication.md +0 -97
- package/docs/kb/qa-extension-install-and-hub-bootstrap.md +0 -85
- package/docs/kb/qa-hub-on-a-public-host.md +0 -48
- package/docs/kb/qa-sqlite-vs-duckdb.md +0 -35
- package/docs/kb/qa-what-the-hub-stores.md +0 -64
- package/docs/kxm-handbook.md +0 -1181
- package/docs/operations.md +0 -510
- package/docs/operator-pi-packages.md +0 -67
- package/docs/provenance-gates.md +0 -295
- package/docs/skills.md +0 -47
- package/docs/test-matrix.md +0 -132
- package/docs/troubleshooting.md +0 -293
- package/docs/webhook-workflows.md +0 -240
|
@@ -3,18 +3,20 @@
|
|
|
3
3
|
This page describes every file a KXM project or operator configures: where it
|
|
4
4
|
lives, which parser reads it, every field that parser accepts, the error codes
|
|
5
5
|
it reports, and which commands read or write it. It was written against the
|
|
6
|
-
parsers in `plugins/kxm/src` and `scripts
|
|
6
|
+
parsers in `plugins/kxm/src` and `scripts/`, and every example on
|
|
7
7
|
this page was validated with the commands named next to it. Where a field is
|
|
8
8
|
accepted but nothing acts on it yet, the tables say so.
|
|
9
9
|
|
|
10
10
|
Related pages:
|
|
11
11
|
|
|
12
|
-
- [
|
|
13
|
-
workers, and agents.
|
|
12
|
+
- [Environment variables and limits](configuration.md) lists the environment
|
|
13
|
+
variables for the hub, workers, and agents, and the protocol limits.
|
|
14
|
+
- [Workflow definitions](workflow-definitions.md) documents the hub's JSON
|
|
15
|
+
webhook workflow definitions field by field.
|
|
14
16
|
- [Harness routing](harness-routing.md) explains when to run a model through its
|
|
15
17
|
native harness and when to reach the same model through OpenRouter on Pi. This
|
|
16
18
|
page documents the fields; that guide covers the decision.
|
|
17
|
-
- [
|
|
19
|
+
- [Backup and restore](../operations/backup-and-restore.md) covers every path below.
|
|
18
20
|
|
|
19
21
|
## At a glance
|
|
20
22
|
|
|
@@ -141,7 +143,7 @@ makes a directory a KXM project. Parser: `loadKxmProject` in
|
|
|
141
143
|
| Field | Type and allowed values | Required, default | What reads it |
|
|
142
144
|
|---|---|---|---|
|
|
143
145
|
| `schema` | `kxm.project.v1` | Required | Loader |
|
|
144
|
-
| `id` | Opaque ID matching `^[a-z][a-z0-9]{1,15}_[A-Za-z0-9][A-Za-z0-9_-]{5,127}$` | Required | Loader, Runtime. `kxm init` generates `prj_` plus 32 hex characters; `--project-id` must start with `prj_`.
|
|
146
|
+
| `id` | Opaque ID matching `^[a-z][a-z0-9]{1,15}_[A-Za-z0-9][A-Za-z0-9_-]{5,127}$` | Required | Loader, Runtime. `kxm init` generates `prj_` plus 32 hex characters; `--project-id` must start with `prj_`. See the note below |
|
|
145
147
|
| `name` | String, 1 to 120 characters | Required | Display only |
|
|
146
148
|
| `description` | String, at most 2,000 characters | Optional | Display only |
|
|
147
149
|
| `defaultWorkflow` | Identifier | Optional, `default` | Loader only: the named workflow must exist (`default_workflow_unknown`). `kxm run` always takes an explicit workflow. |
|
|
@@ -164,6 +166,9 @@ makes a directory a KXM project. Parser: `loadKxmProject` in
|
|
|
164
166
|
| `limits.maxRunDurationMs` | Integer, 0 to 31,536,000,000 | Optional | Runtime. Combined with the workflow's own value; the smaller one wins. |
|
|
165
167
|
| `limits.maxAgentTimeMs` | Integer, 0 to 31,536,000,000 | Optional | Runtime refuses to drive any run while it is set (`limit_unsupported`); leave it out |
|
|
166
168
|
|
|
169
|
+
The Runtime binds one project `id` to one control root per state root, so a
|
|
170
|
+
second checkout with the same ID is refused with `project_home_conflict`.
|
|
171
|
+
|
|
167
172
|
Example (validated with `kxm init --json`, including a nested member checkout
|
|
168
173
|
at `repositories/api`):
|
|
169
174
|
|
|
@@ -374,7 +379,7 @@ checks it when it probes the harness before dispatch.
|
|
|
374
379
|
| `agy` | Provider `google` and `gemini-` models |
|
|
375
380
|
| `kimi` | Provider `moonshot` and `kimi`, `moonshot`, or `kimi-for-coding` models |
|
|
376
381
|
| `deepseek` | Provider `deepseek` and `deepseek-` models |
|
|
377
|
-
| `pi` |
|
|
382
|
+
| `pi` | Refuses a native vendor's model named directly, through the vendor's Pi provider or behind an aggregator, except `antigravity/gemini-…` (`pi_native_impersonation_blocked`); see [the brake](harness-routing.md#what-the-brake-refuses) |
|
|
378
383
|
|
|
379
384
|
A mismatch is reported as `harness_unhosted_model`. Which route to choose for a
|
|
380
385
|
model that more than one harness can reach is covered in
|
|
@@ -500,7 +505,9 @@ ID used by `kxm run <workflow>`. Three layers check it:
|
|
|
500
505
|
1. The loader (`schemas/workflow.schema.json` plus `validateWorkflow` in
|
|
501
506
|
`plugins/kxm/src/project-config.ts`) on every project load.
|
|
502
507
|
2. The compiler (`compileKxmWorkflow` in `plugins/kxm/src/engine-compile.ts`)
|
|
503
|
-
when `kxm
|
|
508
|
+
when the first `kxm runs drive` starts the run. It pins the compiled plan
|
|
509
|
+
on the run then, not when `kxm run` creates it, and it refuses the run
|
|
510
|
+
(`run_revision_drift`) if the configuration changed in between.
|
|
504
511
|
3. Runtime acceptance (`plugins/kxm/src/engine.ts`) before each step executes.
|
|
505
512
|
A step the current Runtime cannot execute hands the run off instead of
|
|
506
513
|
running it.
|
|
@@ -511,17 +518,21 @@ ID used by `kxm run <workflow>`. Three layers check it:
|
|
|
511
518
|
|---|---|---|---|
|
|
512
519
|
| `schema` | `kxm.workflow.v1` | Required | |
|
|
513
520
|
| `description` | String, at most 4,000 characters | Optional | Prose; neutral in `kxm trust` |
|
|
514
|
-
| `coordinator` | Agent ID | Optional, `coordinator` | Must exist (`coordinator_unknown`); pinned on the compiled plan.
|
|
521
|
+
| `coordinator` | Agent ID | Optional, `coordinator` | Must exist (`coordinator_unknown`); pinned on the compiled plan. See the note on approval and wait steps below. |
|
|
515
522
|
| `limits.maxTransitions` | Integer, 1 to 1,000 | Required once any back-edge exists (`workflow_cycle_unbounded`) | Run-wide transition budget; defaults to the number of steps. Exceeding it fails the run with `budget_transitions`. |
|
|
516
|
-
| `limits.maxRunDurationMs` | Integer, 0 to 31,536,000,000 | Optional | The Runtime cancels the run with `budget_run_duration`; the smaller of this and the project limit applies |
|
|
517
|
-
| `limits.maxAgentTimeMs` | Integer, 0 to 31,536,000,000 | Optional | The Runtime refuses to drive a run that declares it (`limit_unsupported
|
|
523
|
+
| `limits.maxRunDurationMs` | Integer, 0 to 31,536,000,000 | Optional | The Runtime cancels the run with `budget_run_duration`; the smaller of this and the project limit applies. Measured on the wall clock |
|
|
524
|
+
| `limits.maxAgentTimeMs` | Integer, 0 to 31,536,000,000 | Optional | The Runtime refuses to drive a run that declares it (`limit_unsupported`); see below |
|
|
518
525
|
| `limits.maxModelCost` | Number greater than 0 | Optional | Fails the run with `budget_model_cost` once attempts recorded with cost basis `metered` reach it. See [Cost basis](#cost-basis-and-staleness). |
|
|
519
526
|
| `limits.currency` | Three uppercase letters | Optional | Pinned on the plan; not otherwise read |
|
|
520
|
-
| `planHash` | `{stageId, evidenceKey}` | Optional |
|
|
521
|
-
| `reproOracle` | `{stageId, evidenceKey}` | Optional | Same shape as `planHash`, for an immutable reproduction |
|
|
522
|
-
| `requirePlanHash` | Unique step IDs, at most 128 | Optional | Requires `planHash` (`plan_hash_missing`); every step
|
|
527
|
+
| `planHash` | `{stageId, evidenceKey}` | Optional | Validated and pinned, not enforced yet (see below). The step must declare that evidence key (`oracle_evidence_unknown`, `oracle_stage_unknown`). |
|
|
528
|
+
| `reproOracle` | `{stageId, evidenceKey}` | Optional | Same shape as `planHash`, for an immutable reproduction; validated and pinned, not enforced yet |
|
|
529
|
+
| `requirePlanHash` | Unique step IDs, at most 128 | Optional | Requires `planHash` (`plan_hash_missing`); every repository-writing step after the `planHash` stage must be listed (`mutation_missing_plan_hash`) |
|
|
523
530
|
| `steps` | 1 to 128 steps | Required | The first step is the entry point |
|
|
524
531
|
|
|
532
|
+
Approval and wait steps without `assignments.allowedAgents` are dispatched to the agent whose ID is literally `coordinator`, not to the `coordinator` field's value.
|
|
533
|
+
|
|
534
|
+
Duration budgets use the wall clock. `maxRunDurationMs` counts from the time the run first entered `running` (its first drive) to the current system time, so a change to the system clock moves it.
|
|
535
|
+
|
|
525
536
|
### Step fields
|
|
526
537
|
|
|
527
538
|
| Field | Type and allowed values | Required, default | Notes |
|
|
@@ -536,7 +547,7 @@ ID used by `kxm run <workflow>`. Three layers check it:
|
|
|
536
547
|
| `signal` | Identifier | Required for `wait` | Compiled and diffed; the Runtime does not match signals to wait steps yet |
|
|
537
548
|
| `model` | Model selector | Optional | Intersected with each allowed agent's own model ceiling; an empty intersection is `model_selector_incompatible`. Live route resolution ignores it. The Runtime refuses it on gate steps. |
|
|
538
549
|
| `maxAttempts` | Integer, 1 to 20 | Optional, `1` | Entering the step again after this many attempts fails the run (`budget_step_attempts`) |
|
|
539
|
-
| `timeoutMs` | Integer, 0 to 31,536,000,000 | Optional | Gate steps: refused
|
|
550
|
+
| `timeoutMs` | Integer, 0 to 31,536,000,000 | Optional | Not `0`. Gate steps: refused for `artifacts-exist` gates or below the gate's `timeoutMs`. Other kinds: unused; the producer times out at 120 s |
|
|
540
551
|
| `repositories` | Map of repository ID to `none`, `read`, or `write` | Optional | IDs must be declared (`repository_unknown`); may not exceed the agent's ceiling (`repository_scope_expansion`) |
|
|
541
552
|
| `tools` | `{preset, allow, deny}` | Optional | Must keep the agent's preset and denials and allow only tools the agent allows (`tool_scope_expansion`). The Runtime refuses steps that declare `tools`. |
|
|
542
553
|
| `secrets` | `[{ref, as, required}]` | Optional | Only refs the agent grants (`secret_scope_expansion`). The Runtime refuses steps that declare `secrets`. |
|
|
@@ -548,7 +559,7 @@ ID used by `kxm run <workflow>`. Three layers check it:
|
|
|
548
559
|
|
|
549
560
|
Fields such as `role`, `area`, or `outcomes` are not part of this schema and
|
|
550
561
|
fail with `schema_additionalProperties`. `area` belongs to
|
|
551
|
-
[webhook workflow stages](
|
|
562
|
+
[webhook workflow stages](workflow-definitions.md#stage-fields); the compiled plan
|
|
552
563
|
derives its outcome list from the keys of `on`.
|
|
553
564
|
|
|
554
565
|
### Assignments and join
|
|
@@ -560,13 +571,24 @@ derives its outcome list from the keys of `on`.
|
|
|
560
571
|
| `assignments.target` | Integer, 1 to 64 | `minimum` | |
|
|
561
572
|
| `assignments.maximum` | Integer, 1 to 64 | `target` | For `moa`, at most the number of allowed agents (`assignment_pool_too_small`) |
|
|
562
573
|
| `assignments.maxParallel` | Integer, 1 to 64 | `maximum` | At most `maximum` (`assignment_parallelism_invalid`) |
|
|
563
|
-
| `assignments.maxAttemptsPerAssignment` | Integer, 1 to 20 | `1` | The Runtime
|
|
574
|
+
| `assignments.maxAttemptsPerAssignment` | Integer, 1 to 20 | `1` | The Runtime accepts at most 2, but runs one attempt per assignment; a retry is a new assignment |
|
|
564
575
|
| `assignments.maxWriteRepositories` | Integer, 1 to 64 | none | At most the number of `write` repositories on the step (`write_repository_bound_invalid`); the Runtime executes at most 1 |
|
|
565
|
-
| `assignments.distinctBy` | Any of `provider`, `model`, `profile` | `[]` |
|
|
566
|
-
| `join.strategy` | `all`, `all-settled`, `quorum`, or `first-success` | `all` | The Runtime executes `all` and `all-settled` |
|
|
576
|
+
| `assignments.distinctBy` | Any of `provider`, `model`, `profile` | `[]` | Checked at load only: the candidates must offer `target` distinct values (`model_diversity_impossible`). The Runtime refuses values other than `provider` |
|
|
577
|
+
| `join.strategy` | `all`, `all-settled`, `quorum`, or `first-success` | `all` | The Runtime executes `all` and `all-settled` (see [How a panel joins](#how-a-panel-joins)) |
|
|
567
578
|
| `join.minimumPassed` | Integer, 1 to 64 | none | Required for `quorum`; at most `maximum` (`join_impossible`); the Runtime accepts it only with `all-settled` |
|
|
568
579
|
| `join.cancelRemaining` | Boolean | none | The Runtime refuses it |
|
|
569
580
|
|
|
581
|
+
At run time, members bind to agents in `allowedAgents` order: the first member runs the first listed agent, the second the second, and so on. The Runtime does not re-check providers, so `distinctBy: [provider]` holds at run time only if the first `target` agents in `allowedAgents` use different providers. List them that way.
|
|
582
|
+
|
|
583
|
+
#### How a panel joins
|
|
584
|
+
|
|
585
|
+
A panel joins once at least `assignments.minimum` members exist and every member's attempt has settled:
|
|
586
|
+
|
|
587
|
+
- If any member's result is unknown or rejected by its producer, the run fails with `outcome_unknown`.
|
|
588
|
+
- `all`: when every member produced the same outcome, the step takes it; otherwise the run fails with `join_conflict`.
|
|
589
|
+
- `all-settled`: when at least `join.minimumPassed` members (default `assignments.minimum`) passed, the outcome is `passed`. Otherwise, a non-passed outcome shared by that many members wins, and failing that the outcome is `quorum-not-met`.
|
|
590
|
+
- A joined outcome with no transition in `on` fails the run with `outcome_unknown`, so declare `quorum-not-met` on an `all-settled` step.
|
|
591
|
+
|
|
570
592
|
### Evidence requirements
|
|
571
593
|
|
|
572
594
|
| Field | Type and allowed values | Default | Notes |
|
|
@@ -582,6 +604,8 @@ derives its outcome list from the keys of `on`.
|
|
|
582
604
|
|
|
583
605
|
A `producerPolicy` is allowed only on `kind: assignment-result`.
|
|
584
606
|
|
|
607
|
+
The Runtime enforces less of this than the loader checks. `producerPolicy` (producer counts, eligible agents, degradation) is checked at load only. On agent and `moa` steps, each requirement only becomes an acceptance criterion in the prompt; nothing checks that the evidence arrived. Only gate steps record evidence at run time: one gate evidence reference for each settled gate attempt.
|
|
608
|
+
|
|
585
609
|
### Transitions and outcomes
|
|
586
610
|
|
|
587
611
|
Each key of `on` is an outcome identifier. Each value is either a step ID
|
|
@@ -645,9 +669,12 @@ falls back to it.
|
|
|
645
669
|
|
|
646
670
|
Validation accepts more than the Runtime executes. When a drive reaches one of
|
|
647
671
|
these, the run is handed off (`step_unsupported`, `gate_unsupported`, or
|
|
648
|
-
`limit_unsupported`) instead of executing
|
|
672
|
+
`limit_unsupported`) instead of executing, and `kxm runs drive` reports
|
|
673
|
+
`run_handoff_required`:
|
|
649
674
|
|
|
650
|
-
- `limits.maxAgentTimeMs` in the workflow or project.
|
|
675
|
+
- `limits.maxAgentTimeMs` in the workflow or project. The built-in template
|
|
676
|
+
sets it, so the `default` workflow that `kxm init` writes cannot be driven
|
|
677
|
+
as generated.
|
|
651
678
|
- `tools`, `secrets`, or `safeSpeculation: true` on any step.
|
|
652
679
|
- `join.strategy` other than `all` or `all-settled`, `join.minimumPassed` with
|
|
653
680
|
`all`, and `join.cancelRemaining`.
|
|
@@ -663,9 +690,35 @@ these, the run is handed off (`step_unsupported`, `gate_unsupported`, or
|
|
|
663
690
|
`write` access to `control` or with access to any other repository; a
|
|
664
691
|
`reserved` gate.
|
|
665
692
|
|
|
693
|
+
Some fields are validated and pinned on the plan but not enforced, and a
|
|
694
|
+
drive does not hand off on them:
|
|
695
|
+
|
|
696
|
+
- `planHash`, `reproOracle`, and `requirePlanHash`. The Runtime captures no
|
|
697
|
+
hash and does not check one before a listed step runs. (Hub
|
|
698
|
+
[webhook workflows](workflow-definitions.md#plan-hash-and-reproduction-oracle)
|
|
699
|
+
do enforce their own `planHash` and `reproOracle`.)
|
|
700
|
+
- `distinctBy: [provider]` and `producerPolicy`, which are checked at load only
|
|
701
|
+
(see [Assignments and join](#assignments-and-join) and
|
|
702
|
+
[Evidence requirements](#evidence-requirements)).
|
|
703
|
+
|
|
666
704
|
The Runtime also caps each run at 100 attempts whose cost basis is `unmetered`
|
|
667
705
|
or `unknown` (`budget_unmetered_attempts`).
|
|
668
706
|
|
|
707
|
+
#### Handoff reasons
|
|
708
|
+
|
|
709
|
+
A handoff stops the drive without failing the run; `kxm runs drive` prints
|
|
710
|
+
the reason, field, and detail. The Runtime uses these reasons:
|
|
711
|
+
|
|
712
|
+
| Reason | Meaning |
|
|
713
|
+
|---|---|
|
|
714
|
+
| `step_unsupported`, `gate_unsupported`, `limit_unsupported` | The step, gate, or limit is one the Runtime does not execute yet (the list above) |
|
|
715
|
+
| `gate_outcome_undeclared` | The drive-time gate pre-flight check failed (see [Transitions and outcomes](#transitions-and-outcomes)) |
|
|
716
|
+
| `attempt_unsettled` | A gate attempt could not settle: its effect is uncertain, or its outcome has no transition |
|
|
717
|
+
| `gate_recovery_pending` | Unfinished gate attempts elsewhere in the project hold later gate steps |
|
|
718
|
+
| `attempt_unreconciled` | An issued attempt is not held by this process, for example after a supervisor restart |
|
|
719
|
+
| `cancel_pending_foreign` | Cancellation is pending in another process |
|
|
720
|
+
| `gate_uncertain_blocked` | The run is `blocked_uncertain` and waits for an external signal or an operator |
|
|
721
|
+
|
|
669
722
|
Example (validated with `kxm init --json` and compiled with
|
|
670
723
|
`compileKxmWorkflow`). Besides the `implementer` and `critic-arch` agents and
|
|
671
724
|
the `critic-claude` profile shown above, it needs a `coordinator` agent, a
|
|
@@ -814,9 +867,10 @@ This example validates, but a live drive would be handed off at `implement`
|
|
|
814
867
|
it as a field reference; the
|
|
815
868
|
[worked example](#worked-example-a-minimal-two-step-project) is one that runs.
|
|
816
869
|
|
|
817
|
-
Commands: `kxm init` validates; `kxm run <id> [prompt]`
|
|
818
|
-
|
|
819
|
-
|
|
870
|
+
Commands: `kxm init` validates; `kxm run <id> [prompt]` creates a run
|
|
871
|
+
(`--dry-run` only loads the bundle); the first `kxm runs drive <runId>`
|
|
872
|
+
compiles and pins the plan, then drives it live, or without models with
|
|
873
|
+
`--simulated`; `kxm runs status|list|cancel`; `kxm trust` diffs.
|
|
820
874
|
`kxm workflow add <id> --template <name>` writes a built-in template
|
|
821
875
|
(`implement-and-verify`, `dual-critic-review`, or `spec-and-plan`), and
|
|
822
876
|
`kxm workflow add <id>` a one-step scaffold, under `.kxm/workflows/` (or
|
|
@@ -850,6 +904,15 @@ code decides the outcome (see
|
|
|
850
904
|
[Transitions and outcomes](#transitions-and-outcomes)); the Runtime records
|
|
851
905
|
hashes and byte counts of stdout and stderr, not their text.
|
|
852
906
|
|
|
907
|
+
Before it starts the process, the Runtime checks the joined `argv` against the
|
|
908
|
+
destructive-command seatbelt (`rm` with recursive and force flags,
|
|
909
|
+
`git reset --hard`, `git clean -f`, `git checkout --` with paths, and
|
|
910
|
+
`git restore .` or `*`); a match starts nothing and fails the run with
|
|
911
|
+
`gate_start_failed`. The command runs in its own
|
|
912
|
+
process group. On timeout or cancellation the Runtime sends `SIGTERM` to the
|
|
913
|
+
group, then `SIGKILL` after 2 seconds. A process that escapes the group can
|
|
914
|
+
outlive the gate, so the seatbelt and the group are cleanup, not a sandbox.
|
|
915
|
+
|
|
853
916
|
```yaml
|
|
854
917
|
# .kxm/gates.yaml — the only place a gate id becomes executable.
|
|
855
918
|
schema: kxm.gate-registry.v1
|
|
@@ -885,10 +948,15 @@ read different fields:
|
|
|
885
948
|
|
|
886
949
|
| Reader | File | Fields it reads | Effect |
|
|
887
950
|
|---|---|---|---|
|
|
888
|
-
| Project loader (`validateBundle`) | `.kxm/roles/writer.yaml` only | `roster[].model`, `roster[].enabled` |
|
|
951
|
+
| Project loader (`validateBundle`) | `.kxm/roles/writer.yaml` only | `roster[].model`, `roster[].enabled` | Cross-checks the writer roster against the `implementer` agent's model (see below). Parsed as restricted YAML. |
|
|
889
952
|
| Runtime route check (`listRoleBindings` in `plugins/kxm/src/routes.ts`) | `.kxm/roles/<role>.yaml`, role = agent ID, `writer` for `implementer` | `roster[].model` | The agent's `provider/model` must appear exactly. `enabled` is ignored, so a disabled entry still admits. The role name comes from the filename. |
|
|
890
953
|
| `kxm role` commands (`plugins/kxm/src/role.ts`) | `.kxm/roles/*.yaml` and `~/.config/kxm/roles/*.yaml` | Everything below | Listing and editing only. A file without `schema: kxm.role.v1` is silently skipped. A local file overrides a global one with the same ID. |
|
|
891
954
|
|
|
955
|
+
The loader check applies when the agent `implementer` (or else `writer`)
|
|
956
|
+
declares a model and the roster has at least one enabled entry. One enabled
|
|
957
|
+
entry must then equal `provider/model`, equal the bare model, or end with
|
|
958
|
+
`/<model>`; otherwise the load fails with `role_roster_conflicts_with_agent`.
|
|
959
|
+
|
|
892
960
|
Write roster models as the full `provider/model` string. `kxm role add --model
|
|
893
961
|
grok-4.6` writes a bare model ID, which satisfies the loader check but not the
|
|
894
962
|
Runtime route check. `kxm role modify <role> --add-model grok:xai/grok-4.6`
|
|
@@ -977,7 +1045,7 @@ unknown keys are ignored).
|
|
|
977
1045
|
| `schema` | `kxm.routes.v2` | Required | Anything else fails with `invalid .kxm/routes.yaml` |
|
|
978
1046
|
| `admitted` | Array of route strings | Required | Runtime route check; `kxm routes list`, `kxm routes count`; `kxm models` |
|
|
979
1047
|
| `disabled` | Array of route strings | Optional, `[]` | Runtime: a disabled route is refused even if admitted |
|
|
980
|
-
| `roles` | Map of name to route strings | Optional, `{}` | Not read by any code path yet; shown by `kxm routes list
|
|
1048
|
+
| `roles` | Map of name to route strings | Optional, `{}` | Not read by any code path yet; shown only by `kxm routes list --json`, and preserved on rewrite. Role rosters live in `.kxm/roles/` |
|
|
981
1049
|
| `updatedAt` | ISO timestamp string | Optional | Rewritten by every CLI change |
|
|
982
1050
|
|
|
983
1051
|
A route string is exactly the agent's `model.provider`, a slash, and
|
|
@@ -1020,7 +1088,7 @@ report them; review them in the pull request diff.
|
|
|
1020
1088
|
## `.kxm/roster.yaml` (`kxm.developer-roster.v1`)
|
|
1021
1089
|
|
|
1022
1090
|
The developer roster for `scripts/assignment-run.mjs` (the `just` assignment
|
|
1023
|
-
recipes; see [Assignment runner](assignment-runner.md)). It applies to the KXM
|
|
1091
|
+
recipes; see [Assignment runner](../contributing/assignment-runner.md)). It applies to the KXM
|
|
1024
1092
|
source repository itself: the loader in `scripts/roster-policy.mjs` reads the
|
|
1025
1093
|
copy committed at `HEAD` of the repository that contains the script, and
|
|
1026
1094
|
refuses unless the worktree is clean, `HEAD` is an ancestor of
|
|
@@ -1212,11 +1280,14 @@ models:
|
|
|
1212
1280
|
cacheReadPerMillion: 0.25
|
|
1213
1281
|
```
|
|
1214
1282
|
|
|
1215
|
-
Commands: the
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1283
|
+
Commands: the one-shot producer, which the Runtime uses for every harness,
|
|
1284
|
+
reads it on every attempt and ignores a catalog not dated today (the package's
|
|
1285
|
+
long-lived Pi producer also reads it, but nothing in the Runtime calls that
|
|
1286
|
+
producer today); `kxm explain` reports `catalogStatus` (`verified`, `stale`,
|
|
1287
|
+
`corrupt`, or `missing`); `kxm routing report --list-prices [--prices <file>]`
|
|
1288
|
+
reads it (default `<workspace>/prices.yaml`, normally `.kxm/prices.yaml`) and
|
|
1289
|
+
ignores a bad file. The report skips the freshness check, so it prices with a
|
|
1290
|
+
catalog of any date, including one the producers treat as stale.
|
|
1220
1291
|
|
|
1221
1292
|
## `.kxm/models/inventory.yaml` (`kxm.model-inventory.v1`)
|
|
1222
1293
|
|
|
@@ -1287,7 +1358,7 @@ commands themselves are not counted.
|
|
|
1287
1358
|
| `sync.jira.host`, `.projectKey`, `.issueType`, `.autoTransition` | String or boolean | none | Not read by any code path yet |
|
|
1288
1359
|
| `improvement.promotionPolicy` | `manual_pr`, `critic_quorum`, or `auto_threshold`; any other value falls back to `manual_pr` | `manual_pr` | `kxm improve` (`cmdImprove` in `plugins/kxm/src/cli/system.ts`, then `evaluatePromotionPolicy` in `improve.ts`): selects the review-readiness rule reported per candidate. No value authorizes or activates anything |
|
|
1289
1360
|
| `improvement.telemetryHalfLifeDays` | Number greater than 0 and at most 3650; otherwise `14` | `14` | `kxm improve`: the half-life of each record's weight in `weightedRecurrence`, which orders report rows and never decides candidacy |
|
|
1290
|
-
| `improvement.autoThreshold.minRuns`, `.minPassRate`, `.minCostSavings` | `minRuns` an integer from 1 to 1,000,000, `minPassRate` from 0 to 1, `minCostSavings` at least 0; otherwise the default | `10`, `0.95`, `0.5` | `kxm improve`, only under `auto_threshold
|
|
1361
|
+
| `improvement.autoThreshold.minRuns`, `.minPassRate`, `.minCostSavings` | `minRuns` an integer from 1 to 1,000,000, `minPassRate` from 0 to 1, `minCostSavings` at least 0; otherwise the default | `10`, `0.95`, `0.5` | `kxm improve`, only under `auto_threshold` (see below) |
|
|
1291
1362
|
| `routing.shadowExecution.enabled` | Boolean | `false` | Not read by any code path yet |
|
|
1292
1363
|
| `routing.shadowExecution.sampleRate` | Number | `0.05` | Not read by any code path yet |
|
|
1293
1364
|
| `routing.shadowExecution.candidateModels` | Array of strings | `[]` | Not read by any code path yet |
|
|
@@ -1297,6 +1368,11 @@ commands themselves are not counted.
|
|
|
1297
1368
|
| `telemetry.anonymize` | Boolean | `true` | Not read by any code path yet |
|
|
1298
1369
|
| `telemetry.userTelemetryDir` | Path | none | Not read by any code path yet |
|
|
1299
1370
|
|
|
1371
|
+
Under `auto_threshold`, `minRuns`, `minPassRate` and `minCostSavings` are the
|
|
1372
|
+
distinct runs, the accepted share, and the mean recorded cost per attempt a
|
|
1373
|
+
candidate needs before `kxm improve` reports it ready for review. A group with
|
|
1374
|
+
no recorded cost is never ready.
|
|
1375
|
+
|
|
1300
1376
|
```yaml
|
|
1301
1377
|
# .kxm/config.yaml (project scope) or ~/.config/kxm/config.yaml (user scope).
|
|
1302
1378
|
# Only hub.autoStart and improvement.* change behavior today.
|
|
@@ -1337,6 +1413,24 @@ Commands:
|
|
|
1337
1413
|
There is no `kxm config unset`. Delete the key from the file to fall back to
|
|
1338
1414
|
the next layer; setting `null` stores `null`.
|
|
1339
1415
|
|
|
1416
|
+
### Configuration layers
|
|
1417
|
+
|
|
1418
|
+
Preferences resolve through three file layers, and environment variables configure the processes beside them without overriding any `kxm.config.v1` key.
|
|
1419
|
+
|
|
1420
|
+
```mermaid
|
|
1421
|
+
flowchart LR
|
|
1422
|
+
D["Built-in defaults<br/>config.ts"] -->|"overridden by"| U["User layer<br/>~/.config/kxm/config.yaml"]
|
|
1423
|
+
U -->|"overridden by"| P["Project layer<br/>.kxm/config.yaml"]
|
|
1424
|
+
P --> V["Merged view<br/>kxm config list"]
|
|
1425
|
+
CU["kxm config set --scope user"] -->|writes| U
|
|
1426
|
+
CP["kxm config set<br/>(project scope, the default)"] -->|writes| P
|
|
1427
|
+
E["Environment variables<br/>KXM_*"] -.->|"KXM_USER_CONFIG_DIR moves it"| U
|
|
1428
|
+
E -->|"configure; never override these keys"| S["Hub, agent, worker<br/>and Runtime processes"]
|
|
1429
|
+
HB["kxm hub start<br/>kxm hub bind"] -->|"persist credentials and URL"| S
|
|
1430
|
+
```
|
|
1431
|
+
|
|
1432
|
+
Values that `kxm hub start` and `kxm hub bind` persist on the machine (`hub-env.json` and `hub-binding.json` under the [state root](#state-outside-the-project)) apply only when the matching variable, such as `KXM_AUTH_TOKEN` or `KXM_SERVER_URL`, is unset. [Environment variables and limits](configuration.md#where-settings-come-from) lists every variable.
|
|
1433
|
+
|
|
1340
1434
|
## `.kxm/modes.yaml` (`kxm.modes.v1`)
|
|
1341
1435
|
|
|
1342
1436
|
Modes for `kxm explain`, which estimates the prompt footprint and token cost of
|
|
@@ -1466,7 +1560,8 @@ Parser: `parseMemoryRecord` in `plugins/kxm/src/memory.ts`.
|
|
|
1466
1560
|
|
|
1467
1561
|
- `.kxm/memory/*.md` (top level only) are authored facts. Only
|
|
1468
1562
|
`lifecycle: active` facts appear in `kxm memory brief` and in the projection
|
|
1469
|
-
that `kxm memory sync` writes into `AGENTS.md`, `CLAUDE.md`, and
|
|
1563
|
+
that `kxm memory sync` writes into whichever of `AGENTS.md`, `CLAUDE.md`, and
|
|
1564
|
+
`GEMINI.md` already exist; it never creates them.
|
|
1470
1565
|
- `.kxm/memory/candidates/*.md` are candidates written by `kxm memory note`.
|
|
1471
1566
|
Promote one by moving it into `.kxm/memory/` in a reviewed change.
|
|
1472
1567
|
- Every file under `.kxm/memory/` except `candidates/` is hashed into the
|
|
@@ -1521,18 +1616,19 @@ Validated with `kxm memory brief --json`.
|
|
|
1521
1616
|
Both directories are written by commands, not configured by hand.
|
|
1522
1617
|
|
|
1523
1618
|
- `.kxm/skills/` holds the governed skill lifecycle:
|
|
1524
|
-
`candidates/<id>/`, `promoted/<id>/`, `
|
|
1619
|
+
`candidates/<id>/`, `promoted/<id>/`, `quarantineds/<id>/` (the directory name
|
|
1620
|
+
the code uses for the `quarantined` state), and
|
|
1525
1621
|
`rejected/<id>/`, each with `SKILL.md` and `metadata.json`
|
|
1526
1622
|
(`kxm.skill-candidate.v1`), plus `history/<id>.jsonl`. Written by
|
|
1527
1623
|
`kxm skills create|evaluate|promote|reject`; `kxm skills verify` detects
|
|
1528
1624
|
out-of-band edits to promoted skills. Promoted skills are hashed into the
|
|
1529
|
-
memory revision pinned on each run. See [Skills](skills.md).
|
|
1625
|
+
memory revision pinned on each run. See [Skills](../guides/governed-skills.md).
|
|
1530
1626
|
- `.kxm/candidates/` holds improvement candidates (`<id>.json`,
|
|
1531
1627
|
`kxm.candidate.v1`, with a proposed diff file) written by `kxm improve`
|
|
1532
1628
|
(`--out-dir` relocates them; `--dry-run` writes none). The report itself goes to
|
|
1533
1629
|
`<workspace>/assets/improvements/`. A candidate is a proposal: its diff has
|
|
1534
1630
|
placeholder hunks, nothing applies it, and its promotion readiness never
|
|
1535
|
-
authorizes. See [Continuous improvement](continuous-improvement.md#coded-repeats-kxm-improve).
|
|
1631
|
+
authorizes. See [Continuous improvement](../guides/continuous-improvement.md#coded-repeats-kxm-improve).
|
|
1536
1632
|
|
|
1537
1633
|
## Webhook workflow definitions
|
|
1538
1634
|
|
|
@@ -1548,114 +1644,14 @@ treated as legacy configuration and makes the whole project unloadable
|
|
|
1548
1644
|
either; those are `kxm.workflow.v1` files and fail to parse as JSON. A path
|
|
1549
1645
|
such as `.kxm/assets/webhooks/workflows.json` works.
|
|
1550
1646
|
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
| `event` | String, at most 128 characters | Optional provider event filter |
|
|
1560
|
-
| `filter.path`, `filter.equals` | Dotted JSON path and exact string | Optional |
|
|
1561
|
-
| `delivery` | `followUp` or `steer` | `followUp` |
|
|
1562
|
-
| `ttlMs` | Integer, 1,000 to 604,800,000 | Optional |
|
|
1563
|
-
| `promptTemplate` | String, at most 20,000 characters, with `{{payload.path}}` substitutions | Required |
|
|
1564
|
-
| `maxTransitions` | Integer, 1 to 200 | Required when any stage has a back-edge |
|
|
1565
|
-
| `planHash`, `reproOracle` | `{stageId, evidenceKey}` | Optional |
|
|
1566
|
-
| `requirePlanHash` | Stage IDs | Optional |
|
|
1567
|
-
| `stages` | 1 to 32 stages | Required |
|
|
1568
|
-
| `stages[].id` | String, at most 64 characters, unique | Required |
|
|
1569
|
-
| `stages[].label` | String, at most 128 characters | The stage ID |
|
|
1570
|
-
| `stages[].instructions` | String, at most 4,000 characters | Required |
|
|
1571
|
-
| `stages[].requiredEvidence` | Up to 32 strings, unique after trimming, collapsing whitespace, and lowercasing | `[]` |
|
|
1572
|
-
| `stages[].maxAttempts` | Integer, 1 to 20 | `3` |
|
|
1573
|
-
| `stages[].autoResumeLimit` | Integer, 1 to 20 | Optional |
|
|
1574
|
-
| `stages[].area` | `harness`, `gates`, `implementation`, `workflow`, `documentation`, `security`, or `other` | Optional |
|
|
1575
|
-
| `stages[].on` | Map of outcome to a stage ID, `$terminal`, or `{target, maxTransitions}` | Optional |
|
|
1576
|
-
| `stages[].maxTransitions` | Integer, 1 to 100 | Optional |
|
|
1577
|
-
| `stages[].evidencePolicies.<requirement>` | `{kind: peer-reply, minProducers (1 to 8), eligibleAgents (1 to 16), acceptedStatuses: [replied], degradation: {minProducers}}` | Optional; see [Peer provenance and quorum gates](provenance-gates.md) |
|
|
1578
|
-
|
|
1579
|
-
Rules that differ from `kxm.workflow.v1`: a forward transition may only target
|
|
1580
|
-
the next stage; `$terminal` takes no `terminalStatus`; an evidence policy key
|
|
1581
|
-
must match a `requiredEvidence` entry, may not list the workflow `target` among
|
|
1582
|
-
its eligible agents, and its degradation minimum must be lower than
|
|
1583
|
-
`minProducers` (a degraded minimum below 2 is a warning). Unknown fields are
|
|
1584
|
-
ignored rather than rejected, and errors are plain messages, not codes. The
|
|
1585
|
-
secret variables must be set when the file is parsed.
|
|
1586
|
-
|
|
1587
|
-
```json
|
|
1588
|
-
[
|
|
1589
|
-
{
|
|
1590
|
-
"id": "jira-development",
|
|
1591
|
-
"source": "jira",
|
|
1592
|
-
"project": "payments",
|
|
1593
|
-
"target": "coordinator",
|
|
1594
|
-
"secretEnv": "JIRA_WEBHOOK_SECRET",
|
|
1595
|
-
"signalSecretEnv": "WORKFLOW_SIGNAL_SECRET",
|
|
1596
|
-
"event": "jira:issue_updated",
|
|
1597
|
-
"filter": { "path": "issue.fields.status.name", "equals": "In Progress" },
|
|
1598
|
-
"delivery": "followUp",
|
|
1599
|
-
"ttlMs": 86400000,
|
|
1600
|
-
"maxTransitions": 6,
|
|
1601
|
-
"planHash": { "stageId": "plan", "evidenceKey": "approved plan" },
|
|
1602
|
-
"requirePlanHash": ["implement"],
|
|
1603
|
-
"promptTemplate": "Deliver {{issue.key}}: {{issue.fields.summary}}",
|
|
1604
|
-
"stages": [
|
|
1605
|
-
{
|
|
1606
|
-
"id": "plan",
|
|
1607
|
-
"label": "Plan and review",
|
|
1608
|
-
"instructions": "Produce a plan and collect two independent peer reviews.",
|
|
1609
|
-
"requiredEvidence": ["approved plan", "peer reviews"],
|
|
1610
|
-
"evidencePolicies": {
|
|
1611
|
-
"peer reviews": {
|
|
1612
|
-
"kind": "peer-reply",
|
|
1613
|
-
"minProducers": 2,
|
|
1614
|
-
"eligibleAgents": ["reviewer-claude", "reviewer-grok"],
|
|
1615
|
-
"acceptedStatuses": ["replied"],
|
|
1616
|
-
"degradation": { "minProducers": 1 }
|
|
1617
|
-
}
|
|
1618
|
-
},
|
|
1619
|
-
"maxAttempts": 3,
|
|
1620
|
-
"area": "workflow",
|
|
1621
|
-
"on": { "passed": "implement" }
|
|
1622
|
-
},
|
|
1623
|
-
{
|
|
1624
|
-
"id": "implement",
|
|
1625
|
-
"label": "Implement",
|
|
1626
|
-
"instructions": "Implement the approved plan.",
|
|
1627
|
-
"requiredEvidence": ["diff"],
|
|
1628
|
-
"maxAttempts": 3,
|
|
1629
|
-
"autoResumeLimit": 2,
|
|
1630
|
-
"area": "implementation",
|
|
1631
|
-
"on": { "passed": "ci" }
|
|
1632
|
-
},
|
|
1633
|
-
{
|
|
1634
|
-
"id": "ci",
|
|
1635
|
-
"label": "Wait for CI",
|
|
1636
|
-
"instructions": "Start kxm_workflow_wait and let kxm gate github watch report the checks.",
|
|
1637
|
-
"requiredEvidence": ["github.check:ci"],
|
|
1638
|
-
"maxAttempts": 3,
|
|
1639
|
-
"area": "gates",
|
|
1640
|
-
"on": {
|
|
1641
|
-
"passed": "$terminal",
|
|
1642
|
-
"failed": { "target": "implement", "maxTransitions": 2 }
|
|
1643
|
-
},
|
|
1644
|
-
"maxTransitions": 2
|
|
1645
|
-
}
|
|
1646
|
-
]
|
|
1647
|
-
}
|
|
1648
|
-
]
|
|
1649
|
-
```
|
|
1650
|
-
|
|
1651
|
-
Validated with `kxm gate validate --file .kxm/assets/webhooks/workflows.json`
|
|
1652
|
-
with both secret variables set (one warning, for the degraded minimum of 1).
|
|
1653
|
-
|
|
1654
|
-
Commands: `kxm gate validate [--file <path>]` parses the active source without
|
|
1655
|
-
printing secrets (exit 2 when no source or both variables are set); the hub
|
|
1656
|
-
loads it on `kxm hub start`; `kxm workflow start`, `kxm gate signal`, and
|
|
1657
|
-
`kxm gate github watch` resolve each definition's secret variables. See
|
|
1658
|
-
[Webhook workflows](webhook-workflows.md).
|
|
1647
|
+
[Workflow definitions](workflow-definitions.md#webhook-workflow-definitions)
|
|
1648
|
+
documents every definition, stage and evidence-policy field, the transition
|
|
1649
|
+
rules, the limits, and a validated example. Check a file with
|
|
1650
|
+
`kxm gate validate --file <path>` (exit 2 when no source or both variables are
|
|
1651
|
+
set); the hub loads it on `kxm hub start`, and `kxm workflow start`,
|
|
1652
|
+
`kxm gate signal` and `kxm gate github watch` resolve each definition's secret
|
|
1653
|
+
variables. See [Webhook workflows](../guides/webhook-workflows.md) for a
|
|
1654
|
+
walk-through.
|
|
1659
1655
|
|
|
1660
1656
|
## Claude Code plugin settings
|
|
1661
1657
|
|
|
@@ -1666,17 +1662,22 @@ declares `userConfig` fields that Claude Code asks each user for. The plugin's
|
|
|
1666
1662
|
| `userConfig` field | Environment variable | Required, default | Notes |
|
|
1667
1663
|
|---|---|---|---|
|
|
1668
1664
|
| `server_url` | `KXM_SERVER_URL` | Required, `http://127.0.0.1:7331` | The MCP server also falls back to that URL when empty |
|
|
1669
|
-
| `auth_token` | `KXM_AUTH_TOKEN` | Optional; marked sensitive | Use the project token, never the admin token.
|
|
1665
|
+
| `auth_token` | `KXM_AUTH_TOKEN` | Optional; marked sensitive | Use the project token, never the admin token. See below for the fallback |
|
|
1670
1666
|
| `agent_name` | `KXM_AGENT_NAME` | Required, `claude` | When empty, `claude-<pid>`. If another live session already holds the name, the server registers once more as `<name>-<pid>` |
|
|
1671
1667
|
| `agent_purpose` | `KXM_AGENT_PURPOSE` | Required, `Claude Code implementation and review agent` | |
|
|
1672
1668
|
| `project` | `KXM_PROJECT` | Optional | When empty, the `name` in `package.json` at the project directory, else the directory name |
|
|
1673
1669
|
| (not a user field) | `KXM_PROJECT_DIR` | Set from `${CLAUDE_PROJECT_DIR}` | Used to derive the default project |
|
|
1674
1670
|
|
|
1671
|
+
When `auth_token` is empty, the MCP server uses only this project's saved
|
|
1672
|
+
project token from the hub credential file (`hub-env.json`) and never falls
|
|
1673
|
+
back to the admin token. With neither, tool calls fail with a message naming
|
|
1674
|
+
the fix.
|
|
1675
|
+
|
|
1675
1676
|
The manifest also registers one `SessionStart` hook,
|
|
1676
1677
|
`node ${CLAUDE_PLUGIN_ROOT}/dist/claude-hook.js session-start`, with a 5-second
|
|
1677
1678
|
timeout. It runs only inside a KXM project, reads this project's state only,
|
|
1678
1679
|
never mints a token or writes a file, and always exits 0. See the
|
|
1679
|
-
[plugin README](
|
|
1680
|
+
[plugin README](../../plugins/kxm/README.md) for what it adds to the session.
|
|
1680
1681
|
|
|
1681
1682
|
## Updater settings (`kxm.update.v1`)
|
|
1682
1683
|
|
|
@@ -1715,16 +1716,18 @@ Everything under `.kxm/` at the project root falls into one of three groups.
|
|
|
1715
1716
|
| `logs/` | Ignored runtime logs | The hub and workers |
|
|
1716
1717
|
| `state/` | Ignored restart state: the hub database `kxm.db`, Pi sessions, worker manifests | The hub and workers |
|
|
1717
1718
|
| `run/` | Ignored sockets (`run/ssh-sockets/`) | `kxm ssh` |
|
|
1719
|
+
| `backups/` | Ignored; each `backup-<time>/` holds a copy of the hub database and `manifest.json` | `kxm backup` (without `--out`) |
|
|
1718
1720
|
| `config/` | Legacy: its JSON files make the project unloadable | Nothing current |
|
|
1719
1721
|
| `.kxm-init-transaction/` (sibling of `.kxm/` at the Git root) | Ignored; interrupted `kxm init` state | `kxm init` |
|
|
1720
1722
|
|
|
1721
|
-
|
|
1723
|
+
Recommended ignore rules for a project, based on the ones the KXM repository uses plus `.kxm/backups/`:
|
|
1722
1724
|
|
|
1723
1725
|
```text
|
|
1724
1726
|
.kxm/logs/*
|
|
1725
1727
|
.kxm/state/*
|
|
1726
1728
|
.kxm/tasks/
|
|
1727
1729
|
.kxm/run/
|
|
1730
|
+
.kxm/backups/
|
|
1728
1731
|
.kxm/assets/generated/
|
|
1729
1732
|
.kxm-init-transaction/
|
|
1730
1733
|
*.db
|
|
@@ -1735,7 +1738,8 @@ The ignore rules the KXM repository itself uses, adapted for a project:
|
|
|
1735
1738
|
`KXM_WORKSPACE_DIR`, `KXM_LOGS_DIR`, `KXM_ASSETS_DIR`, `KXM_STATE_DIR`, and
|
|
1736
1739
|
related variables move `logs/`, `assets/`, and `state/`. They do not move the
|
|
1737
1740
|
configuration files, which always live under `<project root>/.kxm/`. See
|
|
1738
|
-
[
|
|
1741
|
+
[Workspace directories](configuration.md#workspace-directories) and
|
|
1742
|
+
[Backup and restore](../operations/backup-and-restore.md).
|
|
1739
1743
|
|
|
1740
1744
|
### State outside the project
|
|
1741
1745
|
|
|
@@ -1941,3 +1945,10 @@ In a project that `kxm init` created,
|
|
|
1941
1945
|
same shape (without the `requiredEvidence` entries), and `kxm run` prints the
|
|
1942
1946
|
matching `kxm runs drive <runId> --simulated --wait` command for each run it
|
|
1943
1947
|
creates.
|
|
1948
|
+
|
|
1949
|
+
## Related
|
|
1950
|
+
|
|
1951
|
+
- [Environment variables and limits](configuration.md): hub, agent and worker settings
|
|
1952
|
+
- [Workflow definitions](workflow-definitions.md): webhook JSON and Runtime YAML side by side
|
|
1953
|
+
- [CLI reference](cli-reference.md): the commands that read and write these files
|
|
1954
|
+
- [Harness routing](harness-routing.md): choose and confirm a model route
|