nawabari 0.7.1 → 0.9.2

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 (90) hide show
  1. package/README.md +264 -29
  2. package/dist/cli-command-registry.d.ts +50 -0
  3. package/dist/cli-command-registry.js +509 -0
  4. package/dist/cli-command-registry.js.map +1 -0
  5. package/dist/cli.d.ts +18 -0
  6. package/dist/cli.js +302 -583
  7. package/dist/cli.js.map +1 -1
  8. package/dist/contract.d.ts +6 -0
  9. package/dist/contract.js +296 -192
  10. package/dist/contract.js.map +1 -1
  11. package/dist/domain/cgroups-v2.d.ts +77 -0
  12. package/dist/domain/cgroups-v2.js +434 -0
  13. package/dist/domain/cgroups-v2.js.map +1 -0
  14. package/dist/domain/doctor.d.ts +4 -1
  15. package/dist/domain/doctor.js +64 -13
  16. package/dist/domain/doctor.js.map +1 -1
  17. package/dist/domain/errors.d.ts +1 -1
  18. package/dist/domain/errors.js.map +1 -1
  19. package/dist/domain/landlock.d.ts +55 -0
  20. package/dist/domain/landlock.js +279 -0
  21. package/dist/domain/landlock.js.map +1 -0
  22. package/dist/domain/runtime.d.ts +12 -0
  23. package/dist/domain/runtime.js +50 -0
  24. package/dist/domain/runtime.js.map +1 -0
  25. package/dist/domain/sandbox-launcher.d.ts +26 -0
  26. package/dist/domain/sandbox-launcher.js +312 -23
  27. package/dist/domain/sandbox-launcher.js.map +1 -1
  28. package/dist/domain/sandbox-seccomp.d.ts +46 -0
  29. package/dist/domain/sandbox-seccomp.js +302 -0
  30. package/dist/domain/sandbox-seccomp.js.map +1 -0
  31. package/dist/domain/sandbox.d.ts +45 -1
  32. package/dist/domain/sandbox.js +176 -25
  33. package/dist/domain/sandbox.js.map +1 -1
  34. package/dist/domain/session-backend.d.ts +4 -1
  35. package/dist/domain/session-backend.js +256 -3
  36. package/dist/domain/session-backend.js.map +1 -1
  37. package/dist/domain/session.d.ts +207 -3
  38. package/dist/domain/session.js.map +1 -1
  39. package/dist/errors.d.ts +1 -1
  40. package/dist/failure-code-vocabulary.d.ts +20 -0
  41. package/dist/failure-code-vocabulary.js +216 -0
  42. package/dist/failure-code-vocabulary.js.map +1 -0
  43. package/dist/git.js +92 -6
  44. package/dist/git.js.map +1 -1
  45. package/dist/operation-authorization.d.ts +1 -1
  46. package/dist/product-state-manifest.d.ts +152 -0
  47. package/dist/product-state-manifest.js +240 -0
  48. package/dist/product-state-manifest.js.map +1 -0
  49. package/dist/public-contract.d.ts +25 -0
  50. package/dist/public-contract.js +29 -0
  51. package/dist/public-contract.js.map +1 -0
  52. package/dist/public-state.d.ts +75 -0
  53. package/dist/public-state.js +60 -0
  54. package/dist/public-state.js.map +1 -0
  55. package/dist/registry/lock.d.ts +8 -0
  56. package/dist/registry/lock.js +38 -20
  57. package/dist/registry/lock.js.map +1 -1
  58. package/dist/repository-evidence.d.ts +16 -0
  59. package/dist/repository-evidence.js.map +1 -1
  60. package/dist/resource-claims.d.ts +2 -2
  61. package/dist/resource-claims.js +96 -27
  62. package/dist/resource-claims.js.map +1 -1
  63. package/dist/session-lifecycle-actions.d.ts +64 -0
  64. package/dist/session-lifecycle-actions.js +117 -0
  65. package/dist/session-lifecycle-actions.js.map +1 -0
  66. package/dist/session-lifecycle-classification.d.ts +120 -0
  67. package/dist/session-lifecycle-classification.js +88 -0
  68. package/dist/session-lifecycle-classification.js.map +1 -0
  69. package/dist/session-registry.d.ts +210 -2
  70. package/dist/session-registry.js +1330 -87
  71. package/dist/session-registry.js.map +1 -1
  72. package/dist/state/index.d.ts +5 -0
  73. package/dist/state/index.js +4 -0
  74. package/dist/state/index.js.map +1 -0
  75. package/dist/state/session/actors.d.ts +71 -0
  76. package/dist/state/session/actors.js +259 -0
  77. package/dist/state/session/actors.js.map +1 -0
  78. package/dist/state/session/guards.d.ts +25 -0
  79. package/dist/state/session/guards.js +108 -0
  80. package/dist/state/session/guards.js.map +1 -0
  81. package/dist/state/session/index.d.ts +6 -0
  82. package/dist/state/session/index.js +5 -0
  83. package/dist/state/session/index.js.map +1 -0
  84. package/dist/state/session/machine.d.ts +185 -0
  85. package/dist/state/session/machine.js +408 -0
  86. package/dist/state/session/machine.js.map +1 -0
  87. package/dist/state/session/types.d.ts +94 -0
  88. package/dist/state/session/types.js +14 -0
  89. package/dist/state/session/types.js.map +1 -0
  90. package/package.json +46 -26
package/dist/contract.js CHANGED
@@ -1,6 +1,11 @@
1
- import { RESOURCE_CLAIM_FAILURE_CODES } from "./domain/errors.js";
1
+ import { IMPLEMENTATION_FAILURE_CODE_VOCABULARY } from "./failure-code-vocabulary.js";
2
2
  import { OPERATION_AUTHORIZATION_POLICY, OPERATION_VOCABULARY } from "./operation-authorization.js";
3
- import { RESOURCE_CLAIM_COMPATIBILITY_MATRIX, RESOURCE_CLAIM_MODES, RESOURCE_CLAIM_RECOVERY_ACTION_ID, RESOURCE_CLAIM_SCHEMA_VERSION, RESOURCE_CLAIM_TRANSITION_MATRIX, RESOURCE_CLAIM_TRANSITION_MODES, RESOURCE_CLAIM_TRANSITIONS, } from "./resource-claims.js";
3
+ import { RESOURCE_CLAIM_COMPATIBILITY_MATRIX, RESOURCE_CLAIM_MODES, RESOURCE_CLAIM_RECOVERY_ACTION_ID, RESOURCE_CLAIM_SCHEMA_VERSION, RESOURCE_CLAIM_TRANSITION_MATRIX, RESOURCE_CLAIM_TRANSITION_MODES, RESOURCE_CLAIM_TRANSITIONS, LEGACY_RESOURCE_CLAIM_SCHEMA_VERSION, } from "./resource-claims.js";
4
+ import { SESSION_LIFECYCLE_CLASSIFICATION_SCHEMA_VERSION, SESSION_LIFECYCLE_STATES, SESSION_LIFECYCLE_TRANSITION_TABLE, } from "./session-lifecycle-classification.js";
5
+ import { SESSION_LIFECYCLE_ACTION_SCHEMA_VERSION } from "./session-lifecycle-actions.js";
6
+ import { SANDBOX_CONTRACT_ID, SANDBOX_CONTRACT_SCHEMA_VERSION, SANDBOX_OPTIONAL_CAPABILITIES, SANDBOX_REQUIRED_CAPABILITIES, } from "./domain/sandbox.js";
7
+ import { CLI_COMMAND_REGISTRY, resolveCliCommandDefinition } from "./cli-command-registry.js";
8
+ import { DISCARD_PREVIEW_SCHEMA_VERSION } from "./session-registry.js";
4
9
  /** Stable discovery identifier for the standalone local execution contract. */
5
10
  export const MACHINE_CONTRACT_ID = "nawabari.standalone-execution.v1";
6
11
  export const MACHINE_CONTRACT_SCHEMA_VERSION = 1;
@@ -14,6 +19,47 @@ export const RESOURCE_CLAIM_MACHINE_CONTRACT_VERSION = 2;
14
19
  export const RESOURCE_CLAIM_RESULT_SCHEMA = "resource-claim.v2";
15
20
  export const RESOURCE_CLAIM_TRANSITION_MATRIX_ID = "resource-claim-transition-matrix.v1";
16
21
  export const RESOURCE_CLAIM_RECOVERY_SCHEMA = "resource-claim-recovery.v1";
22
+ /**
23
+ * Registry-lock recovery has a separate public platform contract because a
24
+ * package can run on more platforms than it can safely reclaim stale locks.
25
+ */
26
+ export const REGISTRY_LOCK_RECOVERY_CONTRACT_ID = "nawabari.registry-lock-recovery.v1";
27
+ export const REGISTRY_LOCK_RECOVERY_CONTRACT_VERSION = 1;
28
+ /** Public discovery projection of the authoritative protected-execution contract. */
29
+ const PROTECTED_EXECUTION_CAPABILITY = Object.freeze({
30
+ id: "protected-execution",
31
+ contract_id: SANDBOX_CONTRACT_ID,
32
+ schema_version: SANDBOX_CONTRACT_SCHEMA_VERSION,
33
+ commands: ["session run", "session exec"],
34
+ command_aliases: [{ alias: "session exec", canonical: "session run" }],
35
+ result_schema: "sandbox-execution.v1",
36
+ result_schema_version: SANDBOX_CONTRACT_SCHEMA_VERSION,
37
+ result_schemas: [
38
+ {
39
+ schema: "sandbox-execution.v1",
40
+ version: SANDBOX_CONTRACT_SCHEMA_VERSION,
41
+ commands: ["session run", "session exec"],
42
+ },
43
+ ],
44
+ identities: ["session_id", "repository", "worktree", "branch", "network_mode"],
45
+ required_capabilities: SANDBOX_REQUIRED_CAPABILITIES,
46
+ optional_capabilities: SANDBOX_OPTIONAL_CAPABILITIES,
47
+ network_mode: "inherited",
48
+ fail_closed: true,
49
+ ambient_fallback: false,
50
+ readiness: {
51
+ command: "doctor",
52
+ report_field: "sandbox",
53
+ authority: "sandboxDoctorReport",
54
+ fields: ["platform", "platform_supported", "capabilities", "ready", "missing_required", "network_mode"],
55
+ },
56
+ failure_codes: IMPLEMENTATION_FAILURE_CODE_VOCABULARY["protected-execution"],
57
+ failure_code_policy: {
58
+ source: "implementation-owned protected-execution vocabulary",
59
+ missing_or_extra: "deterministic conformance failure",
60
+ internal_exceptions: [],
61
+ },
62
+ });
17
63
  /** Public lifecycle names are projections of the existing dispatcher/help identities. */
18
64
  const RESOURCE_CLAIM_COMMANDS = Object.freeze([
19
65
  "session claim",
@@ -29,6 +75,7 @@ const RESOURCE_CLAIM_COMMANDS = Object.freeze([
29
75
  "resource claims",
30
76
  "session release",
31
77
  "resource release",
78
+ "migrate",
32
79
  ]);
33
80
  const RESOURCE_CLAIM_COMMAND_ALIASES = Object.freeze([
34
81
  { alias: "resource claim", canonical: "session claim" },
@@ -85,6 +132,18 @@ const RESOURCE_CLAIM_RESULT_MAPPINGS = Object.freeze([
85
132
  required: ["claims", "claim_set_generation"],
86
133
  nested_claim_schema_version: RESOURCE_CLAIM_SCHEMA_VERSION,
87
134
  },
135
+ {
136
+ schema: "resource-claim.migration.v1",
137
+ version: RESOURCE_CLAIM_MACHINE_CONTRACT_VERSION,
138
+ commands: ["migrate"],
139
+ required: ["migrated", "registry_schema_version", "claim_schema_version"],
140
+ source_claim_schema_version: LEGACY_RESOURCE_CLAIM_SCHEMA_VERSION,
141
+ target_claim_schema_version: RESOURCE_CLAIM_SCHEMA_VERSION,
142
+ nested_claim_schema_version: RESOURCE_CLAIM_SCHEMA_VERSION,
143
+ atomic: true,
144
+ idempotent_retry: true,
145
+ fail_closed: true,
146
+ },
88
147
  ]);
89
148
  function jsonMatrix() {
90
149
  return Object.fromEntries(RESOURCE_CLAIM_TRANSITION_MODES.map((source) => [
@@ -115,55 +174,82 @@ function operationRequiredModes() {
115
174
  function jsonClone(value) {
116
175
  return JSON.parse(JSON.stringify(value));
117
176
  }
177
+ /** Resolve every machine-contract command through the canonical CLI registry. */
178
+ function registryCommandReference(command) {
179
+ const definition = resolveCliCommandDefinition(command);
180
+ if (definition === undefined) {
181
+ throw new Error(`Machine contract command is not registered: ${command}`);
182
+ }
183
+ const canonical = CLI_COMMAND_REGISTRY.find((candidate) => candidate.name === command || candidate.aliases?.includes(command));
184
+ if (canonical === undefined) {
185
+ throw new Error(`Machine contract command has no canonical identity: ${command}`);
186
+ }
187
+ return { command: definition.name, canonical_command: canonical.name };
188
+ }
189
+ function registryCommands(commands) {
190
+ return commands.map((command) => registryCommandReference(command).command);
191
+ }
192
+ function registryCommandReferences(commands) {
193
+ return commands.map((command) => registryCommandReference(command));
194
+ }
195
+ function registryResultSchemas(mappings) {
196
+ return jsonClone(mappings.map((mapping) => ({
197
+ ...jsonClone(mapping),
198
+ commands: [...registryCommands(mapping.commands)],
199
+ })));
200
+ }
201
+ function registryAliasReferences(aliases) {
202
+ return jsonClone(aliases.map((entry) => {
203
+ const alias = registryCommandReference(entry.alias);
204
+ const canonical = registryCommandReference(entry.canonical);
205
+ if (alias.canonical_command !== canonical.canonical_command) {
206
+ throw new Error(`Machine contract alias identity mismatch: ${entry.alias} -> ${entry.canonical}`);
207
+ }
208
+ return { alias: alias.command, canonical: canonical.canonical_command };
209
+ }));
210
+ }
118
211
  const MACHINE_CONTRACT_CAPABILITIES = Object.freeze([
212
+ PROTECTED_EXECUTION_CAPABILITY,
119
213
  {
120
214
  id: "session-lifecycle",
121
215
  commands: ["session create", "session id", "session show", "session list", "status", "session close"],
122
216
  result_schema: "session.v1",
123
- identities: ["session_id", "repository", "worktree", "branch", "state"],
124
- failure_codes: [
125
- "NOT_GIT_REPOSITORY",
126
- "PROTECTED_WORKTREE",
127
- "PROTECTED_BRANCH",
128
- "WORKTREE_ALREADY_EXISTS",
129
- "BRANCH_ALREADY_EXISTS",
130
- "INVALID_SESSION_ID",
131
- "INVALID_BASE_REF",
132
- "INVALID_REMOTE",
133
- "INVALID_REMOTE_BRANCH",
134
- "INTEGRATION_FETCH_FAILED",
135
- "INVALID_BRANCH",
136
- "INVALID_WORKTREE",
137
- "WORKTREE_OWNED_BY_OTHER_SESSION",
138
- "BRANCH_OWNED_BY_OTHER_SESSION",
139
- "REPOSITORY_MISMATCH",
140
- "WORKTREE_MISMATCH",
141
- "BRANCH_MISMATCH",
142
- "STALE_REGISTRY",
143
- "GIT_STATE_AMBIGUOUS",
144
- "PHYSICAL_OBSERVATION_UNAVAILABLE",
145
- "SESSION_NOT_FOUND",
146
- "NO_CURRENT_SESSION",
147
- "DIRTY_WORKTREE",
148
- "RECOVERABLE_COMMITS",
149
- "RECOVERABLE_STASHES",
150
- "MISSING_WORKTREE",
151
- "INVALID_REGISTRY",
152
- "OPERATION_REJECTED",
153
- "REGISTRY_CORRUPT",
154
- "REGISTRY_UNREADABLE",
155
- "REGISTRY_DURABILITY_UNCERTAIN",
156
- "LOCK_CONTENTION",
157
- "GIT_COMMAND_FAILED",
158
- "GIT_SPAWN_FAILED",
159
- "GIT_TIMEOUT",
160
- "GIT_OUTPUT_LIMIT",
217
+ result_schema_version: 1,
218
+ result_schemas: [
219
+ {
220
+ schema: "session.v1",
221
+ version: 1,
222
+ commands: ["session create", "session id", "session show", "session list", "status", "session close"],
223
+ },
161
224
  ],
225
+ identities: ["session_id", "repository", "worktree", "branch", "state"],
226
+ failure_codes: IMPLEMENTATION_FAILURE_CODE_VOCABULARY["session-lifecycle"],
227
+ failure_code_policy: {
228
+ source: "implementation-owned session-lifecycle vocabulary",
229
+ missing_or_extra: "deterministic conformance failure",
230
+ internal_exceptions: [],
231
+ },
232
+ registry_lock_recovery: {
233
+ contract_id: REGISTRY_LOCK_RECOVERY_CONTRACT_ID,
234
+ contract_version: REGISTRY_LOCK_RECOVERY_CONTRACT_VERSION,
235
+ supported_platforms: ["linux"],
236
+ unsupported_platforms: "non-linux",
237
+ owner_identity: ["hostname", "pid", "processStartTime"],
238
+ process_generation_provider: "linux:/proc/<pid>/stat:starttime",
239
+ stale_recovery: {
240
+ live_owner: "never-reclaim-by-age",
241
+ unknown_or_remote_owner: "fail-closed",
242
+ pid_only_identity: "not-sufficient",
243
+ unsupported_platform: "LOCK_STALE; deliberate operator remediation required",
244
+ },
245
+ },
162
246
  },
163
247
  {
164
248
  id: "session-discard",
165
249
  commands: ["session discard"],
166
250
  result_schema: "session-discard.v1",
251
+ result_schema_version: 1,
252
+ result_schemas: [{ schema: "session-discard.v1", version: 1, commands: ["session discard"] }],
167
253
  identities: [
168
254
  "session_id",
169
255
  "previous_head",
@@ -177,34 +263,45 @@ const MACHINE_CONTRACT_CAPABILITIES = Object.freeze([
177
263
  "final_session_state",
178
264
  "idempotent",
179
265
  ],
180
- failure_codes: [
181
- "INVALID_ARGUMENT",
182
- "MISSING_ARGUMENT",
183
- "INVALID_SESSION_ID",
184
- "SESSION_NOT_FOUND",
185
- "OPERATION_REJECTED",
186
- "OWNERSHIP_MISMATCH",
187
- "WORKTREE_MISMATCH",
188
- "BRANCH_MISMATCH",
189
- "DETACHED_HEAD",
190
- "GIT_STATE_AMBIGUOUS",
191
- "MISSING_WORKTREE",
192
- "PROTECTED_WORKTREE",
193
- "PROTECTED_BRANCH",
194
- "REGISTRY_CORRUPT",
195
- "REGISTRY_UNREADABLE",
196
- "REGISTRY_DURABILITY_UNCERTAIN",
197
- "LOCK_CONTENTION",
198
- "GIT_COMMAND_FAILED",
199
- "GIT_SPAWN_FAILED",
200
- "GIT_TIMEOUT",
201
- "GIT_OUTPUT_LIMIT",
202
- ],
266
+ failure_codes: IMPLEMENTATION_FAILURE_CODE_VOCABULARY["session-discard"],
267
+ failure_code_policy: {
268
+ source: "implementation-owned session-discard vocabulary",
269
+ missing_or_extra: "deterministic conformance failure",
270
+ internal_exceptions: [],
271
+ },
272
+ preview: {
273
+ option: "--preview",
274
+ read_only: true,
275
+ result_schema: "session-discard-preview.v1",
276
+ result_schema_version: DISCARD_PREVIEW_SCHEMA_VERSION,
277
+ identities: [
278
+ "session_id",
279
+ "repository",
280
+ "worktree",
281
+ "branch",
282
+ "current_state",
283
+ "persisted_state",
284
+ "physical_state",
285
+ "worktree_present",
286
+ "branch_present",
287
+ "head",
288
+ "recoverable_commits",
289
+ "claims",
290
+ "claim_count",
291
+ "destructive_scope",
292
+ "warning",
293
+ ],
294
+ evidence_sources: ["session-diagnostic", "cleanup-reconciliation", "authoritative-claim-snapshot"],
295
+ destructive: true,
296
+ one_document: true,
297
+ },
203
298
  },
204
299
  {
205
300
  id: "session-diagnostics",
206
301
  commands: ["session inspect"],
207
302
  result_schema: "session-diagnostic.v1",
303
+ result_schema_version: 1,
304
+ result_schemas: [{ schema: "session-diagnostic.v1", version: 1, commands: ["session inspect"] }],
208
305
  identities: [
209
306
  "session_id",
210
307
  "repository",
@@ -217,25 +314,38 @@ const MACHINE_CONTRACT_CAPABILITIES = Object.freeze([
217
314
  "result_state",
218
315
  "blockers",
219
316
  "safe_actions",
317
+ "next_action",
318
+ "next_actions",
220
319
  "integration_evidence",
320
+ "lifecycle_state",
321
+ "lifecycle",
322
+ "garbage_collection",
221
323
  ],
222
- failure_codes: [
223
- "INVALID_SESSION_ID",
224
- "SESSION_NOT_FOUND",
225
- "NO_CURRENT_SESSION",
226
- "NOT_GIT_REPOSITORY",
227
- "STALE_REGISTRY",
228
- "GIT_STATE_AMBIGUOUS",
229
- "PHYSICAL_OBSERVATION_UNAVAILABLE",
230
- "GIT_COMMAND_FAILED",
231
- "GIT_SPAWN_FAILED",
232
- "GIT_TIMEOUT",
233
- "GIT_OUTPUT_LIMIT",
234
- "REGISTRY_CORRUPT",
235
- "REGISTRY_UNREADABLE",
236
- "REGISTRY_DURABILITY_UNCERTAIN",
237
- "LOCK_CONTENTION",
238
- ],
324
+ lifecycle: {
325
+ schema_version: SESSION_LIFECYCLE_CLASSIFICATION_SCHEMA_VERSION,
326
+ states: [...SESSION_LIFECYCLE_STATES],
327
+ transition_table: SESSION_LIFECYCLE_TRANSITION_TABLE,
328
+ authority: "local-session-registry-observation",
329
+ age_rule: "elapsed-age-is-diagnostic-only",
330
+ recovery_actions: {
331
+ schema_version: SESSION_LIFECYCLE_ACTION_SCHEMA_VERSION,
332
+ action_ids: [
333
+ "retain-session",
334
+ "supply-exact-integrated-revision",
335
+ "retry-close-with-bounded-integration-fetch",
336
+ "discard-session",
337
+ "reconcile-physical-state",
338
+ ],
339
+ execution: "caller-must-invoke-explicit-command",
340
+ ambiguity: "retain-or-reconcile; no-destructive-action",
341
+ },
342
+ },
343
+ failure_codes: IMPLEMENTATION_FAILURE_CODE_VOCABULARY["session-diagnostics"],
344
+ failure_code_policy: {
345
+ source: "implementation-owned session-diagnostics vocabulary",
346
+ missing_or_extra: "deterministic conformance failure",
347
+ internal_exceptions: [],
348
+ },
239
349
  },
240
350
  {
241
351
  id: "resource-claims",
@@ -258,8 +368,11 @@ const MACHINE_CONTRACT_CAPABILITIES = Object.freeze([
258
368
  "updated_at",
259
369
  "claim_set_generation",
260
370
  "previous_claim_set_generation",
371
+ "migrated",
372
+ "registry_schema_version",
373
+ "claim_schema_version",
261
374
  ],
262
- failure_codes: RESOURCE_CLAIM_FAILURE_CODES,
375
+ failure_codes: IMPLEMENTATION_FAILURE_CODE_VOCABULARY["resource-claims"],
263
376
  failure_code_policy: {
264
377
  source: "implementation-owned resource-claim lifecycle vocabulary",
265
378
  missing_or_extra: "deterministic conformance failure",
@@ -348,38 +461,29 @@ const MACHINE_CONTRACT_CAPABILITIES = Object.freeze([
348
461
  id: "authorization-and-evidence",
349
462
  commands: ["guard", "authorize", "checkpoint"],
350
463
  result_schema: "decision.v1 / evidence.v1",
351
- identities: ["operation", "allowed", "code", "claim_ids", "head", "in_claim", "out_of_claim"],
352
- failure_codes: [
353
- "INVALID_OPERATION",
354
- "INVALID_SESSION_ID",
355
- "INVALID_RESOURCE",
356
- "MISSING_RESOURCE_CLAIM",
357
- "INSUFFICIENT_CLAIM_MODE",
358
- "RESOURCE_CLAIM_CONFLICT",
359
- "SESSION_NOT_FOUND",
360
- "SESSION_NOT_ACTIVE",
361
- "NOT_GIT_REPOSITORY",
362
- "MISSING_WORKTREE",
363
- "REPOSITORY_MISMATCH",
364
- "WORKTREE_MISMATCH",
365
- "BRANCH_MISMATCH",
366
- "DETACHED_HEAD",
367
- "STALE_REGISTRY",
368
- "GIT_STATE_AMBIGUOUS",
369
- "PHYSICAL_OBSERVATION_UNAVAILABLE",
370
- "GIT_COMMAND_FAILED",
371
- "WORKTREE_OWNED_BY_OTHER_SESSION",
372
- "BRANCH_OWNED_BY_OTHER_SESSION",
373
- "OWNERSHIP_MISMATCH",
374
- "REGISTRY_CORRUPT",
375
- "REGISTRY_UNREADABLE",
376
- "LOCK_CONTENTION",
464
+ result_schema_version: 1,
465
+ result_schemas: [
466
+ { schema: "decision.v1", version: 1, commands: ["guard", "authorize"] },
467
+ { schema: "evidence.v1", version: 1, commands: ["checkpoint"] },
377
468
  ],
469
+ identities: ["operation", "allowed", "code", "claim_ids", "head", "in_claim", "out_of_claim"],
470
+ operation_vocabulary: [...OPERATION_VOCABULARY],
471
+ failure_codes: IMPLEMENTATION_FAILURE_CODE_VOCABULARY["authorization-and-evidence"],
472
+ failure_code_policy: {
473
+ source: "implementation-owned authorization-and-evidence vocabulary",
474
+ missing_or_extra: "deterministic conformance failure",
475
+ internal_exceptions: [],
476
+ },
378
477
  },
379
478
  {
380
479
  id: "repository-evidence",
381
480
  commands: ["evidence snapshot", "diff"],
382
481
  result_schema: "repository-evidence.v1 / diff.v1",
482
+ result_schema_version: 1,
483
+ result_schemas: [
484
+ { schema: "repository-evidence.v1", version: 1, commands: ["evidence snapshot"] },
485
+ { schema: "diff.v1", version: 1, commands: ["diff"] },
486
+ ],
383
487
  identities: [
384
488
  "session_id",
385
489
  "repository",
@@ -391,34 +495,25 @@ const MACHINE_CONTRACT_CAPABILITIES = Object.freeze([
391
495
  "head",
392
496
  "evidence_hash",
393
497
  ],
394
- failure_codes: [
395
- "INVALID_SESSION_ID",
396
- "SESSION_NOT_FOUND",
397
- "STALE_REGISTRY",
398
- "OWNERSHIP_MISMATCH",
399
- "NOT_GIT_REPOSITORY",
400
- "MISSING_WORKTREE",
401
- "REPOSITORY_MISMATCH",
402
- "WORKTREE_MISMATCH",
403
- "BRANCH_MISMATCH",
404
- "DETACHED_HEAD",
405
- "GIT_STATE_AMBIGUOUS",
406
- "PHYSICAL_OBSERVATION_UNAVAILABLE",
407
- "GIT_COMMAND_FAILED",
408
- "GIT_SPAWN_FAILED",
409
- "GIT_TIMEOUT",
410
- "GIT_OUTPUT_LIMIT",
411
- "REGISTRY_CORRUPT",
412
- "REGISTRY_UNREADABLE",
413
- "LOCK_CONTENTION",
414
- ],
498
+ failure_codes: IMPLEMENTATION_FAILURE_CODE_VOCABULARY["repository-evidence"],
499
+ failure_code_policy: {
500
+ source: "implementation-owned repository-evidence vocabulary",
501
+ missing_or_extra: "deterministic conformance failure",
502
+ internal_exceptions: [],
503
+ },
415
504
  },
416
505
  {
417
506
  id: "governed-git-mutation",
418
507
  commands: ["commit", "push"],
419
508
  result_schema: "commit.v1 / push.v1",
509
+ result_schema_version: 1,
510
+ result_schemas: [
511
+ { schema: "commit.v1", version: 1, commands: ["commit"] },
512
+ { schema: "push.v1", version: 1, commands: ["push"] },
513
+ ],
420
514
  identities: [
421
515
  "commit_sha",
516
+ "reconciliation",
422
517
  "source_sha",
423
518
  "remote",
424
519
  "branch",
@@ -427,71 +522,45 @@ const MACHINE_CONTRACT_CAPABILITIES = Object.freeze([
427
522
  "observed_remote_sha",
428
523
  "relation",
429
524
  ],
430
- failure_codes: [
431
- "INVALID_COMMIT_MESSAGE",
432
- "INVALID_SESSION_ID",
433
- "INVALID_OPERATION",
434
- "INVALID_RESOURCE",
435
- "MISSING_RESOURCE_CLAIM",
436
- "INSUFFICIENT_CLAIM_MODE",
437
- "RESOURCE_CLAIM_CONFLICT",
438
- "SESSION_NOT_FOUND",
439
- "SESSION_NOT_ACTIVE",
440
- "COMMIT_EMPTY_DIFF",
441
- "UNEXPECTED_CHANGED_PATHS",
442
- "COMMIT_STAGING_FAILED",
443
- "COMMIT_FAILED",
444
- "COMMIT_RESULT_UNAVAILABLE",
445
- "COMMIT_RESULT_DIVERGED",
446
- "GIT_STATE_AMBIGUOUS",
447
- "INVALID_REMOTE",
448
- "INVALID_REMOTE_BRANCH",
449
- "PUSH_TARGET_MISMATCH",
450
- "PUSH_REMOTE_INSPECTION_FAILED",
451
- "PUSH_NO_UPSTREAM",
452
- "PUSH_BEHIND",
453
- "PUSH_DIVERGED",
454
- "PUSH_DIRTY_WORKTREE",
455
- "PUSH_FAILED",
456
- "GIT_COMMAND_FAILED",
457
- "GIT_SPAWN_FAILED",
458
- "GIT_TIMEOUT",
459
- "GIT_OUTPUT_LIMIT",
460
- "REGISTRY_CORRUPT",
461
- "REGISTRY_UNREADABLE",
462
- ],
525
+ failure_codes: IMPLEMENTATION_FAILURE_CODE_VOCABULARY["governed-git-mutation"],
526
+ failure_code_policy: {
527
+ source: "implementation-owned governed-git-mutation vocabulary",
528
+ missing_or_extra: "deterministic conformance failure",
529
+ internal_exceptions: [],
530
+ },
531
+ selectors: {
532
+ explicit_resources: "--resource <path> (repeatable; existing default)",
533
+ all_claimed: "--all-claimed (explicit opt-in; mutually exclusive with --resource)",
534
+ resolution: "authoritative claim snapshot plus concrete Git/repository evidence and operation authorization",
535
+ },
463
536
  },
464
537
  {
465
538
  id: "reconciliation-and-cleanup",
466
539
  commands: ["doctor", "gc"],
467
540
  result_schema: "reconciliation.v1 / cleanup.v1",
468
- identities: ["clean", "issues", "candidates", "cleaned", "blocked", "recovery_hints"],
469
- failure_codes: [
470
- "RECONCILIATION_DRIFT",
471
- "DOCTOR_FAILED",
472
- "NOT_GIT_REPOSITORY",
473
- "GIT_COMMAND_FAILED",
474
- "GIT_SPAWN_FAILED",
475
- "GIT_TIMEOUT",
476
- "GIT_OUTPUT_LIMIT",
477
- "PROTECTED_WORKTREE",
478
- "PROTECTED_BRANCH",
479
- "WORKTREE_ALREADY_EXISTS",
480
- "BRANCH_ALREADY_EXISTS",
481
- "WORKTREE_OWNED_BY_OTHER_SESSION",
482
- "BRANCH_OWNED_BY_OTHER_SESSION",
483
- "MISSING_WORKTREE",
484
- "OWNERSHIP_MISMATCH",
485
- "DIRTY_WORKTREE",
486
- "RECOVERABLE_COMMITS",
487
- "RECOVERABLE_STASHES",
488
- "NESTED_REPOSITORY",
489
- "STALE_SESSION",
490
- "REGISTRY_CORRUPT",
491
- "LOCK_CONTENTION",
492
- "REGISTRY_UNREADABLE",
493
- "REGISTRY_DURABILITY_UNCERTAIN",
541
+ result_schema_version: 1,
542
+ result_schemas: [
543
+ { schema: "reconciliation.v1", version: 1, commands: ["doctor"] },
544
+ { schema: "cleanup.v1", version: 1, commands: ["gc"] },
545
+ ],
546
+ identities: [
547
+ "clean",
548
+ "issues",
549
+ "candidates",
550
+ "eligible",
551
+ "cleaned",
552
+ "blocked",
553
+ "recovery_hints",
554
+ "suspicion",
555
+ "destructive_eligibility",
556
+ "lifecycle_state",
494
557
  ],
558
+ failure_codes: IMPLEMENTATION_FAILURE_CODE_VOCABULARY["reconciliation-and-cleanup"],
559
+ failure_code_policy: {
560
+ source: "implementation-owned reconciliation-and-cleanup vocabulary",
561
+ missing_or_extra: "deterministic conformance failure",
562
+ internal_exceptions: [],
563
+ },
495
564
  },
496
565
  ]);
497
566
  /**
@@ -523,18 +592,26 @@ export function machineContract(packageVersion) {
523
592
  },
524
593
  capabilities: MACHINE_CONTRACT_CAPABILITIES.map((capability) => ({
525
594
  id: capability.id,
526
- commands: [...capability.commands],
595
+ commands: [...registryCommands(capability.commands)],
596
+ command_references: [...registryCommandReferences(capability.commands)],
527
597
  result_schema: capability.result_schema,
598
+ ...(capability.id !== "resource-claims"
599
+ ? {
600
+ result_schema_version: capability.result_schema_version,
601
+ result_schemas: registryResultSchemas(capability.result_schemas),
602
+ }
603
+ : {}),
528
604
  identities: [...capability.identities],
529
605
  failure_codes: [...capability.failure_codes],
606
+ failure_code_policy: jsonClone(capability.failure_code_policy),
530
607
  ...(capability.id === "resource-claims"
531
608
  ? {
532
609
  contract_id: capability.contract_id,
533
610
  contract_version: capability.contract_version,
534
611
  claim_schema_version: capability.claim_schema_version,
535
612
  result_schema_version: capability.result_schema_version,
536
- command_aliases: jsonClone(capability.command_aliases),
537
- result_schemas: jsonClone(capability.result_schemas),
613
+ command_aliases: registryAliasReferences(capability.command_aliases),
614
+ result_schemas: registryResultSchemas(capability.result_schemas),
538
615
  failure_code_policy: jsonClone(capability.failure_code_policy),
539
616
  transition_matrix: jsonClone(capability.transition_matrix),
540
617
  compatibility: jsonClone(capability.compatibility),
@@ -543,16 +620,42 @@ export function machineContract(packageVersion) {
543
620
  recovery: jsonClone(capability.recovery),
544
621
  operation_required_claim_modes: capability.operation_required_claim_modes,
545
622
  help_dispatcher: {
546
- commands: [...capability.commands],
623
+ commands: [...registryCommands(capability.commands)],
547
624
  identity_rule: "each command and alias resolves to an existing dispatcher and help identity",
548
625
  },
549
626
  claim_set_replacement: {
550
- commands: ["session update", "resource update"],
627
+ commands: [...registryCommands(["session update", "resource update"])],
551
628
  atomic: true,
552
629
  pairing: "adjacent-resource-mode",
553
630
  idempotent_retry: true,
554
631
  unchanged_on_rejection: true,
555
632
  },
633
+ migration: {
634
+ command: registryCommandReference("migrate").command,
635
+ source_claim_schema_version: LEGACY_RESOURCE_CLAIM_SCHEMA_VERSION,
636
+ target_claim_schema_version: RESOURCE_CLAIM_SCHEMA_VERSION,
637
+ result_schema: "resource-claim.migration.v1",
638
+ atomic: true,
639
+ idempotent_retry: true,
640
+ fail_closed: true,
641
+ },
642
+ }
643
+ : {}),
644
+ ...(capability.id === "session-lifecycle"
645
+ ? { registry_lock_recovery: jsonClone(capability.registry_lock_recovery) }
646
+ : {}),
647
+ ...(capability.id === "session-diagnostics" ? { lifecycle: jsonClone(capability.lifecycle) } : {}),
648
+ ...(capability.id === "protected-execution"
649
+ ? {
650
+ contract_id: capability.contract_id,
651
+ schema_version: capability.schema_version,
652
+ command_aliases: registryAliasReferences(capability.command_aliases),
653
+ required_capabilities: [...capability.required_capabilities],
654
+ optional_capabilities: [...capability.optional_capabilities],
655
+ network_mode: capability.network_mode,
656
+ fail_closed: capability.fail_closed,
657
+ ambient_fallback: capability.ambient_fallback,
658
+ readiness: jsonClone(capability.readiness),
556
659
  }
557
660
  : {}),
558
661
  })),
@@ -593,6 +696,7 @@ export function machineContract(packageVersion) {
593
696
  commands: ["show", "inspect", "claim", "claims", "release", "update", "close", "discard"],
594
697
  ambiguity: "supplying both positional and --session is rejected",
595
698
  discard_requires_explicit_target: true,
699
+ discard_preview: "--preview (read-only; one bounded JSON document in machine mode)",
596
700
  },
597
701
  destructive_lifecycle: {
598
702
  command: "session discard",