@xemahq/kernel-contracts 0.14.0 → 0.16.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 (167) hide show
  1. package/dist/agent-composition/lib/agent.d.ts.map +1 -1
  2. package/dist/agent-composition/lib/agent.js.map +1 -1
  3. package/dist/agent-session/index.d.ts +2 -0
  4. package/dist/agent-session/index.d.ts.map +1 -0
  5. package/dist/{document-templates/lib → agent-session}/index.js +1 -2
  6. package/dist/agent-session/index.js.map +1 -0
  7. package/dist/agent-session/lib/lifecycle.d.ts +40 -0
  8. package/dist/agent-session/lib/lifecycle.d.ts.map +1 -0
  9. package/dist/agent-session/lib/lifecycle.js +73 -0
  10. package/dist/agent-session/lib/lifecycle.js.map +1 -0
  11. package/dist/agent-workspace/awp-spec.json +1 -1
  12. package/dist/agent-workspace/lib/workspace-layout.d.ts +0 -1
  13. package/dist/agent-workspace/lib/workspace-layout.d.ts.map +1 -1
  14. package/dist/agent-workspace/lib/workspace-layout.js +1 -6
  15. package/dist/agent-workspace/lib/workspace-layout.js.map +1 -1
  16. package/dist/biome/index.d.ts +0 -1
  17. package/dist/biome/index.d.ts.map +1 -1
  18. package/dist/biome/index.js +0 -1
  19. package/dist/biome/index.js.map +1 -1
  20. package/dist/biome/lib/biome-manifest.d.ts +12 -22
  21. package/dist/biome/lib/biome-manifest.d.ts.map +1 -1
  22. package/dist/biome/lib/biome-manifest.js +5 -27
  23. package/dist/biome/lib/biome-manifest.js.map +1 -1
  24. package/dist/biome/lib/biome-origin.d.ts.map +1 -1
  25. package/dist/biome/lib/biome-origin.js.map +1 -1
  26. package/dist/distribution/lib/distribution-lock.d.ts +2 -1
  27. package/dist/distribution/lib/distribution-lock.d.ts.map +1 -1
  28. package/dist/distribution/lib/distribution-lock.js +2 -1
  29. package/dist/distribution/lib/distribution-lock.js.map +1 -1
  30. package/dist/distribution/lib/distribution.d.ts +4 -2
  31. package/dist/distribution/lib/distribution.d.ts.map +1 -1
  32. package/dist/distribution/lib/distribution.js +6 -2
  33. package/dist/distribution/lib/distribution.js.map +1 -1
  34. package/dist/execution-context/lib/execution-context.d.ts.map +1 -1
  35. package/dist/execution-context/lib/execution-context.js.map +1 -1
  36. package/dist/execution-environment/lib/execution-environment.d.ts +0 -1
  37. package/dist/execution-environment/lib/execution-environment.d.ts.map +1 -1
  38. package/dist/execution-environment/lib/execution-environment.js +1 -2
  39. package/dist/execution-environment/lib/execution-environment.js.map +1 -1
  40. package/dist/object/lib/xema-object-kind.d.ts +0 -1
  41. package/dist/object/lib/xema-object-kind.d.ts.map +1 -1
  42. package/dist/object/lib/xema-object-kind.js +0 -1
  43. package/dist/object/lib/xema-object-kind.js.map +1 -1
  44. package/dist/object/lib/xema-object-ref.d.ts.map +1 -1
  45. package/dist/object/lib/xema-object-ref.js +20 -1
  46. package/dist/object/lib/xema-object-ref.js.map +1 -1
  47. package/dist/reference-resolution/lib/reference-resolution.d.ts.map +1 -1
  48. package/dist/reference-resolution/lib/reference-resolution.js.map +1 -1
  49. package/dist/runner/index.d.ts +0 -1
  50. package/dist/runner/index.d.ts.map +1 -1
  51. package/dist/runner/index.js +0 -1
  52. package/dist/runner/index.js.map +1 -1
  53. package/dist/runner-input-hash/index.d.ts +2 -0
  54. package/dist/runner-input-hash/index.d.ts.map +1 -0
  55. package/dist/{document-themes/lib → runner-input-hash}/index.js +1 -2
  56. package/dist/runner-input-hash/index.js.map +1 -0
  57. package/dist/runner-input-hash/lib/input-hash.d.ts.map +1 -0
  58. package/dist/runner-input-hash/lib/input-hash.js.map +1 -0
  59. package/dist/search-source/lib/search-replay.d.ts +0 -1
  60. package/dist/search-source/lib/search-replay.d.ts.map +1 -1
  61. package/dist/search-source/lib/search-replay.js +0 -5
  62. package/dist/search-source/lib/search-replay.js.map +1 -1
  63. package/dist/service-registry/lib/service-names.generated.d.ts +3 -0
  64. package/dist/service-registry/lib/service-names.generated.d.ts.map +1 -1
  65. package/dist/service-registry/lib/service-names.generated.js +3 -0
  66. package/dist/service-registry/lib/service-names.generated.js.map +1 -1
  67. package/dist/workflow/index.d.ts +0 -2
  68. package/dist/workflow/index.d.ts.map +1 -1
  69. package/dist/workflow/index.js +0 -2
  70. package/dist/workflow/index.js.map +1 -1
  71. package/dist/workflow/lib/catalog-taxonomies.d.ts +0 -1
  72. package/dist/workflow/lib/catalog-taxonomies.d.ts.map +1 -1
  73. package/dist/workflow/lib/catalog-taxonomies.js +9 -12
  74. package/dist/workflow/lib/catalog-taxonomies.js.map +1 -1
  75. package/dist/workflow/lib/enums.d.ts +0 -8
  76. package/dist/workflow/lib/enums.d.ts.map +1 -1
  77. package/dist/workflow/lib/enums.js +1 -15
  78. package/dist/workflow/lib/enums.js.map +1 -1
  79. package/dist/workflow/lib/model-ref.d.ts.map +1 -1
  80. package/dist/workflow/lib/model-ref.js.map +1 -1
  81. package/dist/workflow/lib/mount-plan.d.ts.map +1 -1
  82. package/dist/workflow/lib/run-progress.d.ts +0 -1
  83. package/dist/workflow/lib/run-progress.d.ts.map +1 -1
  84. package/dist/workflow/lib/run-progress.js +0 -1
  85. package/dist/workflow/lib/run-progress.js.map +1 -1
  86. package/dist/workspace-storage/index.d.ts +0 -1
  87. package/dist/workspace-storage/index.d.ts.map +1 -1
  88. package/dist/workspace-storage/index.js +0 -1
  89. package/dist/workspace-storage/index.js.map +1 -1
  90. package/dist/workspace-storage/lib/types.d.ts.map +1 -1
  91. package/package.json +1 -1
  92. package/src/agent-composition/lib/agent.ts +3 -2
  93. package/src/agent-session/index.ts +1 -0
  94. package/src/agent-session/lib/lifecycle.ts +156 -0
  95. package/src/agent-workspace/lib/workspace-layout.ts +0 -13
  96. package/src/biome/index.ts +0 -1
  97. package/src/biome/lib/biome-manifest.ts +11 -52
  98. package/src/biome/lib/biome-origin.ts +4 -3
  99. package/src/distribution/lib/distribution-lock.ts +6 -2
  100. package/src/distribution/lib/distribution.ts +22 -3
  101. package/src/execution-context/lib/execution-context.ts +4 -7
  102. package/src/execution-environment/lib/execution-environment.ts +4 -7
  103. package/src/object/lib/xema-object-kind.ts +2 -2
  104. package/src/object/lib/xema-object-ref.ts +21 -1
  105. package/src/policy/lib/obligations.ts +5 -5
  106. package/src/reference-resolution/lib/reference-resolution.ts +4 -2
  107. package/src/runner/index.ts +0 -1
  108. package/src/runner-input-hash/index.ts +1 -0
  109. package/src/{runner → runner-input-hash}/lib/input-hash.ts +7 -0
  110. package/src/search-source/lib/search-replay.ts +0 -10
  111. package/src/service-registry/lib/service-names.generated.ts +3 -0
  112. package/src/workflow/index.ts +0 -2
  113. package/src/workflow/lib/catalog-taxonomies.ts +21 -15
  114. package/src/workflow/lib/enums.ts +3 -24
  115. package/src/workflow/lib/model-ref.ts +5 -6
  116. package/src/workflow/lib/mount-plan.ts +0 -1
  117. package/src/workflow/lib/run-progress.ts +0 -1
  118. package/src/workspace-storage/index.ts +0 -1
  119. package/src/workspace-storage/lib/types.ts +11 -5
  120. package/dist/agent-composition/lib/composition-limits-schema.d.ts +0 -4
  121. package/dist/agent-composition/lib/composition-limits-schema.d.ts.map +0 -1
  122. package/dist/agent-composition/lib/composition-limits-schema.js +0 -13
  123. package/dist/agent-composition/lib/composition-limits-schema.js.map +0 -1
  124. package/dist/agent-composition/lib/composition-workspace.d.ts +0 -37
  125. package/dist/agent-composition/lib/composition-workspace.d.ts.map +0 -1
  126. package/dist/agent-composition/lib/composition-workspace.js +0 -9
  127. package/dist/agent-composition/lib/composition-workspace.js.map +0 -1
  128. package/dist/agent-composition/lib/composition.d.ts +0 -65
  129. package/dist/agent-composition/lib/composition.d.ts.map +0 -1
  130. package/dist/agent-composition/lib/composition.js +0 -18
  131. package/dist/agent-composition/lib/composition.js.map +0 -1
  132. package/dist/agent-workspace/lib/awp-v1.d.ts +0 -15
  133. package/dist/agent-workspace/lib/awp-v1.d.ts.map +0 -1
  134. package/dist/agent-workspace/lib/awp-v1.js +0 -197
  135. package/dist/agent-workspace/lib/awp-v1.js.map +0 -1
  136. package/dist/biome/lib/biome-api.d.ts +0 -12
  137. package/dist/biome/lib/biome-api.d.ts.map +0 -1
  138. package/dist/biome/lib/biome-api.js +0 -14
  139. package/dist/biome/lib/biome-api.js.map +0 -1
  140. package/dist/document-templates/lib/index.d.ts +0 -3
  141. package/dist/document-templates/lib/index.d.ts.map +0 -1
  142. package/dist/document-templates/lib/index.js.map +0 -1
  143. package/dist/document-themes/lib/index.d.ts +0 -3
  144. package/dist/document-themes/lib/index.d.ts.map +0 -1
  145. package/dist/document-themes/lib/index.js.map +0 -1
  146. package/dist/runner/lib/input-hash.d.ts.map +0 -1
  147. package/dist/runner/lib/input-hash.js.map +0 -1
  148. package/dist/workflow/lib/sampling-profiles.d.ts +0 -18
  149. package/dist/workflow/lib/sampling-profiles.d.ts.map +0 -1
  150. package/dist/workflow/lib/sampling-profiles.js +0 -56
  151. package/dist/workflow/lib/sampling-profiles.js.map +0 -1
  152. package/dist/workflow/lib/workflow-stage.d.ts +0 -11
  153. package/dist/workflow/lib/workflow-stage.d.ts.map +0 -1
  154. package/dist/workflow/lib/workflow-stage.js +0 -28
  155. package/dist/workflow/lib/workflow-stage.js.map +0 -1
  156. package/dist/workspace-storage/lib/schemas.d.ts +0 -56
  157. package/dist/workspace-storage/lib/schemas.d.ts.map +0 -1
  158. package/dist/workspace-storage/lib/schemas.js +0 -59
  159. package/dist/workspace-storage/lib/schemas.js.map +0 -1
  160. package/src/biome/lib/biome-api.ts +0 -33
  161. package/src/document-templates/lib/index.ts +0 -2
  162. package/src/document-themes/lib/index.ts +0 -2
  163. package/src/workflow/lib/sampling-profiles.ts +0 -153
  164. package/src/workflow/lib/workflow-stage.ts +0 -89
  165. package/src/workspace-storage/lib/schemas.ts +0 -75
  166. /package/dist/{runner → runner-input-hash}/lib/input-hash.d.ts +0 -0
  167. /package/dist/{runner → runner-input-hash}/lib/input-hash.js +0 -0
@@ -0,0 +1,156 @@
1
+ // ═══════════════════════════════════════════════════════════════════════════
2
+ // ── Agent-session lifecycle — SINGLE SOURCE OF TRUTH ──
3
+ //
4
+ // The closed `SessionLifecycleState` / `SessionOwnerKind` value sets + the
5
+ // transition FSM for an agent-session row. This is the canonical Layer-0
6
+ // contract that the persistence enum (agent-session-api Prisma `SessionStatus`
7
+ // / `SessionOwnerKind`), the service's in-tree state machine, and the
8
+ // runtime worker mirror ALL derive from — collapsing the former three hand-
9
+ // maintained copies into one. Prisma cannot import a TS value, so its schema
10
+ // re-declares the same members and CI guards parity
11
+ // (`tooling/boundaries/check-session-enum-parity.mjs`).
12
+ //
13
+ // `canTransition()` is the single predicate every caller (interactive sessions
14
+ // AND the workflow-runtime worker dispatch activity) consults before issuing a
15
+ // state-change HTTP call, so misuse fails fast at compile time rather than as a
16
+ // 409 from the service.
17
+ // ═══════════════════════════════════════════════════════════════════════════
18
+
19
+ import { z } from 'zod';
20
+
21
+ /**
22
+ * Lifecycle state of an agent-session row. Value-identical to the persisted
23
+ * `session_status` Prisma enum. Closed set.
24
+ */
25
+ export const SessionLifecycleState = {
26
+ creating: 'creating',
27
+ provisioning: 'provisioning',
28
+ active: 'active',
29
+ paused: 'paused',
30
+ recovering: 'recovering',
31
+ completing: 'completing',
32
+ completed: 'completed',
33
+ failed: 'failed',
34
+ archived: 'archived',
35
+ } as const;
36
+
37
+ export type SessionLifecycleStateValue =
38
+ (typeof SessionLifecycleState)[keyof typeof SessionLifecycleState];
39
+
40
+ export const SessionLifecycleStateSchema = z.enum(
41
+ Object.values(SessionLifecycleState) as [
42
+ SessionLifecycleStateValue,
43
+ ...SessionLifecycleStateValue[],
44
+ ],
45
+ );
46
+
47
+ /**
48
+ * Who created the session row. Value-identical to the persisted
49
+ * `session_owner_kind` Prisma enum.
50
+ *
51
+ * - `interactive_session` — user-facing chat sessions
52
+ * - `pipeline_run` — workflow-runtime-worker redraft loop spines
53
+ * - `chat_thread` — reserved (no dispatcher today)
54
+ */
55
+ export const SessionOwnerKind = {
56
+ interactive_session: 'interactive_session',
57
+ pipeline_run: 'pipeline_run',
58
+ chat_thread: 'chat_thread',
59
+ } as const;
60
+
61
+ export type SessionOwnerKindValue =
62
+ (typeof SessionOwnerKind)[keyof typeof SessionOwnerKind];
63
+
64
+ export const SessionOwnerKindSchema = z.enum(
65
+ Object.values(SessionOwnerKind) as [
66
+ SessionOwnerKindValue,
67
+ ...SessionOwnerKindValue[],
68
+ ],
69
+ );
70
+
71
+ /**
72
+ * Per-state transition matrix. `canTransition(from, to)` returns true iff the
73
+ * transition is valid.
74
+ *
75
+ * Notable transitions:
76
+ * - `paused → recovering` (resume claim)
77
+ * - `recovering → active` (resume success)
78
+ * - `recovering → paused` (resume rollback)
79
+ * - `active → completing → completed` (terminal success)
80
+ * - any-non-terminal → `failed` (terminal failure)
81
+ * - `paused | completed | failed → archived` (cleanup sweep)
82
+ */
83
+ const TRANSITIONS: Readonly<
84
+ Record<SessionLifecycleStateValue, ReadonlySet<SessionLifecycleStateValue>>
85
+ > = {
86
+ creating: new Set([
87
+ SessionLifecycleState.provisioning,
88
+ SessionLifecycleState.failed,
89
+ ]),
90
+ provisioning: new Set([
91
+ SessionLifecycleState.active,
92
+ SessionLifecycleState.failed,
93
+ ]),
94
+ active: new Set([
95
+ SessionLifecycleState.paused,
96
+ SessionLifecycleState.completing,
97
+ SessionLifecycleState.failed,
98
+ ]),
99
+ paused: new Set([
100
+ SessionLifecycleState.recovering,
101
+ SessionLifecycleState.archived,
102
+ SessionLifecycleState.failed,
103
+ ]),
104
+ recovering: new Set([
105
+ SessionLifecycleState.active,
106
+ SessionLifecycleState.paused,
107
+ SessionLifecycleState.failed,
108
+ ]),
109
+ completing: new Set([
110
+ SessionLifecycleState.completed,
111
+ SessionLifecycleState.failed,
112
+ ]),
113
+ completed: new Set([SessionLifecycleState.archived]),
114
+ failed: new Set([SessionLifecycleState.archived]),
115
+ archived: new Set(),
116
+ };
117
+
118
+ export function canTransition(
119
+ from: SessionLifecycleStateValue,
120
+ to: SessionLifecycleStateValue,
121
+ ): boolean {
122
+ return TRANSITIONS[from].has(to);
123
+ }
124
+
125
+ /**
126
+ * Terminal states — no further transitions possible (except the
127
+ * `completed | failed → archived` cleanup sweep). Callers use this to
128
+ * short-circuit "is this session done?" checks.
129
+ */
130
+ export function isTerminal(state: SessionLifecycleStateValue): boolean {
131
+ return (
132
+ state === SessionLifecycleState.completed ||
133
+ state === SessionLifecycleState.failed ||
134
+ state === SessionLifecycleState.archived
135
+ );
136
+ }
137
+
138
+ /**
139
+ * Pausable states — the session has a live worker that can be told to
140
+ * snapshot. `provisioning` is intentionally excluded: the worker isn't ready
141
+ * yet, so a pause request would 409. Callers receiving such a 409 should retry
142
+ * with backoff once `active` is reached.
143
+ */
144
+ export function isPausable(state: SessionLifecycleStateValue): boolean {
145
+ return state === SessionLifecycleState.active;
146
+ }
147
+
148
+ /**
149
+ * Resumable states. `paused` is the canonical case. `failed` rows are NOT
150
+ * resumable from here — they require explicit operator action (the resume API
151
+ * would 409). `recovering` is a transient state owned by an in-flight resume;
152
+ * another caller observing it should back off.
153
+ */
154
+ export function isResumable(state: SessionLifecycleStateValue): boolean {
155
+ return state === SessionLifecycleState.paused;
156
+ }
@@ -35,19 +35,6 @@ export enum WorkspaceMount {
35
35
  Instructions = '/workspace/.xema/instructions',
36
36
  }
37
37
 
38
- // `WorkspaceRole` is the role the running session takes. The canonical
39
- // values + helpers live in `@xemahq/workflow-contracts:agent-role` —
40
- // re-exported here as `WorkspaceRole` for back-compat with consumers
41
- // that imported from this module. New code should import `AgentRunRole`
42
- // directly from `@xemahq/workflow-contracts`.
43
- export {
44
- AGENT_RUN_ROLES as WORKSPACE_ROLES,
45
- AGENT_RUN_ROLES_INTERACTIVE as WORKSPACE_ROLES_INTERACTIVE,
46
- AGENT_RUN_ROLES_PIPELINE as WORKSPACE_ROLES_PIPELINE,
47
- isAgentRunRole as isWorkspaceRole,
48
- type AgentRunRole as WorkspaceRole,
49
- } from '../../workflow';
50
-
51
38
  /**
52
39
  * Mount mode the worker requests. Read-only mounts are `chmod a-w` at
53
40
  * attach-time so the kernel enforces immutability; writable mounts
@@ -7,7 +7,6 @@ export * from './lib/biome-audience';
7
7
  export * from './lib/biome-origin';
8
8
  export * from './lib/biome-trust-tier';
9
9
  export * from './lib/biome-availability-grant';
10
- export * from './lib/biome-api';
11
10
  export * from './lib/biome-lifecycle-hooks';
12
11
  export * from './lib/biome-engines';
13
12
  export * from './lib/biome-permissions';
@@ -13,21 +13,18 @@ import {
13
13
  MigrationRunnerKind,
14
14
  OrgDatabasePurpose,
15
15
  } from '../../org-database';
16
- // Import from the specific runner lib files, NOT the `../../runner` barrel.
17
- // The barrel re-exports `input-hash` (a server-only util with a top-level
18
- // `require('node:crypto')`); pulling the barrel here drags `node:crypto` into
19
- // every browser consumer of `@xemahq/kernel-contracts/biome` (e.g. host-web's
20
- // BiomeNewPage), which webpack cannot bundle (UnhandledSchemeError). These
21
- // three symbols carry no crypto dependency.
22
- import { DataLocalitySchema } from '../../runner/lib/runner-registration';
23
- import { RuntimeIsolationLevelSchema } from '../../runner/lib/runtime-isolation';
24
- import { RunnerTrustTier } from '../../runner/lib/runner';
16
+ import {
17
+ DataLocalitySchema,
18
+ RuntimeIsolationLevelSchema,
19
+ RunnerTrustTier,
20
+ } from '../../runner';
25
21
  import { z } from 'zod';
26
22
  import {
27
23
  BiomeAudience,
28
24
  BiomeAudienceSchema,
29
25
  DEFAULT_BIOME_AUDIENCE,
30
26
  } from './biome-audience';
27
+ import { BiomeOriginSchema } from './biome-origin';
31
28
  import {
32
29
  BiomeEnginesSchema,
33
30
  } from './biome-engines';
@@ -129,18 +126,6 @@ const LEGACY_SHIPS_CONTENT_DIR: Readonly<Record<string, string>> = {
129
126
  provisioningScaffolds: 'provisioning',
130
127
  };
131
128
 
132
- const LEGACY_SHIPS_MODULES_DIR: Readonly<Record<string, string>> = {
133
- agents: 'agents',
134
- actions: 'actions',
135
- mountSourceKinds: 'mount-source-kinds',
136
- deliverableSpecKinds: 'deliverable-spec-kinds',
137
- runtimeMountKinds: 'runtime-mount-kinds',
138
- workspaceSpecOverlay: 'workspace-spec-overlay',
139
- systemOverlayContributions: 'system-overlay-contributions',
140
- adapterKinds: 'adapter-kinds',
141
- integrationProviders: 'integration-providers',
142
- };
143
-
144
129
  /**
145
130
  * Resolve a legacy `ships.content[]` value to its conventional directory
146
131
  * name, or `null` for unknown tokens. Used by the legacy file-walk
@@ -157,21 +142,6 @@ export function contentKindToDir(kind: string): string {
157
142
  return dir;
158
143
  }
159
144
 
160
- /**
161
- * Resolve a legacy `ships.modules[]` value to its conventional directory
162
- * name. Same legacy-only scope as `contentKindToDir`.
163
- */
164
- export function moduleKindToDir(kind: string): string {
165
- const dir = LEGACY_SHIPS_MODULES_DIR[kind];
166
- if (!dir) {
167
- throw new Error(
168
- `biome-host-sdk: unknown legacy ships.modules[] value "${kind}". ` +
169
- `Either migrate the biome to xema.contributions or extend LEGACY_SHIPS_MODULES_DIR.`,
170
- );
171
- }
172
- return dir;
173
- }
174
-
175
145
  /**
176
146
  * Org-managed database declaration for biomes that need a dedicated
177
147
  * schema in a provisioned org database.
@@ -335,19 +305,6 @@ export const BiomeShipsSchema = z
335
305
  .strict();
336
306
  export type BiomeShips = z.infer<typeof BiomeShipsSchema>;
337
307
 
338
- /**
339
- * Manifest-shape hosting/trust posture for a server biome. Used by
340
- * integration-host plumbing (Phase 7) to decide whether to load
341
- * adapter-contribution modules in-process or via a sidecar deployment.
342
- * Manifests authored by Xema and audited third parties may set
343
- * `first-party`; everything else defaults to `third-party`.
344
- *
345
- * Kept manifest-internal (not re-exported) so it does not collide with the
346
- * kernel `BiomeTrustTier` provenance enum (`first-party | verified-store |
347
- * community-store | …`) already exposed by this package.
348
- */
349
- const ManifestBiomeTrustTierSchema = z.enum(['first-party', 'third-party']);
350
-
351
308
  /**
352
309
  * AdapterKind slug — accepts a built-in slug verbatim, plus any
353
310
  * lowercase kebab-case slug a biome-contributed kind could register.
@@ -765,10 +722,12 @@ const ServerBiomeXemaSchema = z
765
722
  ships: BiomeShipsSchema.optional(),
766
723
  capabilities: ServerBiomeCapabilitiesSchema.optional(),
767
724
  /**
768
- * Hosting posture for adapter-contribution modules (Phase 7). Other
769
- * biome kinds ignore this field. Defaults to `third-party`.
725
+ * Hosting/provenance posture for adapter-contribution modules (Phase 7).
726
+ * The same `first-party | third-party` set as {@link BiomeOrigin} (which
727
+ * documents this very field) — uses `BiomeOriginSchema` so the two cannot
728
+ * drift. Other biome kinds ignore this field. Defaults to `third-party`.
770
729
  */
771
- trustTier: ManifestBiomeTrustTierSchema.optional(),
730
+ trustTier: BiomeOriginSchema.optional(),
772
731
  /**
773
732
  * Integration dependencies the biome needs to be useful. Surfaced
774
733
  * to the install wizard as a consent screen. Non-optional entries
@@ -11,9 +11,10 @@ import { z } from 'zod';
11
11
  * and is not knowable from source. Keep the two separate — the distribution
12
12
  * trust gate operates on origin, not on install-time provenance.
13
13
  *
14
- * Closed set; new values are a kernel change. (Seam: the biome-sdk manifest's
15
- * own 2-value `BiomeTrustTierSchema` should migrate to import this enum so the
16
- * posture has a single source of truth.)
14
+ * Closed set; new values are a kernel change. This IS the single source of
15
+ * truth: the `xema-biome.json` manifest schema (`BiomeXemaSchema.trustTier`)
16
+ * validates against `BiomeOriginSchema`, and biome-sdk re-exports that schema
17
+ * rather than declaring its own — so the posture cannot drift.
17
18
  */
18
19
  export enum BiomeOrigin {
19
20
  FirstParty = 'first-party',
@@ -7,6 +7,10 @@ import {
7
7
  type BiomeTarget,
8
8
  type BiomeOrigin,
9
9
  } from '../../biome';
10
+ import {
11
+ PlatformServiceTierSchema,
12
+ type PlatformServiceTier,
13
+ } from './distribution';
10
14
 
11
15
  /**
12
16
  * A single biome as resolved into a distribution lockfile. Version-pinned and
@@ -63,12 +67,12 @@ export const LockedBiomeSchema = z.object({
63
67
  export interface LockedPlatformService {
64
68
  name: string;
65
69
  /** Wave/boot tier — drives ordering in the generated bring-up plan. */
66
- tier: BiomeTier | 'edge';
70
+ tier: PlatformServiceTier;
67
71
  }
68
72
 
69
73
  export const LockedPlatformServiceSchema = z.object({
70
74
  name: z.string().min(1),
71
- tier: z.union([BiomeTierSchema, z.literal('edge')]),
75
+ tier: PlatformServiceTierSchema,
72
76
  }) as z.ZodType<LockedPlatformService>;
73
77
 
74
78
  /**
@@ -1,10 +1,29 @@
1
1
  import { z } from 'zod';
2
- import { BiomeOriginSchema, type BiomeOrigin } from '../../biome';
2
+ import {
3
+ BiomeOriginSchema,
4
+ BiomeTierSchema,
5
+ type BiomeOrigin,
6
+ type BiomeTier,
7
+ } from '../../biome';
3
8
  import {
4
9
  DistributionSelectorSchema,
5
10
  type DistributionSelector,
6
11
  } from './distribution-selector';
7
12
 
13
+ /**
14
+ * Wave/boot tier of a platform-substrate service — the four {@link BiomeTier}
15
+ * waves (`kernel | system | base | platform`) plus `edge` for the outermost,
16
+ * browser-facing wave. Single source of truth for BOTH the distribution
17
+ * manifest ({@link DistributionPlatformService}) and the resolved lock
18
+ * (`LockedPlatformService`), so the tier vocabulary can never drift between them.
19
+ */
20
+ export type PlatformServiceTier = BiomeTier | 'edge';
21
+
22
+ export const PlatformServiceTierSchema = z.union([
23
+ BiomeTierSchema,
24
+ z.literal('edge'),
25
+ ]) as z.ZodType<PlatformServiceTier>;
26
+
8
27
  /**
9
28
  * Schema-versioning seed for `xema-distribution.json`. Bumped via a coordinated
10
29
  * PR on an incompatible shape change; consumers refuse versions they do not
@@ -37,12 +56,12 @@ export const DistributionTrustPolicySchema = z.object({
37
56
  export interface DistributionPlatformService {
38
57
  name: string;
39
58
  /** Wave/boot tier — drives ordering in the generated bring-up plan. */
40
- tier: 'kernel' | 'system' | 'base' | 'platform' | 'edge';
59
+ tier: PlatformServiceTier;
41
60
  }
42
61
 
43
62
  export const DistributionPlatformServiceSchema = z.object({
44
63
  name: z.string().min(1),
45
- tier: z.enum(['kernel', 'system', 'base', 'platform', 'edge']),
64
+ tier: PlatformServiceTierSchema,
46
65
  }) as z.ZodType<DistributionPlatformService>;
47
66
 
48
67
  /**
@@ -64,14 +64,11 @@ export const ExecutionContextBiomeSchema = z.object({
64
64
  * v4.3 §A.3).
65
65
  *
66
66
  * `id` is the canonical `environment:<slug>` ref (string-typed here to
67
- * keep the envelope JSON-clean — the kernel-side reference type lives in
68
- * `@xemahq/execution-environment-contracts`).
67
+ * keep the envelope JSON-clean — the kernel-side reference type lives in the
68
+ * `@xemahq/kernel-contracts/execution-environment` surface).
69
69
  *
70
- * `kind` is the {@link ExecutionEnvironmentKind} value matched against the eight
71
- * built-in environments + the `trusted-dev` escape hatch. The internal
72
- * identifier `ExecutionEnvironmentKind` is still named "Zone" — the rename to
73
- * `ExecutionEnvironmentKind` is scheduled for Phase A.5 (plan §A.1
74
- * follow-up sweep), not Phase A.3.
70
+ * `kind` is the {@link ExecutionEnvironmentKind} value matched against the
71
+ * built-in environments + the `trusted-dev` escape hatch.
75
72
  */
76
73
  export interface ExecutionContextEnvironment {
77
74
  id: string;
@@ -53,10 +53,10 @@ export interface ParsedExecutionEnvironmentRef {
53
53
 
54
54
  /**
55
55
  * Structured error thrown by `parseEnvironmentRef` / `formatEnvironmentRef`.
56
- * Carries the stable `EXECUTION_ENVIRONMENT_REF_INVALID` code. Subclass
57
- * of `CapabilityError` so call sites that already branch on capability-
58
- * layer errors get this for free; the dedicated code keeps the denial
59
- * taxonomy crisp.
56
+ * A subclass of `CapabilityError` carrying `CapabilityErrorCode.CapabilityRefInvalid`
57
+ * an environment ref IS a capability-layer ref, so call sites that already
58
+ * branch on `CapabilityRefInvalid` handle it uniformly. The subclass `name`
59
+ * (`ExecutionEnvironmentRefParseError`) distinguishes it for diagnostics.
60
60
  */
61
61
  export class ExecutionEnvironmentRefParseError extends CapabilityError {
62
62
  constructor(args: { message: string; raw: string }) {
@@ -69,9 +69,6 @@ export class ExecutionEnvironmentRefParseError extends CapabilityError {
69
69
  }
70
70
  }
71
71
 
72
- /** Stable wire code for `ExecutionEnvironmentRefParseError`. */
73
- export const EXECUTION_ENVIRONMENT_REF_INVALID = 'EXECUTION_ENVIRONMENT_REF_INVALID';
74
-
75
72
  /**
76
73
  * Parse an `ExecutionEnvironmentRef` string into its structured parts.
77
74
  * Throws `ExecutionEnvironmentRefParseError` on any grammar violation —
@@ -19,8 +19,8 @@ export enum XemaObjectKind {
19
19
  ExternalSubject = 'external-subject',
20
20
  DelegatedSession = 'delegated-session',
21
21
 
22
- // Agent runtime primitives a base kernel armed into an Agent
23
- AgentKernel = 'agent-kernel',
22
+ // Agent runtime primitives. A "kernel" is just an Agent with no subagents —
23
+ // there is no separate AgentKernel object kind (unified-Agent model).
24
24
  Agent = 'agent',
25
25
  Skill = 'skill',
26
26
  Tool = 'tool',
@@ -106,10 +106,30 @@ function parseScope(segments: string[], ref: string): ScopeParse {
106
106
  consumed: 2,
107
107
  };
108
108
  }
109
+ case 'sessions': {
110
+ const sessionId = requireSegment(segments, 1, ref, 'sessionId');
111
+ return {
112
+ scope: { tier: SpaceKind.Session, sessionId },
113
+ consumed: 2,
114
+ };
115
+ }
109
116
  case 'orgs': {
110
117
  const orgId = requireSegment(segments, 1, ref, 'orgId');
111
118
  if (segments.length >= 4 && segments[2] === 'projects') {
112
119
  const projectId = requireSegment(segments, 3, ref, 'projectId');
120
+ // …/projects/<p>/apps/<a> — the App tier (most specific under a project).
121
+ if (segments.length >= 6 && segments[4] === 'apps') {
122
+ const appId = requireSegment(segments, 5, ref, 'appId');
123
+ return {
124
+ scope: {
125
+ tier: SpaceKind.App,
126
+ orgId,
127
+ projectId,
128
+ appId,
129
+ },
130
+ consumed: 6,
131
+ };
132
+ }
113
133
  return {
114
134
  scope: {
115
135
  tier: SpaceKind.Project,
@@ -127,7 +147,7 @@ function parseScope(segments: string[], ref: string): ScopeParse {
127
147
  default:
128
148
  throw new XemaObjectRefParseError(
129
149
  ref,
130
- `unknown scope head "${head}" (expected one of: system, biomes, orgs, users)`,
150
+ `unknown scope head "${head}" (expected one of: system, biomes, orgs, users, sessions)`,
131
151
  );
132
152
  }
133
153
  }
@@ -36,11 +36,11 @@ export const PolicyObligationKindSchema = z.nativeEnum(PolicyObligationKind);
36
36
  * (`require-runner-kind`) and by `RouteHint.preferredRunnerKind` (plan
37
37
  * v4.3 §2 / §A.4).
38
38
  *
39
- * This is the POLICY view of a runner — the dimension policy selects on
40
- * to route an invocation. Phase F will unify this with the transport-
41
- * level `RunnerKind` in `@xemahq/runner-contracts`
42
- * (Embedded/LocalModule/Remote/McpExternal); for Phase A this enum lives
43
- * inline in `@xemahq/policy-contracts` per the plan.
39
+ * This is the canonical `RunnerKind` — the policy decision layer is its
40
+ * primary author (policy selects on it to route an invocation), so it lives
41
+ * in the `policy` surface. The `runner` surface re-exports it
42
+ * (`runner/lib/runner-kind.ts`) so runner-side consumers get a single source
43
+ * of truth with no second declaration to drift against.
44
44
  */
45
45
  export enum RunnerKind {
46
46
  Local = 'local',
@@ -1,10 +1,12 @@
1
1
  // ═══════════════════════════════════════════════════════════════════════════
2
2
  // ── Reference Resolution — graceful-degradation decision (DBM.1) ──
3
3
  //
4
- // The ONE shared contract every resolver uses when it walks a definition's
4
+ // The shared contract a resolver SHOULD use when it walks a definition's
5
5
  // declared references (an Agent node's `agentRef`, a skill's sub-skill, an
6
6
  // action's capability, a workflow's `uses:`) and asks "is this reference
7
- // available right now, and what do I do if it isn't?".
7
+ // available right now, and what do I do if it isn't?". This is the Layer-0
8
+ // vocabulary for DBM.1; the per-resolver wiring is rolled out incrementally,
9
+ // so not every resolver consumes it yet.
8
10
  //
9
11
  // It exists because of DYNAMIC BIOME MODULARITY: a definition authored while
10
12
  // biome X was installed keeps referencing X's contributions after X is
@@ -8,4 +8,3 @@ export * from './lib/runner-registration';
8
8
  export * from './lib/runner-plane';
9
9
  export * from './lib/runner-job';
10
10
  export * from './lib/dispatch';
11
- export * from './lib/input-hash';
@@ -0,0 +1 @@
1
+ export * from './lib/input-hash';
@@ -24,6 +24,13 @@ import { createHash } from 'node:crypto';
24
24
  * - arrays preserve order;
25
25
  * - non-JSON values (`bigint`, `function`, `symbol`, non-finite numbers)
26
26
  * are rejected — capability input is JSON, never a host object.
27
+ *
28
+ * NOTE: this is the ONE module in `@xemahq/kernel-contracts` that depends on
29
+ * a Node built-in (`node:crypto`). It lives in its own `runner-input-hash`
30
+ * subpath — separate from the `runner` contract barrel — so the rest of the
31
+ * package stays isomorphic and browser-bundleable. Server-only consumers
32
+ * (router gateway, runner verifier, kernel-server) import it from
33
+ * `@xemahq/kernel-contracts/runner-input-hash`.
27
34
  */
28
35
  export function canonicalCapabilityInputHash(input: unknown): string {
29
36
  const canonical = canonicalize(input === undefined ? {} : input);
@@ -47,16 +47,6 @@ export function isSearchReplayCapabilityRef(ref: string): boolean {
47
47
  return SEARCH_REPLAY_REF_REGEX.test(ref);
48
48
  }
49
49
 
50
- /**
51
- * Extract the `sourceKey` (domain segment) from a replay capability ref, or
52
- * `null` when `ref` is not a replay ref. Used by the capability-router to map
53
- * a replay ref to the owning source's HTTP endpoint.
54
- */
55
- export function searchSourceKeyFromReplayRef(ref: string): string | null {
56
- const match = SEARCH_REPLAY_REF_REGEX.exec(ref);
57
- return match?.[1] ?? null;
58
- }
59
-
60
50
  /**
61
51
  * Backfill request search sends to a source's replay capability (via
62
52
  * capability-router — NOT a direct client call). Paginated so a large source
@@ -25,8 +25,10 @@ export const ServiceName = {
25
25
  BIOME_HOST_API: 'biome-host-api',
26
26
  CAPABILITY_REGISTRY_API: 'capability-registry-api',
27
27
  CATALOG_API: 'catalog-api',
28
+ CHANNEL_GATEWAY_API: 'channel-gateway-api',
28
29
  CONNECTOR_GATEWAY_API: 'connector-gateway-api',
29
30
  CONTAINER_REGISTRY_API: 'container-registry-api',
31
+ CONTROL_PLANE_API: 'control-plane-api',
30
32
  CREDENTIAL_BROKER_API: 'credential-broker-api',
31
33
  DELIVERABLE_SPECS_API: 'deliverable-specs-api',
32
34
  DESIGN_SYSTEM_BUILDER_API: 'design-system-builder-api',
@@ -53,6 +55,7 @@ export const ServiceName = {
53
55
  WORKFLOW_RUNTIME_WORKER: 'workflow-runtime-worker',
54
56
  WORKLOAD_RUNTIME_API: 'workload-runtime-api',
55
57
  WORKSPACE_GIT_API: 'workspace-git-api',
58
+ WORKSPACE_MATERIALIZATION_API: 'workspace-materialization-api',
56
59
  WORKSPACE_ORCHESTRATOR_API: 'workspace-orchestrator-api',
57
60
  WORKSPACE_PROXY: 'workspace-proxy',
58
61
  WORKSPACE_STORAGE_POOL_API: 'workspace-storage-pool-api',
@@ -38,8 +38,6 @@ export * from './lib/domain-tag';
38
38
  // hierarchy, and gate-reviewer map were relocated to the software-dev biome
39
39
  // (`biomes/platform/software-dev/workflow-config/phase-config.json`) — the
40
40
  // kernel carries no domain phase enum.
41
- export * from './lib/workflow-stage';
42
41
  export * from './lib/phase-report';
43
42
  export * from './lib/work-item-payloads';
44
- export * from './lib/sampling-profiles';
45
43
  export * from './lib/canonical-concepts';
@@ -14,6 +14,8 @@
14
14
  // Resource types use "group/name" notation (e.g. "database/postgresql").
15
15
  // ═══════════════════════════════════════════════════════════════════════════
16
16
 
17
+ import { COMPLEXITY_TIERS, type ComplexityTier } from './phase-report';
18
+
17
19
  // ── Common Interfaces ──────────────────────────────────────────────────
18
20
 
19
21
  /**
@@ -129,42 +131,46 @@ export const ITEM_TYPE_VALUES = ITEM_TYPE_CATALOG.map((t) => t.value);
129
131
  export type ItemType = (typeof ITEM_TYPE_VALUES)[number];
130
132
 
131
133
  // ── Complexity Tiers ───────────────────────────────────────────────────
132
- // Used by: pipeline runs, doc-template matching, agent model selection
133
- // NOTE: COMPLEXITY_TIERS and ComplexityTier are also in phase-report.ts
134
- // for backward compat. This is the canonical rich definition.
135
-
136
- export const COMPLEXITY_CATALOG: CatalogEntry[] = [
137
- {
138
- value: 'simple',
134
+ // Used by: pipeline runs, doc-template matching, agent model selection.
135
+ //
136
+ // SINGLE SOURCE OF TRUTH for the value set is `COMPLEXITY_TIERS` /
137
+ // `ComplexityTier` in ./phase-report. This catalog only layers presentation
138
+ // metadata (label/hint/color/sortOrder) keyed by `ComplexityTier`, so adding
139
+ // or removing a tier in phase-report makes this a COMPILE error rather than a
140
+ // silent drift between the two definitions.
141
+ const COMPLEXITY_PRESENTATION: Record<
142
+ ComplexityTier,
143
+ Omit<CatalogEntry, 'value'>
144
+ > = {
145
+ simple: {
139
146
  label: 'Simple',
140
147
  hint: 'Single service, few files, straightforward logic. ~1-3 day effort.',
141
148
  color: 'bg-green-100 text-green-700',
142
149
  sortOrder: 0,
143
150
  },
144
- {
145
- value: 'standard',
151
+ standard: {
146
152
  label: 'Standard',
147
153
  hint: 'Multi-file changes within 1-2 services. Moderate complexity. ~3-7 day effort.',
148
154
  color: 'bg-blue-100 text-blue-700',
149
155
  sortOrder: 1,
150
156
  },
151
- {
152
- value: 'complex',
157
+ complex: {
153
158
  label: 'Complex',
154
159
  hint: 'Multi-service changes, new APIs, database migrations. ~1-3 week effort.',
155
160
  color: 'bg-orange-100 text-orange-700',
156
161
  sortOrder: 2,
157
162
  },
158
- {
159
- value: 'enterprise',
163
+ enterprise: {
160
164
  label: 'Enterprise',
161
165
  hint: 'Cross-system integration, new microservices, major architectural changes. ~1+ month effort.',
162
166
  color: 'bg-red-100 text-red-700',
163
167
  sortOrder: 3,
164
168
  },
165
- ];
169
+ };
166
170
 
167
- export const COMPLEXITY_VALUES = COMPLEXITY_CATALOG.map((c) => c.value);
171
+ export const COMPLEXITY_CATALOG: CatalogEntry[] = COMPLEXITY_TIERS.map(
172
+ (value) => ({ value, ...COMPLEXITY_PRESENTATION[value] }),
173
+ );
168
174
 
169
175
  // ── Status Definitions ─────────────────────────────────────────────────
170
176
  // Used by: backlog items