@kontextmind/kxm 0.6.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.
- package/.claude-plugin/marketplace.json +19 -0
- package/.kxm/README.md +14 -0
- package/.kxm/assets/README.md +5 -0
- package/.kxm/assets/retrospectives/README.md +5 -0
- package/.kxm/config/README.md +5 -0
- package/.kxm/config/agents.json +43 -0
- package/.kxm/config/env.example +56 -0
- package/.kxm/config/update.example.yaml +9 -0
- package/.kxm/config/workflows/fix.json +160 -0
- package/.kxm/config/workflows/jira-development.json +116 -0
- package/.kxm/config/workflows/provenance-quorum.json +150 -0
- package/.kxm/config/workflows/v04-dogfood.json +72 -0
- package/CHANGELOG.md +465 -0
- package/LICENSE +21 -0
- package/README.md +306 -0
- package/SECURITY.md +72 -0
- package/docs/README.md +48 -0
- package/docs/agent-communication-envelopes-and-gates.md +553 -0
- package/docs/architecture.md +242 -0
- package/docs/assignment-runner.md +241 -0
- package/docs/configuration.md +361 -0
- package/docs/continuous-improvement.md +114 -0
- package/docs/getting-started.md +253 -0
- package/docs/kxm-handbook.md +1090 -0
- package/docs/operations.md +205 -0
- package/docs/provenance-gates.md +291 -0
- package/docs/skills.md +45 -0
- package/docs/templates/README.md +95 -0
- package/docs/templates/adr.md +88 -0
- package/docs/templates/architecture.md +120 -0
- package/docs/templates/bug-fix.md +109 -0
- package/docs/templates/feature.md +108 -0
- package/docs/templates/handoff.md +72 -0
- package/docs/templates/postmortem.md +77 -0
- package/docs/templates/research.md +100 -0
- package/docs/templates/review.md +85 -0
- package/docs/templates/runbook.md +73 -0
- package/docs/templates/test-plan.md +87 -0
- package/docs/templates/test-report.md +72 -0
- package/docs/test-matrix.md +121 -0
- package/docs/troubleshooting.md +249 -0
- package/docs/vnext/README.md +62 -0
- package/docs/vnext/architecture.md +185 -0
- package/docs/vnext/effects-and-recovery.md +172 -0
- package/docs/vnext/lifecycles.md +235 -0
- package/docs/vnext/migration.md +220 -0
- package/docs/vnext/routing.md +184 -0
- package/docs/vnext/synchronization.md +172 -0
- package/docs/vnext/terminology.md +240 -0
- package/docs/vnext/validation.md +335 -0
- package/docs/webhook-workflows.md +240 -0
- package/docs/workflow-guide.md +1150 -0
- package/examples/README.md +102 -0
- package/examples/provenance-workflow.json +40 -0
- package/examples/requester.ts +30 -0
- package/examples/reviewer-agent.ts +29 -0
- package/examples/roundtrip.ts +46 -0
- package/examples/vnext/.kxm/agents/coordinator.yaml +16 -0
- package/examples/vnext/.kxm/agents/critic-1.yaml +16 -0
- package/examples/vnext/.kxm/agents/critic-2.yaml +15 -0
- package/examples/vnext/.kxm/agents/critic-3.yaml +15 -0
- package/examples/vnext/.kxm/agents/implementer.yaml +15 -0
- package/examples/vnext/.kxm/agents/planner.yaml +13 -0
- package/examples/vnext/.kxm/agents/reproducer.yaml +15 -0
- package/examples/vnext/.kxm/agents/reviewer.yaml +15 -0
- package/examples/vnext/.kxm/gates.yaml +8 -0
- package/examples/vnext/.kxm/models/critic-claude.yaml +11 -0
- package/examples/vnext/.kxm/models/critic-gemini.yaml +11 -0
- package/examples/vnext/.kxm/models/critic-grok.yaml +12 -0
- package/examples/vnext/.kxm/models/implementation.yaml +14 -0
- package/examples/vnext/.kxm/models/primary.yaml +17 -0
- package/examples/vnext/.kxm/prices.yaml +111 -0
- package/examples/vnext/.kxm/project/env.yaml +7 -0
- package/examples/vnext/.kxm/project.yaml +32 -0
- package/examples/vnext/.kxm/repo/repo.yaml +8 -0
- package/examples/vnext/.kxm/workflows/default.yaml +92 -0
- package/examples/vnext/.kxm/workflows/fix.yaml +376 -0
- package/examples/vnext/.kxm/workflows/improve.yaml +57 -0
- package/examples/vnext/README.md +53 -0
- package/examples/vnext/records/assignment-result-recorded.json +63 -0
- package/examples/vnext/records/assignment-result.json +46 -0
- package/examples/vnext/records/context-candidate.json +42 -0
- package/examples/vnext/records/delivery-manifest.json +66 -0
- package/examples/vnext/records/effect-uncertainty-resolved-sync.json +67 -0
- package/examples/vnext/records/effect-uncertainty-resolved.json +62 -0
- package/examples/vnext/records/run-created.json +54 -0
- package/examples/vnext/records/sync-event.json +65 -0
- package/examples/vnext/repositories/api/.kxm/repo/env.yaml +7 -0
- package/examples/vnext/repositories/api/.kxm/repo/repo.yaml +8 -0
- package/examples/vnext/repositories/web/.kxm/repo/repo.yaml +8 -0
- package/examples/workflow-signal.ts +63 -0
- package/package.json +129 -0
- package/plugins/kxm/.claude-plugin/plugin.json +73 -0
- package/plugins/kxm/.mcp.json +19 -0
- package/plugins/kxm/README.md +93 -0
- package/plugins/kxm/dist/cli.js +42853 -0
- package/plugins/kxm/dist/client.js +416 -0
- package/plugins/kxm/dist/core.js +1823 -0
- package/plugins/kxm/dist/extension.js +3797 -0
- package/plugins/kxm/dist/mcp-server.js +17104 -0
- package/plugins/kxm/dist/runtime.js +23361 -0
- package/plugins/kxm/dist/server.js +13640 -0
- package/plugins/kxm/dist/vnext-runtime-supervisor.js +21109 -0
- package/plugins/kxm/package.json +12 -0
- package/plugins/kxm/skills/kxm/SKILL.md +97 -0
- package/plugins/kxm/skills/kxm/references/protocol.md +103 -0
- package/plugins/kxm/skills/kxm-session/SKILL.md +53 -0
- package/plugins/kxm/src/arbiter.ts +355 -0
- package/plugins/kxm/src/artifacts-exist.ts +62 -0
- package/plugins/kxm/src/autocomplete.ts +236 -0
- package/plugins/kxm/src/cli.ts +3707 -0
- package/plugins/kxm/src/client.ts +614 -0
- package/plugins/kxm/src/commands.ts +1063 -0
- package/plugins/kxm/src/config.ts +290 -0
- package/plugins/kxm/src/context/providers.ts +101 -0
- package/plugins/kxm/src/context-packet.ts +332 -0
- package/plugins/kxm/src/context.ts +499 -0
- package/plugins/kxm/src/core.ts +6 -0
- package/plugins/kxm/src/database.ts +563 -0
- package/plugins/kxm/src/diagnostics.ts +184 -0
- package/plugins/kxm/src/envelope.ts +118 -0
- package/plugins/kxm/src/extension.ts +895 -0
- package/plugins/kxm/src/external-effects.ts +299 -0
- package/plugins/kxm/src/github-watch.ts +255 -0
- package/plugins/kxm/src/hub-binding.ts +160 -0
- package/plugins/kxm/src/hub.ts +2502 -0
- package/plugins/kxm/src/improve.ts +383 -0
- package/plugins/kxm/src/inbox.ts +10 -0
- package/plugins/kxm/src/kxm-install-kind.ts +113 -0
- package/plugins/kxm/src/kxm-update-config.ts +39 -0
- package/plugins/kxm/src/kxm-update.ts +238 -0
- package/plugins/kxm/src/local-snapshot.ts +406 -0
- package/plugins/kxm/src/logger.ts +198 -0
- package/plugins/kxm/src/mcp-server.ts +143 -0
- package/plugins/kxm/src/memory.ts +385 -0
- package/plugins/kxm/src/nous-pi.ts +287 -0
- package/plugins/kxm/src/nous-provider.ts +729 -0
- package/plugins/kxm/src/price-calc.ts +87 -0
- package/plugins/kxm/src/prices.ts +121 -0
- package/plugins/kxm/src/protocol.ts +172 -0
- package/plugins/kxm/src/recovery.ts +211 -0
- package/plugins/kxm/src/redact.ts +26 -0
- package/plugins/kxm/src/retrospective.ts +400 -0
- package/plugins/kxm/src/routing.ts +830 -0
- package/plugins/kxm/src/runtime.ts +9 -0
- package/plugins/kxm/src/server.ts +117 -0
- package/plugins/kxm/src/session-work.ts +571 -0
- package/plugins/kxm/src/session.ts +184 -0
- package/plugins/kxm/src/skills.ts +535 -0
- package/plugins/kxm/src/state.ts +326 -0
- package/plugins/kxm/src/store.ts +637 -0
- package/plugins/kxm/src/studio-layout.ts +268 -0
- package/plugins/kxm/src/suggest.ts +162 -0
- package/plugins/kxm/src/task-manager.ts +244 -0
- package/plugins/kxm/src/telemetry.ts +116 -0
- package/plugins/kxm/src/tui.ts +1046 -0
- package/plugins/kxm/src/vnext-bindings.ts +403 -0
- package/plugins/kxm/src/vnext-config.ts +1646 -0
- package/plugins/kxm/src/vnext-engine-artifacts.ts +86 -0
- package/plugins/kxm/src/vnext-engine-command.ts +533 -0
- package/plugins/kxm/src/vnext-engine-compile.ts +722 -0
- package/plugins/kxm/src/vnext-engine-evidence.ts +273 -0
- package/plugins/kxm/src/vnext-engine-fold.ts +1400 -0
- package/plugins/kxm/src/vnext-engine-gate-records.ts +583 -0
- package/plugins/kxm/src/vnext-engine-plan.ts +717 -0
- package/plugins/kxm/src/vnext-engine.ts +2458 -0
- package/plugins/kxm/src/vnext-gate-hash.ts +10 -0
- package/plugins/kxm/src/vnext-harness.ts +1142 -0
- package/plugins/kxm/src/vnext-init.ts +430 -0
- package/plugins/kxm/src/vnext-migrate.ts +1848 -0
- package/plugins/kxm/src/vnext-oneshot-producer.ts +424 -0
- package/plugins/kxm/src/vnext-permission.ts +936 -0
- package/plugins/kxm/src/vnext-pi-producer.ts +628 -0
- package/plugins/kxm/src/vnext-repair.ts +1094 -0
- package/plugins/kxm/src/vnext-runtime-owner.ts +320 -0
- package/plugins/kxm/src/vnext-runtime-store.ts +1560 -0
- package/plugins/kxm/src/vnext-runtime-supervisor.ts +586 -0
- package/plugins/kxm/src/vnext-runtime.ts +663 -0
- package/plugins/kxm/src/vnext-template.ts +247 -0
- package/plugins/kxm/src/wiki.ts +313 -0
- package/plugins/kxm/src/workflow.ts +1548 -0
- package/schemas/vnext/README.md +46 -0
- package/schemas/vnext/agent.schema.json +40 -0
- package/schemas/vnext/assignment-result.schema.json +66 -0
- package/schemas/vnext/backup-manifest.schema.json +89 -0
- package/schemas/vnext/candidate.schema.json +109 -0
- package/schemas/vnext/common.schema.json +422 -0
- package/schemas/vnext/context-candidate.schema.json +76 -0
- package/schemas/vnext/context-packet.schema.json +192 -0
- package/schemas/vnext/delivery-manifest.schema.json +159 -0
- package/schemas/vnext/environment.schema.json +66 -0
- package/schemas/vnext/gate-registry.schema.json +109 -0
- package/schemas/vnext/handoff-manifest.schema.json +146 -0
- package/schemas/vnext/init-operation.schema.json +61 -0
- package/schemas/vnext/local-repository-bindings.schema.json +30 -0
- package/schemas/vnext/memory-record.schema.json +45 -0
- package/schemas/vnext/migration-decision.schema.json +26 -0
- package/schemas/vnext/migration-plan.schema.json +123 -0
- package/schemas/vnext/migration-receipt.schema.json +52 -0
- package/schemas/vnext/model.schema.json +42 -0
- package/schemas/vnext/permission-diff.schema.json +57 -0
- package/schemas/vnext/prices.schema.json +115 -0
- package/schemas/vnext/project.schema.json +85 -0
- package/schemas/vnext/repository.schema.json +24 -0
- package/schemas/vnext/run-event.schema.json +460 -0
- package/schemas/vnext/session-brief.schema.json +153 -0
- package/schemas/vnext/sync-event.schema.json +234 -0
- package/schemas/vnext/template-provenance.schema.json +38 -0
- package/schemas/vnext/workflow.schema.json +248 -0
- package/scripts/assignment-run.d.mts +354 -0
- package/scripts/assignment-run.mjs +4451 -0
- package/scripts/build-runtime.mjs +56 -0
- package/scripts/check-generated.mjs +77 -0
- package/scripts/check-versions.mjs +34 -0
- package/scripts/emit-codex-artifacts.d.mts +9 -0
- package/scripts/emit-codex-artifacts.mjs +91 -0
- package/scripts/harness-run.d.mts +83 -0
- package/scripts/harness-run.mjs +2095 -0
- package/scripts/kxm-hub.mjs +105 -0
- package/scripts/kxm-publish-npm.mjs +327 -0
- package/scripts/kxm-release-github.mjs +472 -0
- package/scripts/kxm-runtime-supervisor.mjs +7 -0
- package/scripts/kxm-worker.mjs +1127 -0
- package/scripts/kxm.mjs +27 -0
- package/scripts/roster-policy.d.mts +20 -0
- package/scripts/roster-policy.mjs +161 -0
- package/scripts/smoke-multi-pi.mjs +479 -0
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
# Architecture
|
|
2
|
+
|
|
3
|
+
KXM is a durable, single-node hub for agents and workflows. It deliberately avoids becoming a shared-memory framework or autonomous workflow scheduler.
|
|
4
|
+
|
|
5
|
+
## Workers
|
|
6
|
+
|
|
7
|
+
Agents and gates share one worker identity schema and one result envelope; they differ by driver.
|
|
8
|
+
|
|
9
|
+
| Kind | Driver | Operator command(s) | Meaning |
|
|
10
|
+
|---|---|---|---|
|
|
11
|
+
| `agent` | `ai` | `kxm agent worker --name <n> --project <p>` | Starts one long-lived Pi worker. Roster values in a workspace `agents.json` (model, thinking) are **not** applied by this command; pass `--model`, `--tools`, and related flags explicitly. |
|
|
12
|
+
| `gate` | `code` | `kxm gate validate`, `kxm gate artifacts-exist`, `kxm gate degrade`, `kxm gate signal`, `kxm gate github watch` | The five implemented deterministic operations. |
|
|
13
|
+
|
|
14
|
+
**Gate names in a workspace `gates.json` are records, not runners.** A record with `driver: "code"` is executable only if it maps to one of the five commands above. There is no `kxm gate run <name>` and no dispatcher; any other declared name (for example `quality`, `git-commit`, `jira-fetch`) is a planned gate that a stage instruction cannot cause to run. `kxm gate validate` parses workflow definitions; it does not check that a stage's named gates are runnable.
|
|
15
|
+
|
|
16
|
+
Shared schemas:
|
|
17
|
+
|
|
18
|
+
- `kxm.worker.v1` — worker identity (`kind`, `driver`, `name`, optional `project`, `model`, `thinking`, `purpose`)
|
|
19
|
+
- `kxm.worker-result.v1` — result envelope (`worker`, `command`, `ok`, `outcome`, `createdAt`, `summary`; additional fields are additive)
|
|
20
|
+
|
|
21
|
+
Envelope parity is a **shape** guarantee, not a **trust** guarantee. An agent-authored envelope, a gate-emitted envelope, and a hub-verified peer reply have different evidentiary weight; see *Trust boundaries*. Non-dry-run envelopes are written to `.kxm/logs/telemetry.jsonl` only by gate commands that use the shared result printer (`gate validate`, `gate artifacts-exist`, `gate degrade`, `gate signal`, and `gate github watch`). Live worker output, hub-side workflow checkpoints, and peer replies are not recorded there; the durable record of workflow activity is the hub's SQLite journal.
|
|
22
|
+
|
|
23
|
+
## Sessions (current behaviour)
|
|
24
|
+
|
|
25
|
+
`kxm session` is an early operator surface whose verbs do not yet share one lifecycle:
|
|
26
|
+
|
|
27
|
+
| Command | What it does today | What it does not do |
|
|
28
|
+
|---|---|---|
|
|
29
|
+
| `kxm session start --id <id> (--mix a,b \| --workflow <definitionId>)` | Resolves names against the workspace `agents.json` / `gates.json`, writes `.kxm/assets/sessions/<id>/session.json` (`kxm.session.v1`), creates `inputs/` and `outputs/` (plus `assets/workflows/<definitionId>/{inputs,outputs,generated}` in workflow mode), and exits. | Start any process, dispatch a workflow, run a gate, or set `KXM_SESSION_ID`. In `--workflow` mode it lists the **entire roster**, not the definition's participants, and does not read the definition. |
|
|
30
|
+
| `kxm session status` | Lists PID claim files and worker-recovery envelopes under `.kxm/state`. | Read `session.json` or report anything `session start` created. |
|
|
31
|
+
| `kxm session brief [--status]` | Read-only hub snapshot of recent workflow runs (tasks) and journal `plan` rows. `--status` prints the status line. No message bodies. | Start a hub, dispatch a workflow, or read vNext Runtime runs |
|
|
32
|
+
| `kxm session stop` | Requests shutdown of the hub **and every worker** with a PID file in the workspace. It takes no session ID and is the same operation as `kxm hub stop`. | Stop one session. **Treat it as a global stop.** |
|
|
33
|
+
|
|
34
|
+
Treat `session.json` as a manifest for humans and dashboards. The effective execution primitives are `kxm hub start` (one hub process), `kxm agent worker` (one worker process), and `kxm workflow start` (one signed run).
|
|
35
|
+
|
|
36
|
+
### Pi model-context isolation
|
|
37
|
+
|
|
38
|
+
A KXM session manifest, a durable workflow run, and a Pi conversation session are different objects:
|
|
39
|
+
|
|
40
|
+
| Object | Durable location | Purpose |
|
|
41
|
+
|---|---|---|
|
|
42
|
+
| KXM session manifest | `.kxm/assets/sessions/<id>/session.json` | Human-reviewed roster/asset plan; never launches a process |
|
|
43
|
+
| Workflow run | `.kxm/state/kxm.db` | Hub-owned stage machine, evidence, journal, messages, and callbacks |
|
|
44
|
+
| Pi session | `.kxm/state/pi-sessions/<workerKey>/.../*.jsonl` | Model conversation history for one exact worker context binding |
|
|
45
|
+
|
|
46
|
+
`kxm agent worker --session-isolation workflow` enables scoped isolation. It remains opt-in for the first upgrade-compatible release so existing shared Pi histories are not silently abandoned. Ordinary messages then bind to a stable `default/` Pi session. Hub-authorized workflow work binds to `runs/<runId>/`, producing one durable Pi history for each `{project, agent, workflowRunId}`. The hub owns the canonical `workflowRunId`; a caller-controlled correlation ID cannot create affinity.
|
|
47
|
+
|
|
48
|
+
```text
|
|
49
|
+
hub message queued
|
|
50
|
+
│
|
|
51
|
+
├─ binding already active ── acknowledge ── one model turn ── reply
|
|
52
|
+
│
|
|
53
|
+
└─ different binding ── leave queued ── atomic route request
|
|
54
|
+
└─ current Pi child closes
|
|
55
|
+
└─ supervisor starts one child
|
|
56
|
+
with target --session-dir
|
|
57
|
+
└─ queued message replays
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
The extension requests a change only while there is no active, awaiting, or settling inbound turn. The supervisor applies it only from the child's `close` handler, so two Pi processes never write the same session JSONL. Provider, tool-timeout, supervisor, and machine restarts resume only the active binding when that directory contains history. Route requests are bound to the exact worker identity and supervisor generation; manifests and canonical run IDs are bounded and validated. At most `KXM_WORKER_MAX_RUN_SESSIONS` run histories are retained, with inactive least-recently-used histories evicted. An invalid manifest is renamed with a `.corrupt-<timestamp>` suffix and the worker fails safely back to the stable default scope; unrelated session directories are never selected by inference.
|
|
61
|
+
|
|
62
|
+
The upgrade-compatible default `--session-isolation off` retains the former single shared Pi history. Enabling `workflow` creates new scoped storage and therefore begins a fresh default history unless the worker already used that scope; authoritative facts must remain in workflow state, assets, and Git.
|
|
63
|
+
|
|
64
|
+
## Design goals
|
|
65
|
+
|
|
66
|
+
- Discover peers by declared purpose.
|
|
67
|
+
- Exchange bounded tasks without merging model contexts.
|
|
68
|
+
- Continue independent work using message IDs and explicit state.
|
|
69
|
+
- Survive hub restarts without losing identities or queued messages.
|
|
70
|
+
- Package one implementation for Pi, Agent Skills, Claude plugins, and MCP.
|
|
71
|
+
- Preserve each harness's safety, approval, and filesystem rules.
|
|
72
|
+
|
|
73
|
+
## Non-goals
|
|
74
|
+
|
|
75
|
+
- Automatic task decomposition or peer selection.
|
|
76
|
+
- Sharing hidden reasoning or complete conversation histories.
|
|
77
|
+
- Coordinating concurrent filesystem writes.
|
|
78
|
+
- Horizontal scaling, multi-primary storage, or exactly-once execution.
|
|
79
|
+
- Replacing verification of peer output.
|
|
80
|
+
|
|
81
|
+
## Components
|
|
82
|
+
|
|
83
|
+
```text
|
|
84
|
+
Pi extension ── HTTP/SSE ──┐
|
|
85
|
+
├── Hub ── SQLite WAL
|
|
86
|
+
Claude MCP ─── HTTP/SSE ───┘ ├── SQLite WAL
|
|
87
|
+
│ ├── signed webhook workflows
|
|
88
|
+
└── stdio MCP ── Claude ├── readiness + metrics
|
|
89
|
+
└── operations + learning journal
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
The hub validates and authenticates requests, stores agents and messages, pushes addressed work over SSE, and exposes a separate administrative metadata-only operations SSE stream for dashboards. Operations wakeups and snapshots are project-scoped and never include request or reply bodies. The hub expires stale work and purges terminal records after the configured retention window. SQLite is the source of restart recovery; in-memory maps are the live working set.
|
|
93
|
+
|
|
94
|
+
**Source of truth.** Semantics are defined by the protocol and schema types (`src/protocol.ts`, `src/workflow.ts`), the hub's durable state (`.kxm/state/kxm.db`: agents, messages, workflow runs, journal), and reviewed workspace configuration in git (`.kxm/config`). The `kxm` CLI, the Pi extension, and the Claude MCP server are **clients** of that state. When a client's behaviour differs from the hub's or a definition's contract, the contract is authoritative and the client is the defect. One deliberate locality limitation remains: `kxm workflow list` / `get` read the local SQLite file rather than the configured hub, so they only describe runs when the operator is on the hub host. Start, signal, and GitHub watch now resolve credentials from the selected active definition and use the start secret as the documented callback fallback.
|
|
95
|
+
|
|
96
|
+
Signed webhook workflows add a durable run and coordinator message in one request. The stable provider delivery ID prevents duplicate Jira or GitHub retries. Ordered checkpoints enforce attempt limits and exact keyed evidence requirements. Local evidence can be accumulated when a coordinator enters a durable `waiting` state; a separately signed and deduplicated external result must complete the remaining named requirements before it can advance the stage. A separate journal preserves plans, decisions, contradictions, errors, and lessons for reviewed continuous improvement.
|
|
97
|
+
|
|
98
|
+
Peer-policy requirements add an evidence plane beside caller-authored strings.
|
|
99
|
+
At run creation, configured eligible agent selectors resolve to stable producer
|
|
100
|
+
IDs and are snapshotted into the run. The coordinator can create countable peer
|
|
101
|
+
work only for the current stage and attempt; the hub stamps immutable workflow
|
|
102
|
+
context on each authorized message. At checkpoint or wait, cited message IDs
|
|
103
|
+
are verified from durable state and converted into metadata-only snapshots with
|
|
104
|
+
producer identity, context, lifecycle timestamps, and request/reply hashes.
|
|
105
|
+
Quorum counts unique producers per requirement. The verified snapshot survives
|
|
106
|
+
normal terminal-message purging without retaining prompt or reply bodies in the
|
|
107
|
+
workflow record.
|
|
108
|
+
|
|
109
|
+
**The coordinator is never a producer.** The hub counts only replies to messages sent *by* the run's target *to* other agents. A policy whose `eligibleAgents` includes the target, or whose `minProducers` exceeds the number of other eligible agents, cannot be satisfied except through `kxm gate degrade`. The definition parser rejects the workflow target inside `eligibleAgents` and rejects `minProducers` beyond the eligible peer pool. Every lifecycle timestamp compared during verification is assigned by the hub's own clock, so worker clock skew does not affect provenance checks.
|
|
110
|
+
|
|
111
|
+
## Workflow lifecycle
|
|
112
|
+
|
|
113
|
+
```text
|
|
114
|
+
running ── checkpoint passed ──> next stage / completed
|
|
115
|
+
│
|
|
116
|
+
├── checkpoint warning or failure ──> retry / failed
|
|
117
|
+
│
|
|
118
|
+
└── explicit external wait ──> waiting
|
|
119
|
+
├── signed result ──> retry / next stage / completed
|
|
120
|
+
└── deadline ──────> failed
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
An ordinary coordinator reply while `running` is a failure because required work was abandoned. A reply while `waiting` is expected: it releases compute and context until the callback creates a fresh message. Signal receipts live inside the persisted workflow record, so provider retries remain deduplicated after restart.
|
|
124
|
+
|
|
125
|
+
Stages form an ordered list. A failed checkpoint retries the **same** stage until `maxAttempts` is exhausted, after which the run is terminal; there are no back-edges (an instruction such as "failures return to build" is prose the engine cannot execute) and no resume verb. Workflow definitions are read from the single file or inline JSON the hub was started with. Each run records a secret-free semantic `definitionHash`, so credential rotation does not create false drift while behavior changes remain auditable.
|
|
126
|
+
|
|
127
|
+
`HubClient` owns registration, rotating agent credentials, heartbeats, bounded HTTP requests, SSE reconnects, and automatic re-registration after hub state loss. The Pi extension adds peer messaging plus workflow checkpoint, wait, journal, and reporting tools. Claude MCP adds the same workflow plane plus `kxm_inbox` and `kxm_reply`.
|
|
128
|
+
|
|
129
|
+
## Message lifecycle
|
|
130
|
+
|
|
131
|
+
```text
|
|
132
|
+
queued ── acknowledge ──> delivered ── reply ──> replied
|
|
133
|
+
│ │
|
|
134
|
+
├──── sender cancel ──────┴───────────────> cancelled
|
|
135
|
+
└──── TTL elapsed ────────────────────────> expired
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
`error` is also terminal. The sender receives an ID immediately. An idempotency key deduplicates an exact retry by the same sender. It does not prevent the recipient from repeating external side effects, so tasks must still be designed to be safely retryable.
|
|
139
|
+
|
|
140
|
+
Queued and delivered records survive restart. When the same project and agent name reconnect, the hub rotates the agent key and replays both states with the same message ID; live clients suppress duplicate notifications and simultaneous turns for that ID. During a Pi session route change, the candidate stays `queued` until the destination child registers and acknowledges it, so a workflow prompt never briefly enters the default model context. Delivery remains at-least-once: a crash after external side effects but before reply can execute the work again, so handlers must be idempotent. Terminal records are retained for diagnostics and polling, then removed automatically.
|
|
141
|
+
|
|
142
|
+
## Trust boundaries
|
|
143
|
+
|
|
144
|
+
The administrative token manages administrative routes and acts as the project token only where no explicit project token exists. A configured project token can access only its project. Registration returns an agent key for identity-specific routes. Token comparisons are constant-time after hashing, and prompt or reply bodies are excluded from logs.
|
|
145
|
+
|
|
146
|
+
Provenance is bounded by those credentials. A project-token holder can register
|
|
147
|
+
a new agent or reclaim an offline agent name and its durable ID in that project,
|
|
148
|
+
so all holders of one project credential form a fully trusted provenance
|
|
149
|
+
domain. A verified peer reply proves the hub-observed durable producer and
|
|
150
|
+
context, not organizational or person independence, model identity,
|
|
151
|
+
non-collusion, correctness, or human approval. Deployments that use provenance
|
|
152
|
+
gates should reserve a distinct administrative token, issue explicit project
|
|
153
|
+
tokens per trust domain, protect network and state access, and keep
|
|
154
|
+
consequential repository or human gates authoritative.
|
|
155
|
+
|
|
156
|
+
`.kxm/state/kxm.db` is not encrypted by the application and contains messages plus agent credentials — message bodies are stored as sent, not redacted. Protect the `.kxm` runtime directories with operating-system permissions and encrypted storage where required. Structured hub logs omit message bodies, but raw worker agent logs (`pi-agent-*.log`) capture the Pi process's stdout and stderr verbatim and may contain model or tool output, including anything a tool printed. Peer content remains untrusted regardless of authentication.
|
|
157
|
+
|
|
158
|
+
**Filesystem write boundaries are not enforced.** The worker launcher's `KXM_WORKER_TOOLS` allowlist restricts which Pi tools a worker may call (for example omitting `write`, `edit`, and the platform shell); it does not restrict paths. Any worker that has a write-capable tool can modify any file its OS user can reach, in any repository under its working directory. Workspace roster fields such as `ownership.writeAgent` and `roles` in `agents.json`, and `mode` or `notes` in `host.json`, are **not read by the hub, the CLI, or the launcher** (host mode is inferred from the `KXM_SERVER_URL` hostname). They document intent for humans and prompts. Deployments that need a real boundary should give non-writer workers a tool allowlist without write tools and/or a separate read-only Git worktree, and review changed paths against the plan.
|
|
159
|
+
|
|
160
|
+
Workflow session isolation is a context-routing and accidental-cross-run safety mechanism, not a security sandbox against a malicious process running as the same OS user. A shell-capable model can reach any state or session file its account can reach and inherits the worker routing environment. The supervisor rejects linked/aliased session directories and validates route identity, generation, source binding, and bounds to contain stale or malformed state, but OS separation is required against a deliberately hostile worker. Keep `.kxm/state` ACL-restricted, withhold shell/write tools from untrusted peers, or run them under separate accounts/containers.
|
|
161
|
+
|
|
162
|
+
## Source layout
|
|
163
|
+
|
|
164
|
+
| Path | Responsibility |
|
|
165
|
+
|---|---|
|
|
166
|
+
| `.kxm/config/` | Tracked workspace workflow and harness configuration |
|
|
167
|
+
| `.kxm/logs/` | Ignored hub, worker, and Pi process logs |
|
|
168
|
+
| `.kxm/assets/` | Intentional workflow inputs and outputs |
|
|
169
|
+
| `.kxm/state/` | Ignored SQLite and restart-recovery state |
|
|
170
|
+
| `src/protocol.ts` | Types, limits, validation, and identifiers |
|
|
171
|
+
| `src/store.ts` | SQLite schema, persistence, and health checks |
|
|
172
|
+
| `src/hub.ts` | HTTP/SSE API, policy, lifecycle, and metrics |
|
|
173
|
+
| `src/client.ts` | Registration, transport, recovery, and polling |
|
|
174
|
+
| `src/extension.ts` | Native Pi integration |
|
|
175
|
+
| `src/mcp-server.ts` | Claude MCP and channel integration |
|
|
176
|
+
| `src/server.ts` | Hub executable and environment configuration |
|
|
177
|
+
| `src/workflow.ts` | Workflow definitions, checkpoints, prompt rendering, and improvement reports |
|
|
178
|
+
| `src/diagnostics.ts` | Allowlisted failure classes and 403 hints |
|
|
179
|
+
| `src/redact.ts` | Secret and token redaction helpers |
|
|
180
|
+
| `src/inbox.ts` | Deduplicated Claude MCP inbox notification delivery |
|
|
181
|
+
| `src/artifacts-exist.ts` | Asset containment and non-empty regular-file gate |
|
|
182
|
+
| `src/tui.ts` | Read-only SSE observer dashboard |
|
|
183
|
+
| `src/local-snapshot.ts` | Read-only hub SQLite snapshot (runs, plans, inbox metadata; no bodies) |
|
|
184
|
+
| `src/session-work.ts` | Session brief, status line, and work-picker labels from that snapshot |
|
|
185
|
+
| `src/hub-binding.ts` | host-level hub binding (Runtime-local, never Git) and 300 ms health probe |
|
|
186
|
+
| `src/kxm-update.ts` | Operator package update check (GitHub releases now, npm later), release-asset digest, and notice cache |
|
|
187
|
+
| `scripts/kxm-release-github.mjs` | Tag-triggered draft GitHub release helper: by-tag published guard, 404-then-list draft discovery with pagination fail-closed, no published-release mutation, digest idempotence |
|
|
188
|
+
| `src/kxm-update-config.ts` | Per-user `update.yaml` under the host state root (`auto` is never read from the project) |
|
|
189
|
+
| `src/kxm-install-kind.ts` | Install-kind classifier (npm-global / npm-local / pi-git / claude-marketplace / source / unknown) |
|
|
190
|
+
| `src/cli.ts` | Operator CLI (agent, session, workflow, gate, hub, dash, improve, context, skills); a client of the hub |
|
|
191
|
+
| `src/envelope.ts` | `kxm.worker.v1` / `kxm.worker-result.v1` constructors |
|
|
192
|
+
| `src/session.ts` | Roster loading and `kxm.session.v1` manifest writing; does not spawn processes |
|
|
193
|
+
| `src/telemetry.ts` | Appends redacted CLI result envelopes to `.kxm/logs/telemetry.jsonl` |
|
|
194
|
+
| `src/improve.ts` | Buckets telemetry events into a proposed-only improvement report; does not read the workflow journal |
|
|
195
|
+
| `src/github-watch.ts` | GitHub check polling to signed signals |
|
|
196
|
+
| `src/retrospective.ts` | Bounded Markdown/JSON export |
|
|
197
|
+
| `src/recovery.ts` | Worker recovery envelope consume |
|
|
198
|
+
| `dist/cli.js` | Generated self-contained operator CLI runtime |
|
|
199
|
+
| `dist/server.js` | Generated self-contained hub runtime |
|
|
200
|
+
| `dist/mcp-server.js` | Generated self-contained Claude runtime |
|
|
201
|
+
|
|
202
|
+
The generated runtimes are committed because installed packages must work without a development toolchain or runtime TypeScript stripping. Edit the source, run `npm run build`, and commit the source and corresponding files under `dist/`.
|
|
203
|
+
|
|
204
|
+
The command groups described in this document (`agent`, `session`, `workflow`, `gate`, `hub`, `dash`, `improve`, `context`, `skills`) plus root `init` are defined in `src/cli.ts`. If `kxm --help` prints a former flat command list instead of these Commander groups, treat it as a stale-`dist` symptom; see [Troubleshooting](troubleshooting.md).
|
|
205
|
+
|
|
206
|
+
Peer-policy fields are additive to SQLite schema version 2 because agents,
|
|
207
|
+
messages, and workflow runs are stored as JSON records. Existing schema-v2
|
|
208
|
+
databases and legacy workflow history remain readable; legacy evidence cannot
|
|
209
|
+
satisfy a newly declared peer policy. Back up the database before upgrading as
|
|
210
|
+
described in [Operations](operations.md).
|
|
211
|
+
|
|
212
|
+
## Context operating system (v0.5)
|
|
213
|
+
|
|
214
|
+
Above the durable workflow/journal plane sits the KXM context engine:
|
|
215
|
+
|
|
216
|
+
```text
|
|
217
|
+
workflow state / journal / provenance → context engine
|
|
218
|
+
├─ temporal state (current/superseded, asOf queries)
|
|
219
|
+
├─ episodes (journal-derived learning records)
|
|
220
|
+
├─ knowledge wiki (compiled, source-linked view)
|
|
221
|
+
├─ skill lifecycle (candidates → protected eval → promote/quarantine)
|
|
222
|
+
└─ role-aware arbiter (per-role packets under token budgets)
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Key invariants:
|
|
226
|
+
|
|
227
|
+
- **Workflow state remains authoritative.** Journal entries are evidence, not policy.
|
|
228
|
+
- **Authority never increases through derivation.** A deterministic grant floor per origin (human/workflow → policy, git → instruction, peer/tool/external/derived → evidence) is enforced at parse time.
|
|
229
|
+
- **Project isolation.** Every context request is project-scoped; cross-project content fails closed.
|
|
230
|
+
- **Promotion is control-plane work.** Agents may propose state and skill candidates; only authorized, evidence-bound decisions promote them.
|
|
231
|
+
|
|
232
|
+
### Provider boundary
|
|
233
|
+
|
|
234
|
+
Optional context backends (a temporal-graph adapter such as Graphiti, or an
|
|
235
|
+
experimental retrieval provider) plug into the internal `ContextProvider` /
|
|
236
|
+
`StateProvider` seams in `plugins/kxm/src/context/providers.ts`. The
|
|
237
|
+
native SQLite implementation (`plugins/kxm/src/state.ts`) is the default
|
|
238
|
+
and the reference. Providers are internal: agents interact only with the
|
|
239
|
+
`kxm context` CLI (`get`, `recall`, `state`, `episode`, `promote`, `explain`,
|
|
240
|
+
`wiki-compile`, `wiki-lint`), governed `kxm skills`, and the Pi/MCP tools
|
|
241
|
+
`kxm_context`, `kxm_recall`, `kxm_state`, `kxm_episode`, and `kxm_promote`.
|
|
242
|
+
Provider failures fail closed to smaller context, never broader authority.
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
# Assignment runner maintainer guide
|
|
2
|
+
|
|
3
|
+
> **Status.** The assignment runner (`scripts/assignment-run.mjs`, `just assign`)
|
|
4
|
+
> is the developer orchestration policy and verification runner for issue 127.
|
|
5
|
+
> It manages native developer assignments, deterministic witness verification,
|
|
6
|
+
> and multi-vendor dual-critic acceptance. It is not the runtime workflow
|
|
7
|
+
> engine (`kxm run`), an agent RPC worker (`kxm agent worker`), or a Phase 11
|
|
8
|
+
> dispatch adapter.
|
|
9
|
+
|
|
10
|
+
This guide explains how maintainers run, verify, attribute, and accept
|
|
11
|
+
assignments, as well as the safety invariants enforced by the developer roster
|
|
12
|
+
policy.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## 1. Overview and role rotation
|
|
17
|
+
|
|
18
|
+
Developer orchestration on this runner uses a role-based rotation backed by
|
|
19
|
+
trusted policy in [`.kxm/roster.json`](../.kxm/roster.json). Roles, harnesses,
|
|
20
|
+
and models are admitted with strict permission and vendor boundaries:
|
|
21
|
+
|
|
22
|
+
| Role | Admitted route | Vendor | Permission | Purpose |
|
|
23
|
+
|---|---|---|---|---|
|
|
24
|
+
| **`writer`** | `grok` / `grok-4.6`, `pi` / `openrouter/qwen/qwen3-coder-plus` | `xai`, `alibaba` | `edit` | Native code authoring. Grok is the default rotation; Qwen on Pi is admitted relief. |
|
|
25
|
+
| **`planner`** | `claude` / `fable` | `anthropic` | `read-only` | Architectural planning and permission boundaries. |
|
|
26
|
+
| **`reviewer-arch`** | `claude` / `fable` | `anthropic` | `read-only` | Architecture, permission, and safety review. |
|
|
27
|
+
| **`reviewer-cli`** | `codex` / `gpt-5.6-sol` | `openai` | `read-only` | CLI surface, documentation, and interface review. |
|
|
28
|
+
|
|
29
|
+
### Core principles
|
|
30
|
+
|
|
31
|
+
- **Independent critics:** Acceptance requires independent review from
|
|
32
|
+
different providers. The writer and each critic must have distinct canonical
|
|
33
|
+
vendors (`xai` / `alibaba`, `anthropic`, `openai`).
|
|
34
|
+
- **Fail-closed dispatch:** Route validation fails closed with `route_invalid` if
|
|
35
|
+
a requested harness/model is not in the admitted role lineup, or if permissions
|
|
36
|
+
exceed the admitted ceiling (e.g. attempting to give edit permissions to a
|
|
37
|
+
read-only reviewer).
|
|
38
|
+
- **Deterministic witness beats extra models:** Implementers run `npm run verify`.
|
|
39
|
+
Root re-runs the fixed witness. Reviewers verify candidate trees; they do not
|
|
40
|
+
replace tests.
|
|
41
|
+
- **Closed schemas:** `accepted.json` (`kxm.task-accepted.v1`) and
|
|
42
|
+
`completion.json` (`kxm.assignment-completion.v1`) schemas are closed. Do not
|
|
43
|
+
add ad-hoc properties.
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## 2. The developer loop
|
|
48
|
+
|
|
49
|
+
The standard progression follows a slim four-step lifecycle:
|
|
50
|
+
|
|
51
|
+
```text
|
|
52
|
+
plan-current ──> assign (writer) ──> witness ──> review (arch + cli) ──> accept
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Do not run the 13-stage `/fix` workflow for daily developer tasks or docs.
|
|
56
|
+
|
|
57
|
+
### Step 1: Current plan pointer
|
|
58
|
+
|
|
59
|
+
Every assignment binds to an explicit plan reference. When working against the
|
|
60
|
+
active plan, stamp or update the pointer:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
just plan-current /abs/task-dir /abs/plan.md <sha256> <base-commit> <expected-generation>
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
The pointer is recorded as `plan-current.json` (`kxm.plan-pointer.v1`) in the
|
|
67
|
+
task directory.
|
|
68
|
+
|
|
69
|
+
### Step 2: Dispatch assignment
|
|
70
|
+
|
|
71
|
+
Create an assignment manifest (`kxm.assignment.v1`) specifying the task id,
|
|
72
|
+
assignment id, kind (`implement`, `review-arch`, `review-cli`), admitted route,
|
|
73
|
+
clean or staged base commit, and deliverables contract.
|
|
74
|
+
|
|
75
|
+
Dispatch using:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
just assign /absolute/path/to/manifest.json
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Under the hood:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
node scripts/assignment-run.mjs run --manifest /absolute/path/to/manifest.json
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
- Manifest validation asserts worktree cleanliness and validates the route
|
|
88
|
+
against `.kxm/roster.json`.
|
|
89
|
+
- Headless execution dispatches to the native harness (or OpenRouter via Pi for
|
|
90
|
+
admitted relief).
|
|
91
|
+
- Successful runs write `completion.json`, candidate snapshot metadata, and
|
|
92
|
+
private sidecars under the assignment record directory.
|
|
93
|
+
|
|
94
|
+
### Step 3: Run the verification witness
|
|
95
|
+
|
|
96
|
+
After the writer completes code changes, execute the fixed verification
|
|
97
|
+
witness:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
just witness /absolute/path/to/record-dir
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Under the hood:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
node scripts/assignment-run.mjs witness --record-dir /absolute/path/to/record-dir
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
The witness executes the fixed gate (`npm run verify`) in the workspace, hashes
|
|
110
|
+
the index and worktree states, and records `witness-receipt.json`
|
|
111
|
+
(`kxm.assignment-witness.v1`). Acceptance requires a witness receipt with
|
|
112
|
+
`result: "passed"`.
|
|
113
|
+
|
|
114
|
+
### Step 4: Dispatch critics
|
|
115
|
+
|
|
116
|
+
Dispatch both designated critics against the candidate index tree:
|
|
117
|
+
|
|
118
|
+
1. **Architecture review (`review-arch`):** Claude Fable (`fable`, read-only).
|
|
119
|
+
2. **CLI & docs review (`review-cli`):** Codex Sol (`gpt-5.6-sol`, read-only).
|
|
120
|
+
|
|
121
|
+
Each review produces its own record directory containing `completion.json` with
|
|
122
|
+
a structured critic verdict (`PASS` or `BLOCK`) bound to the reviewed tree.
|
|
123
|
+
|
|
124
|
+
### Step 5: Acceptance
|
|
125
|
+
|
|
126
|
+
Once the writer passes the witness, changes are committed to Git, and both
|
|
127
|
+
critics have rendered `PASS` verdicts:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
just accept /abs/task-dir <commit-sha> /abs/writer-record /abs/arch-review /abs/cli-review
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Under the hood:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
node scripts/assignment-run.mjs accept \
|
|
137
|
+
--task-dir /abs/task-dir \
|
|
138
|
+
--commit <commit-sha> \
|
|
139
|
+
--record-dir /abs/writer-record \
|
|
140
|
+
--critic /abs/arch-review \
|
|
141
|
+
--critic /abs/cli-review \
|
|
142
|
+
[--observed-pr <pr-id>] \
|
|
143
|
+
[--observed-ci <ci-id>]
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
`accept` validates all acceptance invariants:
|
|
147
|
+
|
|
148
|
+
1. The commit exists and its tree matches the witness index tree.
|
|
149
|
+
2. The writer record matches the latest passed witness.
|
|
150
|
+
3. Both required critic roles (`review-arch` and `review-cli`) are present.
|
|
151
|
+
4. Both critics judged the exact accepted tree and issued `PASS`.
|
|
152
|
+
5. No unresolved `BLOCK` review exists for the tree in the task directory (unless
|
|
153
|
+
superseded by an unbroken `rework_of` lineage).
|
|
154
|
+
6. The writer and all critics satisfy pairwise vendor independence.
|
|
155
|
+
7. Writes `accepted.json` (`kxm.task-accepted.v1`) into the task directory.
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## 3. Attribution and cost tracking
|
|
160
|
+
|
|
161
|
+
### Private attribution notes
|
|
162
|
+
|
|
163
|
+
When friction, environment issues, or model regressions occur, record private
|
|
164
|
+
handoff notes without altering closed completion schemas:
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
just attribute /abs/task-dir /abs/record-dir <class> /abs/note.txt
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
- Allowed classifications: `orchestration`, `model`, `environment`,
|
|
171
|
+
`unclassified`.
|
|
172
|
+
- Appends an immutable attribution entry in the task's attribution history.
|
|
173
|
+
|
|
174
|
+
### Historical cost observation
|
|
175
|
+
|
|
176
|
+
For manual bootstrap runs or unmetered subscription sessions where native
|
|
177
|
+
telemetry was not captured directly:
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
just observe-cost /abs/task-dir /abs/observation.json
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Imports a `kxm.cost-observation.v1` record. Cost observations are strictly
|
|
184
|
+
cost-only; they cannot authorize acceptance or mint witness proof.
|
|
185
|
+
|
|
186
|
+
### Unified change report
|
|
187
|
+
|
|
188
|
+
Generate a consolidated change and cost summary for a task:
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
just change-report /abs/task-dir
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
The change report cleanly separates:
|
|
195
|
+
|
|
196
|
+
- Provider-reported metered spend vs list price estimates.
|
|
197
|
+
- Unmetered subscriptions (e.g. Claude Code or Codex subscription) vs unknown.
|
|
198
|
+
- Token counts, elapsed wall time, witness durations, and attempt counts.
|
|
199
|
+
- Failed or interrupted attempts (never silently omitted or zeroed).
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## 4. Safety invariants and failure codes
|
|
204
|
+
|
|
205
|
+
The runner fails closed with bounded error codes defined in `RUNNER_CODES`:
|
|
206
|
+
|
|
207
|
+
| Code | Trigger condition | Remedy |
|
|
208
|
+
|---|---|---|
|
|
209
|
+
| `route_invalid` | Harness/model not admitted in lineup for the requested role, or permission exceeds route ceiling. | Check `.kxm/roster.json` lineup and permissions for the role. |
|
|
210
|
+
| `critic_invalid` | Missing required critic role, duplicate roles, wrong model, or vendor collision between writer and critics. | Ensure independent critics (Fable + Sol) from distinct providers. |
|
|
211
|
+
| `critic_block` | An unresolved `BLOCK` verdict exists for the target tree. | Rework the changes, address findings, and pass review with a `rework_of` link. |
|
|
212
|
+
| `commit_tree_mismatch` | Git commit tree does not equal the witnessed tree. | Commit the exact candidate tree verified by the witness before running accept. |
|
|
213
|
+
| `witness_failed` | Fixed gate (`npm run verify`) returned a non-zero exit code. | Fix code, typecheck, lint, or test failures and re-witness. |
|
|
214
|
+
| `witness_binding_invalid` | Writer transport incomplete, wrong deliverables boundary, or writer route unadmitted. | Re-run writer assignment through admitted rotation route. |
|
|
215
|
+
| `accepted_exists` | `accepted.json` is already present in the task directory. | Acceptance records are immutable; use a new task directory for new units. |
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
## 5. File layout in task directories
|
|
220
|
+
|
|
221
|
+
A completed task directory contains:
|
|
222
|
+
|
|
223
|
+
```text
|
|
224
|
+
<task-dir>/
|
|
225
|
+
├── plan-current.json # Active plan pointer (kxm.plan-pointer.v1)
|
|
226
|
+
├── plan-current.md # Current plan markdown
|
|
227
|
+
├── accepted.json # Final acceptance proof (kxm.task-accepted.v1)
|
|
228
|
+
├── asg-writer-1/ # Writer assignment record directory
|
|
229
|
+
│ ├── manifest.json # Bound input manifest (kxm.assignment.v1)
|
|
230
|
+
│ ├── prompt.txt # Rendered assignment prompt
|
|
231
|
+
│ ├── completion.json # Completion record (kxm.assignment-completion.v1)
|
|
232
|
+
│ ├── witness-receipt.json # Deterministic gate witness receipt
|
|
233
|
+
│ └── telemetry.jsonl # Usage, latency, and cost telemetry
|
|
234
|
+
├── asg-review-arch/ # Architecture critic record directory
|
|
235
|
+
│ ├── manifest.json
|
|
236
|
+
│ └── completion.json # Contains critic PASS verdict
|
|
237
|
+
├── asg-review-cli/ # CLI critic record directory
|
|
238
|
+
│ ├── manifest.json
|
|
239
|
+
│ └── completion.json # Contains critic PASS verdict
|
|
240
|
+
└── runner-errors.jsonl # Diagnostic log of bounded failure codes
|
|
241
|
+
```
|