@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.
Files changed (227) hide show
  1. package/.claude-plugin/marketplace.json +19 -0
  2. package/.kxm/README.md +14 -0
  3. package/.kxm/assets/README.md +5 -0
  4. package/.kxm/assets/retrospectives/README.md +5 -0
  5. package/.kxm/config/README.md +5 -0
  6. package/.kxm/config/agents.json +43 -0
  7. package/.kxm/config/env.example +56 -0
  8. package/.kxm/config/update.example.yaml +9 -0
  9. package/.kxm/config/workflows/fix.json +160 -0
  10. package/.kxm/config/workflows/jira-development.json +116 -0
  11. package/.kxm/config/workflows/provenance-quorum.json +150 -0
  12. package/.kxm/config/workflows/v04-dogfood.json +72 -0
  13. package/CHANGELOG.md +465 -0
  14. package/LICENSE +21 -0
  15. package/README.md +306 -0
  16. package/SECURITY.md +72 -0
  17. package/docs/README.md +48 -0
  18. package/docs/agent-communication-envelopes-and-gates.md +553 -0
  19. package/docs/architecture.md +242 -0
  20. package/docs/assignment-runner.md +241 -0
  21. package/docs/configuration.md +361 -0
  22. package/docs/continuous-improvement.md +114 -0
  23. package/docs/getting-started.md +253 -0
  24. package/docs/kxm-handbook.md +1090 -0
  25. package/docs/operations.md +205 -0
  26. package/docs/provenance-gates.md +291 -0
  27. package/docs/skills.md +45 -0
  28. package/docs/templates/README.md +95 -0
  29. package/docs/templates/adr.md +88 -0
  30. package/docs/templates/architecture.md +120 -0
  31. package/docs/templates/bug-fix.md +109 -0
  32. package/docs/templates/feature.md +108 -0
  33. package/docs/templates/handoff.md +72 -0
  34. package/docs/templates/postmortem.md +77 -0
  35. package/docs/templates/research.md +100 -0
  36. package/docs/templates/review.md +85 -0
  37. package/docs/templates/runbook.md +73 -0
  38. package/docs/templates/test-plan.md +87 -0
  39. package/docs/templates/test-report.md +72 -0
  40. package/docs/test-matrix.md +121 -0
  41. package/docs/troubleshooting.md +249 -0
  42. package/docs/vnext/README.md +62 -0
  43. package/docs/vnext/architecture.md +185 -0
  44. package/docs/vnext/effects-and-recovery.md +172 -0
  45. package/docs/vnext/lifecycles.md +235 -0
  46. package/docs/vnext/migration.md +220 -0
  47. package/docs/vnext/routing.md +184 -0
  48. package/docs/vnext/synchronization.md +172 -0
  49. package/docs/vnext/terminology.md +240 -0
  50. package/docs/vnext/validation.md +335 -0
  51. package/docs/webhook-workflows.md +240 -0
  52. package/docs/workflow-guide.md +1150 -0
  53. package/examples/README.md +102 -0
  54. package/examples/provenance-workflow.json +40 -0
  55. package/examples/requester.ts +30 -0
  56. package/examples/reviewer-agent.ts +29 -0
  57. package/examples/roundtrip.ts +46 -0
  58. package/examples/vnext/.kxm/agents/coordinator.yaml +16 -0
  59. package/examples/vnext/.kxm/agents/critic-1.yaml +16 -0
  60. package/examples/vnext/.kxm/agents/critic-2.yaml +15 -0
  61. package/examples/vnext/.kxm/agents/critic-3.yaml +15 -0
  62. package/examples/vnext/.kxm/agents/implementer.yaml +15 -0
  63. package/examples/vnext/.kxm/agents/planner.yaml +13 -0
  64. package/examples/vnext/.kxm/agents/reproducer.yaml +15 -0
  65. package/examples/vnext/.kxm/agents/reviewer.yaml +15 -0
  66. package/examples/vnext/.kxm/gates.yaml +8 -0
  67. package/examples/vnext/.kxm/models/critic-claude.yaml +11 -0
  68. package/examples/vnext/.kxm/models/critic-gemini.yaml +11 -0
  69. package/examples/vnext/.kxm/models/critic-grok.yaml +12 -0
  70. package/examples/vnext/.kxm/models/implementation.yaml +14 -0
  71. package/examples/vnext/.kxm/models/primary.yaml +17 -0
  72. package/examples/vnext/.kxm/prices.yaml +111 -0
  73. package/examples/vnext/.kxm/project/env.yaml +7 -0
  74. package/examples/vnext/.kxm/project.yaml +32 -0
  75. package/examples/vnext/.kxm/repo/repo.yaml +8 -0
  76. package/examples/vnext/.kxm/workflows/default.yaml +92 -0
  77. package/examples/vnext/.kxm/workflows/fix.yaml +376 -0
  78. package/examples/vnext/.kxm/workflows/improve.yaml +57 -0
  79. package/examples/vnext/README.md +53 -0
  80. package/examples/vnext/records/assignment-result-recorded.json +63 -0
  81. package/examples/vnext/records/assignment-result.json +46 -0
  82. package/examples/vnext/records/context-candidate.json +42 -0
  83. package/examples/vnext/records/delivery-manifest.json +66 -0
  84. package/examples/vnext/records/effect-uncertainty-resolved-sync.json +67 -0
  85. package/examples/vnext/records/effect-uncertainty-resolved.json +62 -0
  86. package/examples/vnext/records/run-created.json +54 -0
  87. package/examples/vnext/records/sync-event.json +65 -0
  88. package/examples/vnext/repositories/api/.kxm/repo/env.yaml +7 -0
  89. package/examples/vnext/repositories/api/.kxm/repo/repo.yaml +8 -0
  90. package/examples/vnext/repositories/web/.kxm/repo/repo.yaml +8 -0
  91. package/examples/workflow-signal.ts +63 -0
  92. package/package.json +129 -0
  93. package/plugins/kxm/.claude-plugin/plugin.json +73 -0
  94. package/plugins/kxm/.mcp.json +19 -0
  95. package/plugins/kxm/README.md +93 -0
  96. package/plugins/kxm/dist/cli.js +42853 -0
  97. package/plugins/kxm/dist/client.js +416 -0
  98. package/plugins/kxm/dist/core.js +1823 -0
  99. package/plugins/kxm/dist/extension.js +3797 -0
  100. package/plugins/kxm/dist/mcp-server.js +17104 -0
  101. package/plugins/kxm/dist/runtime.js +23361 -0
  102. package/plugins/kxm/dist/server.js +13640 -0
  103. package/plugins/kxm/dist/vnext-runtime-supervisor.js +21109 -0
  104. package/plugins/kxm/package.json +12 -0
  105. package/plugins/kxm/skills/kxm/SKILL.md +97 -0
  106. package/plugins/kxm/skills/kxm/references/protocol.md +103 -0
  107. package/plugins/kxm/skills/kxm-session/SKILL.md +53 -0
  108. package/plugins/kxm/src/arbiter.ts +355 -0
  109. package/plugins/kxm/src/artifacts-exist.ts +62 -0
  110. package/plugins/kxm/src/autocomplete.ts +236 -0
  111. package/plugins/kxm/src/cli.ts +3707 -0
  112. package/plugins/kxm/src/client.ts +614 -0
  113. package/plugins/kxm/src/commands.ts +1063 -0
  114. package/plugins/kxm/src/config.ts +290 -0
  115. package/plugins/kxm/src/context/providers.ts +101 -0
  116. package/plugins/kxm/src/context-packet.ts +332 -0
  117. package/plugins/kxm/src/context.ts +499 -0
  118. package/plugins/kxm/src/core.ts +6 -0
  119. package/plugins/kxm/src/database.ts +563 -0
  120. package/plugins/kxm/src/diagnostics.ts +184 -0
  121. package/plugins/kxm/src/envelope.ts +118 -0
  122. package/plugins/kxm/src/extension.ts +895 -0
  123. package/plugins/kxm/src/external-effects.ts +299 -0
  124. package/plugins/kxm/src/github-watch.ts +255 -0
  125. package/plugins/kxm/src/hub-binding.ts +160 -0
  126. package/plugins/kxm/src/hub.ts +2502 -0
  127. package/plugins/kxm/src/improve.ts +383 -0
  128. package/plugins/kxm/src/inbox.ts +10 -0
  129. package/plugins/kxm/src/kxm-install-kind.ts +113 -0
  130. package/plugins/kxm/src/kxm-update-config.ts +39 -0
  131. package/plugins/kxm/src/kxm-update.ts +238 -0
  132. package/plugins/kxm/src/local-snapshot.ts +406 -0
  133. package/plugins/kxm/src/logger.ts +198 -0
  134. package/plugins/kxm/src/mcp-server.ts +143 -0
  135. package/plugins/kxm/src/memory.ts +385 -0
  136. package/plugins/kxm/src/nous-pi.ts +287 -0
  137. package/plugins/kxm/src/nous-provider.ts +729 -0
  138. package/plugins/kxm/src/price-calc.ts +87 -0
  139. package/plugins/kxm/src/prices.ts +121 -0
  140. package/plugins/kxm/src/protocol.ts +172 -0
  141. package/plugins/kxm/src/recovery.ts +211 -0
  142. package/plugins/kxm/src/redact.ts +26 -0
  143. package/plugins/kxm/src/retrospective.ts +400 -0
  144. package/plugins/kxm/src/routing.ts +830 -0
  145. package/plugins/kxm/src/runtime.ts +9 -0
  146. package/plugins/kxm/src/server.ts +117 -0
  147. package/plugins/kxm/src/session-work.ts +571 -0
  148. package/plugins/kxm/src/session.ts +184 -0
  149. package/plugins/kxm/src/skills.ts +535 -0
  150. package/plugins/kxm/src/state.ts +326 -0
  151. package/plugins/kxm/src/store.ts +637 -0
  152. package/plugins/kxm/src/studio-layout.ts +268 -0
  153. package/plugins/kxm/src/suggest.ts +162 -0
  154. package/plugins/kxm/src/task-manager.ts +244 -0
  155. package/plugins/kxm/src/telemetry.ts +116 -0
  156. package/plugins/kxm/src/tui.ts +1046 -0
  157. package/plugins/kxm/src/vnext-bindings.ts +403 -0
  158. package/plugins/kxm/src/vnext-config.ts +1646 -0
  159. package/plugins/kxm/src/vnext-engine-artifacts.ts +86 -0
  160. package/plugins/kxm/src/vnext-engine-command.ts +533 -0
  161. package/plugins/kxm/src/vnext-engine-compile.ts +722 -0
  162. package/plugins/kxm/src/vnext-engine-evidence.ts +273 -0
  163. package/plugins/kxm/src/vnext-engine-fold.ts +1400 -0
  164. package/plugins/kxm/src/vnext-engine-gate-records.ts +583 -0
  165. package/plugins/kxm/src/vnext-engine-plan.ts +717 -0
  166. package/plugins/kxm/src/vnext-engine.ts +2458 -0
  167. package/plugins/kxm/src/vnext-gate-hash.ts +10 -0
  168. package/plugins/kxm/src/vnext-harness.ts +1142 -0
  169. package/plugins/kxm/src/vnext-init.ts +430 -0
  170. package/plugins/kxm/src/vnext-migrate.ts +1848 -0
  171. package/plugins/kxm/src/vnext-oneshot-producer.ts +424 -0
  172. package/plugins/kxm/src/vnext-permission.ts +936 -0
  173. package/plugins/kxm/src/vnext-pi-producer.ts +628 -0
  174. package/plugins/kxm/src/vnext-repair.ts +1094 -0
  175. package/plugins/kxm/src/vnext-runtime-owner.ts +320 -0
  176. package/plugins/kxm/src/vnext-runtime-store.ts +1560 -0
  177. package/plugins/kxm/src/vnext-runtime-supervisor.ts +586 -0
  178. package/plugins/kxm/src/vnext-runtime.ts +663 -0
  179. package/plugins/kxm/src/vnext-template.ts +247 -0
  180. package/plugins/kxm/src/wiki.ts +313 -0
  181. package/plugins/kxm/src/workflow.ts +1548 -0
  182. package/schemas/vnext/README.md +46 -0
  183. package/schemas/vnext/agent.schema.json +40 -0
  184. package/schemas/vnext/assignment-result.schema.json +66 -0
  185. package/schemas/vnext/backup-manifest.schema.json +89 -0
  186. package/schemas/vnext/candidate.schema.json +109 -0
  187. package/schemas/vnext/common.schema.json +422 -0
  188. package/schemas/vnext/context-candidate.schema.json +76 -0
  189. package/schemas/vnext/context-packet.schema.json +192 -0
  190. package/schemas/vnext/delivery-manifest.schema.json +159 -0
  191. package/schemas/vnext/environment.schema.json +66 -0
  192. package/schemas/vnext/gate-registry.schema.json +109 -0
  193. package/schemas/vnext/handoff-manifest.schema.json +146 -0
  194. package/schemas/vnext/init-operation.schema.json +61 -0
  195. package/schemas/vnext/local-repository-bindings.schema.json +30 -0
  196. package/schemas/vnext/memory-record.schema.json +45 -0
  197. package/schemas/vnext/migration-decision.schema.json +26 -0
  198. package/schemas/vnext/migration-plan.schema.json +123 -0
  199. package/schemas/vnext/migration-receipt.schema.json +52 -0
  200. package/schemas/vnext/model.schema.json +42 -0
  201. package/schemas/vnext/permission-diff.schema.json +57 -0
  202. package/schemas/vnext/prices.schema.json +115 -0
  203. package/schemas/vnext/project.schema.json +85 -0
  204. package/schemas/vnext/repository.schema.json +24 -0
  205. package/schemas/vnext/run-event.schema.json +460 -0
  206. package/schemas/vnext/session-brief.schema.json +153 -0
  207. package/schemas/vnext/sync-event.schema.json +234 -0
  208. package/schemas/vnext/template-provenance.schema.json +38 -0
  209. package/schemas/vnext/workflow.schema.json +248 -0
  210. package/scripts/assignment-run.d.mts +354 -0
  211. package/scripts/assignment-run.mjs +4451 -0
  212. package/scripts/build-runtime.mjs +56 -0
  213. package/scripts/check-generated.mjs +77 -0
  214. package/scripts/check-versions.mjs +34 -0
  215. package/scripts/emit-codex-artifacts.d.mts +9 -0
  216. package/scripts/emit-codex-artifacts.mjs +91 -0
  217. package/scripts/harness-run.d.mts +83 -0
  218. package/scripts/harness-run.mjs +2095 -0
  219. package/scripts/kxm-hub.mjs +105 -0
  220. package/scripts/kxm-publish-npm.mjs +327 -0
  221. package/scripts/kxm-release-github.mjs +472 -0
  222. package/scripts/kxm-runtime-supervisor.mjs +7 -0
  223. package/scripts/kxm-worker.mjs +1127 -0
  224. package/scripts/kxm.mjs +27 -0
  225. package/scripts/roster-policy.d.mts +20 -0
  226. package/scripts/roster-policy.mjs +161 -0
  227. package/scripts/smoke-multi-pi.mjs +479 -0
@@ -0,0 +1,335 @@
1
+ # Configuration and contract validation
2
+
3
+ KXM uses deterministic validation for configuration, commands, events, and
4
+ results. A model may explain an error but MUST NOT decide whether invalid input
5
+ is accepted.
6
+
7
+ ## YAML parser profile
8
+
9
+ YAML is parsed as a data format compatible with JSON Schema.
10
+
11
+ Required parser restrictions:
12
+
13
+ - one document per file;
14
+ - custom tags disabled;
15
+ - duplicate mapping keys rejected;
16
+ - aliases disabled by default or bounded to a small implementation constant;
17
+ - bounded document bytes, nesting depth, scalar length, collection length, and key count;
18
+ - strings preserved as strings where the schema requires them;
19
+ - no object construction or executable types.
20
+
21
+ The `schema` field is required. For agent, model, and workflow files, identity is
22
+ the normalized filename without `.yaml`; an in-document identity field is
23
+ forbidden.
24
+
25
+ ## Validation pipeline
26
+
27
+ ### 1. Parse validation
28
+
29
+ Reject malformed YAML, duplicate keys, forbidden tags, alias expansion, invalid
30
+ UTF-8, and resource-limit violations.
31
+
32
+ ### 2. JSON Schema validation
33
+
34
+ Validate against the exact schema identity under `schemas/vnext`. Unknown fields
35
+ are rejected unless a schema explicitly defines an extension map.
36
+
37
+ ### 3. Path and identity validation
38
+
39
+ - normalize to forward-slash repository-relative paths;
40
+ - reject backslashes, traversal, absolute host paths, Windows device names,
41
+ destination-invalid characters, empty segments, and trailing dots/spaces in
42
+ portable configuration;
43
+ - reject case-folding identity collisions;
44
+ - reject Windows reserved names and destination-incompatible paths;
45
+ - require path-derived IDs to match the canonical identifier grammar;
46
+ - stop project discovery at the nearest Git worktree boundary and require the
47
+ authoritative project root to equal that boundary;
48
+ - require every `required` repository binding to resolve an exact matching
49
+ `repo.yaml` at that repository's authoritative Git worktree root;
50
+ - reject portable `pathHint` values whose existing components traverse a
51
+ symlink/junction or whose real path escapes the control project root;
52
+ - treat out-of-tree member bindings as absolute Runtime-local input, never
53
+ portable YAML, while the control binding is always the project root;
54
+ - persist explicit member bindings only after complete bundle validation in an
55
+ exact, bounded host record keyed by the canonical control-root path; reject
56
+ corrupt, linked, unknown, control-rebinding, or project-mismatched records.
57
+
58
+ #### Managed-template reconciliation
59
+
60
+ A project created by the built-in initializer records an exact, bounded
61
+ `kxm.template-provenance.v1` manifest. SHA-256 covers the UTF-8/LF file bytes;
62
+ comments and formatting therefore count as user edits. The separate authority
63
+ hash excludes only names/descriptions/purpose prose and conservatively includes
64
+ repository access, tools, network, secrets, executors, gates, assignment
65
+ ceilings, synchronization, and other executable policy.
66
+
67
+ For every managed path, three-way classification compares recorded baseline
68
+ `B`, current local bytes `L`, and pinned target bytes `T`, with absence as a
69
+ first-class value:
70
+
71
+ | Condition | Class | Automatic action |
72
+ |---|---|---|
73
+ | `B = L = T` | `unchanged` | None |
74
+ | `L = T`, while `B` differs | `converged` | None |
75
+ | `L = B`, while `T` differs | `template-only` | Replace only when the authority hash is unchanged |
76
+ | `T = B`, while `L` differs | `user-only` | Preserve exact local bytes |
77
+ | Otherwise | `conflict` | Preserve and report |
78
+
79
+ A new managed path or deletion requires review in this slice. Provenance-free
80
+ projects remain valid when their resources are valid, but KXM MUST NOT infer a
81
+ baseline or adopt their files automatically.
82
+
83
+ Before repair changes any project file, it constructs and validates a bounded
84
+ shadow bundle containing user-only bytes plus the proposed safe replacements.
85
+ The fixed sibling transaction then pins an exact plan and target artifacts; it
86
+ backs up every replacement preimage, checks each preimage again immediately
87
+ before atomic file replacement, and installs provenance last. It carries no
88
+ repository-binding authority: an explicit binding is validated and made durable
89
+ in Runtime-local state before repair mutates Git resources. The reader
90
+ re-derives every operation file, action, source, and target from the immutable
91
+ supported-template registry, rather than trusting a self-hash. Recovery derives
92
+ truth from destination hashes rather than trusting the recorded phase. A target
93
+ already present is complete, a matching preimage is pending, and any third
94
+ value blocks without overwrite. Repair moves a verified preimage aside and uses
95
+ a same-directory hard link as a conditional no-replace install; a path recreated
96
+ by a non-KXM writer is preserved and blocks repair. A filesystem without local
97
+ hard-link support fails safely. Create keeps its same-volume directory rename.
98
+ A newer process must finish the pinned transaction before planning another
99
+ template revision.
100
+
101
+ #### Legacy configuration migration
102
+
103
+ `kxm migrate plan|apply|verify` converts legacy `.kxm/config` JSON into
104
+ validated vNext resources with an exact receipt:
105
+
106
+ - Legacy files are read with byte/depth/node bounds and token-level
107
+ duplicate-key rejection. Symbolic links and linked `workflows/` directories
108
+ are never traversed for authoritative bytes.
109
+ - The deterministic `kxm.migration-plan.v1` binds every source file by
110
+ sha256/bytes plus a combined `sourceDigest`, lists target resources with
111
+ rendered content hashes, and enumerates every ambiguity as a stable decision
112
+ key with its allowed values: terminal status for each legacy `$terminal`
113
+ edge (legacy semantics completed the run even on failure outcomes), per-edge
114
+ budgets for unbounded back-edges, missing global transition budgets,
115
+ evidence-policy strengthening from `replied` to `passed`, foreign producer
116
+ identities, secret-field drops, unimplemented gates, and each narrowed
117
+ permission ceiling. Unrecognized or unmappable fields are preserved as
118
+ hashed `unmapped` entries; sensitive values are hashed, never copied.
119
+ Identity normalization that changes a name is an explicit `renames` entry
120
+ applied to all bound references; case-fold collisions fail closed.
121
+ - Apply requires a reviewed `kxm.migration-decision.v1` (or programmatic
122
+ resolutions) binding the exact plan: project ID, project name, and source
123
+ digest. Unknown keys and values outside the allowed set fail closed before
124
+ any write. The complete target bundle must pass exact-schema and semantic
125
+ validation before installation; existing target paths are never overwritten.
126
+ - Installation uses durable writes under the project mutation lock and finishes
127
+ with a self-hashed `kxm.migration-receipt.v1` binding source hashes, decision
128
+ digest, target configuration revision, and installed resource hashes. The
129
+ receipt keeps the legacy inputs read-only: `loadVnextProject` accepts mixed
130
+ trees only through a verified receipt, and any later legacy-source edit makes
131
+ loading and `migrate verify` fail closed. Re-apply is an idempotent no-op.
132
+ - `plan`, `verify`, and every `--dry-run` path perform no writes, locks,
133
+ staging, backups, or Runtime-local state creation.
134
+
135
+ `--dry-run` may parse and classify a transaction but MUST NOT create the writer
136
+ mutex, state directories, staging, backups, temporary files, or cleanup. Live
137
+ mutations use a SQLite immediate transaction so process death releases the
138
+ writer lock; the durable initialization operation, not a PID/age heuristic,
139
+ drives recovery.
140
+
141
+ ### 4. Cross-reference validation
142
+
143
+ Resolve:
144
+
145
+ - workflow agents;
146
+ - model profiles and tags;
147
+ - repository IDs;
148
+ - gates and executors;
149
+ - secret reference names;
150
+ - transition targets;
151
+ - evidence keys;
152
+ - environment scopes.
153
+
154
+ References resolve within the pinned configuration bundle, never from mutable
155
+ process state. A step model selector is intersected with each eligible agent's
156
+ model ceiling; the raw step selector never replaces that ceiling, and an empty
157
+ intersection is invalid. Step tool policy must preserve the agent preset and
158
+ all agent denials, and may only narrow an explicit allowlist. Portable `values`
159
+ reject secret-bearing variable names and any value matching a registered secret
160
+ or deterministic credential classifier; those values must use
161
+ `secrets[].ref`.
162
+
163
+ ### 5. Workflow semantic validation
164
+
165
+ Reject:
166
+
167
+ - undeclared or nonexistent transition targets;
168
+ - an unbounded cycle or missing effective step/assignment attempt ceiling;
169
+ - a back-edge without global and per-edge bounds;
170
+ - a transition capable of bypassing a required approval/gate;
171
+ - impossible assignment minima, targets, maxima, or join rules;
172
+ - impossible MOA diversity;
173
+ - producer minima beyond the eligible assignment pool or evidence policy;
174
+ - an oracle/plan-hash stage or evidence key that does not exist;
175
+ - a mutation/delivery stage missing from `requirePlanHash` during migration of
176
+ an equivalent protected workflow;
177
+ - `first-success` on a step that is not declared safe for speculation;
178
+ - a coordinator, agent, model, or repository request exceeding a step ceiling;
179
+ - terminal transitions without an explicit terminal run status.
180
+
181
+ ### 6. Capability validation
182
+
183
+ Before a run starts, resolve and pin:
184
+
185
+ - exact harness and executor versions;
186
+ - exact model selections;
187
+ - required provider authentication readiness;
188
+ - tool preset versions;
189
+ - repository bindings;
190
+ - required LFS objects;
191
+ - secret reference availability without reading values into configuration.
192
+
193
+ A configured fallback is pinned only if selected before the first dispatch for
194
+ that assignment. A failed live model session is not silently continued on a
195
+ different model.
196
+
197
+ ### 7. Permission-diff validation
198
+
199
+ Compare the new resolved bundle with the trusted revision. Flag increases in:
200
+
201
+ - repository write scope;
202
+ - tool or shell capability;
203
+ - secret grants;
204
+ - executor/network scope;
205
+ - synchronization content;
206
+ - shared external effects;
207
+ - model-created assignment ceilings;
208
+ - automatic delivery behavior.
209
+
210
+ Permission expansion requires an explicit reviewed trust action. Formatting or
211
+ description-only changes do not.
212
+
213
+ #### Structured projections and the `kxm trust` gate
214
+
215
+ The implemented workflow projects every resource into deterministic,
216
+ field-addressed authority entries (`vnextAuthorityEntries`) covering the
217
+ categories above, then diffs two complete bundles into a
218
+ `kxm.permission-diff.v1` report. Every change is classified conservatively:
219
+
220
+ - ordered lattices: repository access (`none` < `read` < `write`), network
221
+ (`none` < `provider-only` < `restricted` < `host`), snapshot untracked
222
+ content (`tracked-only` < `ask` < `bounded`);
223
+ - budgets: raising any numeric limit expands; lowering narrows; mixed
224
+ directions expand;
225
+ - evidence quorums: lowering `minimumProducers`, removing an eligible
226
+ producer, or introducing/lowering a degradation floor expands; raising the
227
+ quorum narrows; adding a producer without touching the floor is neutral;
228
+ - secret grants: a new grant expands; removal narrows; making a grant
229
+ optional narrows, requiring one expands; any other grant change expands;
230
+ - transitions, tools, executors, models, sync policy, gates, delivery, and
231
+ resource shape have no conservative order: any change expands and requires
232
+ review;
233
+ - resource additions expand; removals narrow; prose-only changes
234
+ (name/description/purpose/instructions) surface as neutral and never
235
+ require review.
236
+
237
+ `kxm trust diff [--base <rev>]` prints the report; `kxm trust check`
238
+ (--base defaults to `HEAD`) exits non-zero when any expansion exists, so an
239
+ authority-bearing change cannot merge without a reviewed Git change. Base
240
+ revisions are pinned to their tree SHA once, materialized from Git into a
241
+ temporary shadow with a sanitized environment (every member repository is
242
+ resolved at the same revision in its own history; a member that does not
243
+ resolve it fails closed with `trust_scope_unsupported`), and every Git tree
244
+ entry is segment-validated and containment-checked before any write. Template
245
+ repair blocks authority-bearing template updates and now enriches the
246
+ `template_policy_review_required` issue with the exact field-level diff.
247
+
248
+ ### 8. Snapshot validation
249
+
250
+ For every run:
251
+
252
+ 1. resolve the validated configuration bundle;
253
+ 2. compute `configRevision`;
254
+ 3. record each repository base commit;
255
+ 4. build the normalized dirty-content manifest;
256
+ 5. compute `contentSnapshotHash`;
257
+ 6. materialize the worktree;
258
+ 7. recompute and compare hashes before dispatch.
259
+
260
+ A mismatch fails before agent execution.
261
+
262
+ ## Atomic editor save
263
+
264
+ The CLI, standard TUI, and Pi editor use the same service:
265
+
266
+ ```text
267
+ edit temporary file
268
+ → parse and validate resource
269
+ → validate complete project
270
+ → compute permission diff
271
+ → show resolved preview and Git diff
272
+ → atomically replace original
273
+ ```
274
+
275
+ An invalid edit never replaces the original. Existing runs retain their pinned
276
+ revision.
277
+
278
+ ## Schema evolution
279
+
280
+ - Every document names an exact schema.
281
+ - Readers reject schemas newer than their supported range.
282
+ - Additive fields require explicit schema support; `additionalProperties` is
283
+ false by default.
284
+ - Semantic changes require a new schema identity and migration.
285
+ - Events are immutable; a correction appends a compensating event.
286
+ - Projections record their schema and rebuild version.
287
+
288
+ ## Machine-verifiable fixture
289
+
290
+ [`test/core/contracts-vnext.test.ts`](../../test/core/contracts-vnext.test.ts) parses the
291
+ committed YAML example with the restricted parser profile and validates each
292
+ resource plus representative event/result/delivery/candidate records against
293
+ the committed JSON Schemas.
294
+
295
+ ## Gate registry foundation
296
+
297
+ Projects with gate steps must declare `.kxm/gates.yaml`:
298
+
299
+ ```yaml
300
+ schema: kxm.gate-registry.v1
301
+ gates:
302
+ test:
303
+ kind: command
304
+ argv: [npm, test]
305
+ timeoutMs: 3600000
306
+ report:
307
+ kind: artifacts-exist
308
+ paths: [reviews/result.json]
309
+ ```
310
+
311
+ Command definitions require literal `argv` (1–64 nonempty strings, each at
312
+ most 4096 characters) and integer `timeoutMs` from 1 to 2147483647. The first
313
+ argument must be a bare executable name or an absolute POSIX path; relative
314
+ paths such as `./test.sh` and directory names `.` and `..` refuse. Optional
315
+ `cwd` can only be `control`.
316
+ `env`, `shell`, and undeclared fields refuse. Artifact paths use the shared
317
+ portable relative-path grammar beneath `.kxm/assets`; `.` and traversal refuse.
318
+ Artifact definitions have no timeout. `kind: reserved` registers an id without
319
+ claiming executable support. Registries contain 1–64 named definitions.
320
+
321
+ Workflow gate steps accept `expect: pass` (default) or `expect: fail`.
322
+ Non-gate `expect` is invalid. Use `implementation-failure` and `repro-missing`
323
+ for gate outcomes; their old underscore spellings are rejected. The former
324
+ `registeredGates` caller option and `kxm.gates.v1` identity are also rejected.
325
+ A project without gate steps may omit the registry.
326
+
327
+ These are configuration and compilation contracts. Gate execution, artifact
328
+ containment checks, timeout settlement, and attempt-bound evidence remain D3
329
+ follow-up work; a valid definition does not mean the engine can execute it.
330
+ Registry changes alter the full configuration/tool-policy hashes. Permission
331
+ review treats only numeric timeout decreases as narrowing; other definition
332
+ changes and removal of a gate or registry require review. Explicit default
333
+ `expect: pass` is neutral. New projects use `v4-registry`; historical template
334
+ bytes and provenance remain unchanged. Existing projects must explicitly
335
+ review and add a registry before using gate workflows.
@@ -0,0 +1,240 @@
1
+ # Webhook workflows and long-lived agents
2
+
3
+ KXM can turn a signed Jira, GitHub, or generic webhook into a durable prompt for a long-lived coordinator. The hub verifies the original request body, deduplicates provider retries, records the workflow before acknowledging it, and queues the prompt even when a previously registered coordinator is temporarily offline.
4
+
5
+ ## How the runtime behaves
6
+
7
+ ```text
8
+ Jira webhook ── HMAC + delivery ID ──> Hub ── durable workflow + message
9
+ │
10
+ └── Pi coordinator
11
+ ├── peer planning/review
12
+ ├── checkpoints and retries
13
+ ├── evidence journal
14
+ ├── external wait ── signed result ──┐
15
+ └── final result <── resumed prompt ─┘
16
+ ```
17
+
18
+ The coordinator must register at least once before a webhook can target it. An unknown target returns HTTP 409, which causes Jira Cloud to retry. A known but offline target retains the queued workflow until it reconnects.
19
+
20
+ The hub stores a SHA-256 payload hash and the rendered coordinator prompt, not the complete raw webhook body. Keep prompt templates narrow so they copy only the issue fields the agent needs.
21
+
22
+ ## Configure the Jira example
23
+
24
+ The included [`jira-development.json`](../.kxm/config/workflows/jira-development.json) workspace configuration models this path:
25
+
26
+ 1. Jira issue enters **In Progress**.
27
+ 2. Reproduce the defect and create deterministic evidence.
28
+ 3. Plan with one agent or three independent strong planners, then synthesize their best ideas.
29
+ 4. Review and revise the plan.
30
+ 5. Implement with explicit ownership.
31
+ 6. Run lint, build/typecheck, security, and Playwright gates.
32
+ 7. Reproduce repository and CodeRabbit-style review gates.
33
+ 8. Update documentation.
34
+ 9. Push and watch required checks with `kxm gate github watch`; warnings and failures retry the same stage for correction until its attempt limit is exhausted.
35
+ 10. Merge only when policy and authorization allow it.
36
+ 11. Update Jira with links and evidence.
37
+ 12. Produce an evidence-backed improvement backlog.
38
+
39
+ Load it without storing its secret in the JSON file:
40
+
41
+ ```powershell
42
+ $env:JIRA_WEBHOOK_SECRET = "replace-with-a-high-entropy-secret"
43
+ $env:WORKFLOW_SIGNAL_SECRET = "replace-with-a-separate-callback-secret"
44
+ $env:KXM_WEBHOOK_WORKFLOWS_FILE = ".kxm/config/workflows/jira-development.json"
45
+ kxm hub start
46
+ ```
47
+
48
+ Configure Jira to send `jira:issue_updated` to:
49
+
50
+ ```text
51
+ https://your-kxm-host.example/v1/webhooks/jira-development
52
+ ```
53
+
54
+ Set the same secret when creating the Jira webhook. The endpoint requires `X-Hub-Signature` using SHA-256 and `X-Atlassian-Webhook-Identifier`. The stable delivery identifier makes Jira retries idempotent. Terminate TLS and restrict ingress before exposing the endpoint beyond a trusted network.
55
+
56
+ Webhook authentication authorizes only workflow creation. The Jira-update stage requires a separate authorized Jira tool, MCP server, CLI, or automation callback in the coordinator's harness. Do not place Jira API credentials in the workflow definition or prompt.
57
+
58
+ ## Run a long-lived Pi coordinator
59
+
60
+ Install the Pi package, then configure a stable identity that matches the workflow target:
61
+
62
+ ```powershell
63
+ $env:KXM_SERVER_URL = "http://127.0.0.1:7331"
64
+ $env:KXM_AUTH_TOKEN = "product-project-token"
65
+ $env:KXM_PROJECT = "product"
66
+ $env:KXM_AGENT_NAME = "coordinator"
67
+ $env:KXM_AGENT_PURPOSE = "Coordinates Jira development workflows and quality gates"
68
+ $env:KXM_WORKDIR = "D:\work\product-repository"
69
+ kxm agent worker --session-isolation workflow
70
+ ```
71
+
72
+ Workflow isolation is explicit during the upgrade-compatible release and begins fresh scoped storage on first use. The worker launches Pi in headless RPC mode, keeps stdin open, preserves its active bound session by default, and restarts with bounded exponential backoff. Run the worker itself under the operating system's service manager for boot startup, resource limits, log collection, and crash policy. Set `KXM_WORKER_CONTINUE=false` only when every process restart should create a fresh Pi session.
73
+
74
+ ## Workflow definition fields
75
+
76
+ | Field | Meaning |
77
+ |---|---|
78
+ | `id` | URL-safe workflow identifier |
79
+ | `source` | `jira`, `github`, or `generic` |
80
+ | `project` | Hub project containing the coordinator |
81
+ | `target` | Stable coordinator name or durable agent ID |
82
+ | `secretEnv` | Environment variable containing the HMAC secret |
83
+ | `signalSecretEnv` | Optional separate HMAC secret for external result callbacks |
84
+ | `event` | Optional provider event filter |
85
+ | `filter.path` / `filter.equals` | Optional exact JSON-path value filter |
86
+ | `delivery` | `followUp` or `steer` |
87
+ | `ttlMs` | Time allowed for the coordinator prompt |
88
+ | `promptTemplate` | Prompt with `{{nested.payload.path}}` substitutions |
89
+ | `stages` | Ordered gates with instructions, evidence requirements, and attempt limits |
90
+ | `stages[].evidencePolicies` | Optional per-requirement peer provenance and quorum rules |
91
+
92
+ Each stage may set `area` to route automatic warnings and failures into `harness`, `gates`, `implementation`, `workflow`, `documentation`, `security`, or `other`. It defaults to `workflow`.
93
+
94
+ An `evidencePolicies` key must match one canonical `requiredEvidence` identity.
95
+ A `peer-reply` policy declares a `minProducers`, one or more
96
+ `eligibleAgents`, and `acceptedStatuses: ["replied"]`. Eligible names or IDs
97
+ must already be known in the workflow project. The hub resolves them to stable
98
+ producer IDs when the run starts and fails closed if the coordinator is
99
+ included or the unique resolved set cannot satisfy the configured minimum.
100
+ See [Peer provenance and quorum gates](provenance-gates.md) for the complete
101
+ schema and command-first example.
102
+
103
+ Use `KXM_WEBHOOK_WORKFLOWS` for inline JSON or `KXM_WEBHOOK_WORKFLOWS_FILE` for a file, never both. Prefer `secretEnv` over a literal `secret`.
104
+
105
+ ## Pause for CI, review, merge, or Jira
106
+
107
+ A coordinator should not hold an agent turn open while an external system runs for minutes or hours. On the active stage, call `kxm_workflow_wait` with:
108
+
109
+ - the run and active stage IDs;
110
+ - a stable `signalKey`, such as `github-pr-42-checks`;
111
+ - a concise description of the expected result;
112
+ - optional local evidence keyed by its declared requirement identity;
113
+ - an optional timeout from one second through 30 days; the default is 24 hours.
114
+
115
+ The hub changes the run and stage to `waiting`. The coordinator may then settle its current prompt without triggering the premature-settlement failure. If the deadline passes first, the run fails and records a harness error.
116
+
117
+ The external system reports its result to:
118
+
119
+ ```text
120
+ POST /v1/webhooks/:definitionId/runs/:runId/signals/:signalKey
121
+ ```
122
+
123
+ The JSON body is:
124
+
125
+ ```json
126
+ {
127
+ "status": "passed",
128
+ "summary": "All required GitHub checks passed",
129
+ "evidence": {
130
+ "github.check:ci": "conclusion:success url:https://github.example/org/repo/actions/runs/123"
131
+ }
132
+ }
133
+ ```
134
+
135
+ Sign the exact body bytes with SHA-256 HMAC. Supply the signature in `X-Hub-Signature-256` and a stable retry identifier in `X-GitHub-Delivery`, `X-Atlassian-Webhook-Identifier`, or `X-Mesh-Delivery-ID`. Repeating the same delivery ID and body returns minimal receipt metadata instead of checkpointing twice. Reusing a delivery ID for a different signal or body returns HTTP 409.
136
+
137
+ Use `signalSecretEnv` so CI and merge reporters do not need the secret that creates new workflows. If it is omitted, callbacks fall back to `secretEnv` for compatibility. A valid callback can checkpoint only the named run's current wait and must match its signal key.
138
+
139
+ Context evidence is optional. When a callback supplies `workflow.run`,
140
+ `workflow.stage`, or `workflow.signal`, each value must exactly match the route
141
+ run, active waiting stage, or route signal key respectively. A mismatch returns
142
+ HTTP 409 without advancing the run or recording a delivery receipt. Adapters
143
+ that do not need these diagnostic keys may omit them.
144
+
145
+ `passed` applies the normal evidence rule and advances or completes the run. `warning` or `failed` consumes an attempt, records an error, and queues a correction prompt when attempts remain. The run, signal receipt, optional journal entry, and optional resume message commit in one SQLite transaction before delivery. A terminal result does not create another prompt. Only the validated summary and evidence are retained; the complete callback body is not stored.
146
+
147
+ Callback responses deliberately expose only status, stage, retry, completion, resumption, and duplicate metadata. They never return the workflow record, coordinator prompt, message routing, journal, or evidence. Those remain behind project and agent authentication.
148
+
149
+ The repository includes a small callback sender for smoke tests and automation adapters:
150
+
151
+ ```powershell
152
+ $env:KXM_SERVER_URL = "https://your-hub-host.example"
153
+ $env:KXM_WORKFLOW_ID = "jira-development"
154
+ $env:KXM_WORKFLOW_SIGNAL_SECRET = "replace-with-the-callback-secret"
155
+ $env:KXM_SIGNAL_DELIVERY_ID = "github-check-run-123-attempt-1"
156
+ node --experimental-strip-types examples/workflow-signal.ts `
157
+ run_123 github-pr-42-checks passed "All required checks passed" `
158
+ "github.check:ci=https://github.example/org/repo/actions/runs/123"
159
+ ```
160
+
161
+ `examples/workflow-signal.ts` reads `KXM_SIGNAL_DELIVERY_ID` and sends it as
162
+ `x-kxm-delivery-id`. The CLI equivalent is `kxm gate signal --delivery-id`.
163
+
164
+ In a real integration, store the `runId` and `signalKey` in Jira, pull-request metadata, or the external job's inputs when the coordinator starts the wait. Treat them as routing identifiers rather than secrets.
165
+
166
+ To watch GitHub checks and post that same signal, use the command-first adapter:
167
+
168
+ ```powershell
169
+ $env:KXM_WORKFLOW_ID = "jira-development"
170
+ $env:KXM_WORKFLOW_SIGNAL_SECRET = "replace-with-the-callback-secret"
171
+ $env:GITHUB_TOKEN = "replace-with-a-checks-read-token"
172
+ kxm gate github watch --run-id run_123 --stage-id watch --signal-key github-pr-42-checks --repo org/repo --pr 42 --required ci --timeout-ms 3600000
173
+ ```
174
+
175
+ The watcher binds every result to the exact run, stage, and signal key, requests
176
+ up to 100 check runs per GitHub page, and follows every reported page. Each
177
+ check is reported as `github.check:<check-name>`; diagnostic context such as
178
+ `workflow.run` never satisfies an unrelated requirement. GitHub
179
+ `startup_failure` is a failed result. On timeout the watcher posts a signed
180
+ `failed` signal with summary `github_watch_timeout`, then exits `4`; it never
181
+ invents a `passed` result.
182
+
183
+ Each watcher invocation creates a new bounded delivery generation and includes
184
+ the pull-request head SHA when GitHub returned one. Transport retries within
185
+ that invocation reuse the exact `x-kxm-delivery-id`. After a failed or timed
186
+ out result, start a new watcher for the new workflow wait; do not reuse the old
187
+ generated ID. Supply `--delivery-id` only when an external supervisor must
188
+ retry the same callback attempt with a stable provider identifier. The standalone
189
+ `kxm gate signal` command follows the same rule.
190
+
191
+ ## Checkpoint contract
192
+
193
+ Only the assigned coordinator can read, journal, checkpoint, or wait a run. A
194
+ passing checkpoint must provide a non-empty value for every exact
195
+ `requiredEvidence` identity. Evidence is a JSON object rather than a list, so
196
+ extra GitHub checks or generic context cannot replace an unrelated review,
197
+ artifact, or retrospective requirement. Identities are normalized by trimming,
198
+ collapsing repeated whitespace, and case-folding; normalized aliases in one
199
+ submission are rejected as duplicates.
200
+
201
+ When a requirement has a peer policy, caller-authored evidence text cannot
202
+ satisfy it. The coordinator must create peer messages with an authorized,
203
+ immutable `workflowContext` for the exact run, active stage, canonical
204
+ requirement, and current 1-based attempt. A passing checkpoint or wait cites the
205
+ resulting durable message IDs in `evidenceRefs`. The hub verifies project,
206
+ direction, eligible target, context, correlation, non-empty replied status,
207
+ and coherent timestamps, then counts unique producer IDs. Old, pending,
208
+ duplicate-producer, coordinator-authored, or cross-context messages do not
209
+ count.
210
+
211
+ Evidence supplied when entering `waiting` is accumulated with a later passing
212
+ callback. `warning` and `failed` evidence is retained in the journal for
213
+ diagnosis but intentionally does not satisfy a later passing attempt. Those
214
+ results remain on the active stage and return a correction instruction.
215
+ Reaching `maxAttempts` fails the run. Settling the coordinator prompt before all
216
+ stages pass also fails the run and records a workflow error unless the
217
+ coordinator deliberately placed the active stage in `waiting` first.
218
+
219
+ If a policy declares `degradation.minProducers`, an operator may use
220
+ `kxm gate degrade` with the administrative token to approve that exact
221
+ lower minimum for only the current stage attempt. The coordinator, peer agents,
222
+ and callback secret cannot authorize degradation. Approval alone never passes
223
+ the stage; the coordinator must still provide the required verified references.
224
+ The reason, policy minimum, approved minimum, attempt, and any eventual degraded
225
+ pass are retained for audit.
226
+
227
+ The hub enforces stage order and requirement identity; agents remain responsible
228
+ for the truth of submitted evidence. Repository rules, human approvals, and
229
+ harness permissions remain authoritative for push, merge, Jira mutation, and
230
+ other external effects.
231
+
232
+ Peer quorum proves provenance inside the hub project credential boundary. It
233
+ does not prove answer quality, truth, distinct underlying models, independent
234
+ inference, non-collusion, or human approval.
235
+
236
+ ## Platform references
237
+
238
+ - [Pi extension lifecycle and message injection](https://pi.dev/docs/latest/extensions)
239
+ - [Pi headless RPC mode](https://pi.dev/docs/latest/rpc)
240
+ - [Jira Cloud webhook signing and retry behavior](https://developer.atlassian.com/cloud/jira/software/webhooks/)