@xemahq/agent-session-runtime 0.6.7 → 0.8.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 (48) hide show
  1. package/README.md +6 -1
  2. package/dist/index.d.ts +1 -0
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +1 -0
  5. package/dist/index.js.map +1 -1
  6. package/dist/lib/agent-resolution.d.ts.map +1 -1
  7. package/dist/lib/agent-resolution.js.map +1 -1
  8. package/dist/lib/dispatch-contract.d.ts +2 -1
  9. package/dist/lib/dispatch-contract.d.ts.map +1 -1
  10. package/dist/lib/launch-identity/canonical-contract.d.ts +22 -0
  11. package/dist/lib/launch-identity/canonical-contract.d.ts.map +1 -0
  12. package/dist/lib/launch-identity/canonical-contract.js +229 -0
  13. package/dist/lib/launch-identity/canonical-contract.js.map +1 -0
  14. package/dist/lib/launch-identity/compiled-session-launch-plan-store.d.ts +44 -0
  15. package/dist/lib/launch-identity/compiled-session-launch-plan-store.d.ts.map +1 -0
  16. package/dist/lib/launch-identity/compiled-session-launch-plan-store.js +116 -0
  17. package/dist/lib/launch-identity/compiled-session-launch-plan-store.js.map +1 -0
  18. package/dist/lib/launch-identity/compiled-session-launch-plan.d.ts +84 -0
  19. package/dist/lib/launch-identity/compiled-session-launch-plan.d.ts.map +1 -0
  20. package/dist/lib/launch-identity/compiled-session-launch-plan.js +382 -0
  21. package/dist/lib/launch-identity/compiled-session-launch-plan.js.map +1 -0
  22. package/dist/lib/launch-identity/index.d.ts +7 -0
  23. package/dist/lib/launch-identity/index.d.ts.map +1 -0
  24. package/dist/lib/launch-identity/index.js +23 -0
  25. package/dist/lib/launch-identity/index.js.map +1 -0
  26. package/dist/lib/launch-identity/runtime-template-key.d.ts +30 -0
  27. package/dist/lib/launch-identity/runtime-template-key.d.ts.map +1 -0
  28. package/dist/lib/launch-identity/runtime-template-key.js +69 -0
  29. package/dist/lib/launch-identity/runtime-template-key.js.map +1 -0
  30. package/dist/lib/launch-identity/session-binding.d.ts +24 -0
  31. package/dist/lib/launch-identity/session-binding.d.ts.map +1 -0
  32. package/dist/lib/launch-identity/session-binding.js +62 -0
  33. package/dist/lib/launch-identity/session-binding.js.map +1 -0
  34. package/dist/lib/launch-identity/thread-reuse-key.d.ts +19 -0
  35. package/dist/lib/launch-identity/thread-reuse-key.d.ts.map +1 -0
  36. package/dist/lib/launch-identity/thread-reuse-key.js +46 -0
  37. package/dist/lib/launch-identity/thread-reuse-key.js.map +1 -0
  38. package/package.json +7 -5
  39. package/src/index.ts +1 -0
  40. package/src/lib/agent-resolution.ts +15 -4
  41. package/src/lib/dispatch-contract.ts +4 -9
  42. package/src/lib/launch-identity/canonical-contract.ts +352 -0
  43. package/src/lib/launch-identity/compiled-session-launch-plan-store.ts +178 -0
  44. package/src/lib/launch-identity/compiled-session-launch-plan.ts +681 -0
  45. package/src/lib/launch-identity/index.ts +6 -0
  46. package/src/lib/launch-identity/runtime-template-key.ts +143 -0
  47. package/src/lib/launch-identity/session-binding.ts +152 -0
  48. package/src/lib/launch-identity/thread-reuse-key.ts +93 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-template-key.js","sourceRoot":"","sources":["../../../src/lib/launch-identity/runtime-template-key.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import { type CanonicalJsonValue, type ResourceBindingRef } from './canonical-contract';
2
+ export interface SessionBinding {
3
+ readonly schemaVersion: 1;
4
+ readonly sessionId: string;
5
+ readonly organizationId: string;
6
+ readonly projectId: string;
7
+ readonly userId: string;
8
+ readonly domainRefs: readonly ResourceBindingRef[];
9
+ readonly storageAllocationRef: string;
10
+ readonly workingFileSourceRefs: readonly string[];
11
+ readonly outputRouteRef: string;
12
+ readonly actorTokenRef?: string;
13
+ readonly serviceTokenRef?: string;
14
+ readonly providerTokenRefs: readonly string[];
15
+ readonly credentialGrantRefs: readonly string[];
16
+ readonly databaseGrantRefs: readonly string[];
17
+ readonly dynamicContext: Readonly<Record<string, CanonicalJsonValue>>;
18
+ readonly bindingRevision: string;
19
+ readonly bindingEpoch: number;
20
+ }
21
+ export declare function createSessionBinding(input: unknown): SessionBinding;
22
+ export declare function serializeSessionBinding(input: SessionBinding): string;
23
+ export declare function hashSessionBinding(input: SessionBinding): string;
24
+ //# sourceMappingURL=session-binding.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-binding.d.ts","sourceRoot":"","sources":["../../../src/lib/launch-identity/session-binding.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,kBAAkB,EAEvB,KAAK,kBAAkB,EAOxB,MAAM,sBAAsB,CAAC;AAE9B,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,aAAa,EAAE,CAAC,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,EAAE,SAAS,kBAAkB,EAAE,CAAC;IACnD,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,qBAAqB,EAAE,SAAS,MAAM,EAAE,CAAC;IAClD,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,iBAAiB,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9C,QAAQ,CAAC,mBAAmB,EAAE,SAAS,MAAM,EAAE,CAAC;IAChD,QAAQ,CAAC,iBAAiB,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9C,QAAQ,CAAC,cAAc,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC,CAAC;IACtE,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AA2BD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,cAAc,CAqFnE;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAErE;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAEhE"}
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createSessionBinding = createSessionBinding;
4
+ exports.serializeSessionBinding = serializeSessionBinding;
5
+ exports.hashSessionBinding = hashSessionBinding;
6
+ const canonical_contract_1 = require("./canonical-contract");
7
+ const REQUIRED_KEYS = [
8
+ 'schemaVersion',
9
+ 'sessionId',
10
+ 'organizationId',
11
+ 'projectId',
12
+ 'userId',
13
+ 'domainRefs',
14
+ 'storageAllocationRef',
15
+ 'workingFileSourceRefs',
16
+ 'outputRouteRef',
17
+ 'providerTokenRefs',
18
+ 'credentialGrantRefs',
19
+ 'databaseGrantRefs',
20
+ 'dynamicContext',
21
+ 'bindingRevision',
22
+ 'bindingEpoch',
23
+ ];
24
+ const OPTIONAL_KEYS = ['actorTokenRef', 'serviceTokenRef'];
25
+ function createSessionBinding(input) {
26
+ const object = (0, canonical_contract_1.requireExactObject)(input, 'SessionBinding', REQUIRED_KEYS, OPTIONAL_KEYS);
27
+ if (object.schemaVersion !== 1) {
28
+ throw new TypeError('SessionBinding.schemaVersion must be 1.');
29
+ }
30
+ const actorTokenRef = object.actorTokenRef === undefined
31
+ ? undefined
32
+ : (0, canonical_contract_1.requireNonEmptyString)(object.actorTokenRef, 'SessionBinding.actorTokenRef');
33
+ const serviceTokenRef = object.serviceTokenRef === undefined
34
+ ? undefined
35
+ : (0, canonical_contract_1.requireNonEmptyString)(object.serviceTokenRef, 'SessionBinding.serviceTokenRef');
36
+ return Object.freeze({
37
+ schemaVersion: 1,
38
+ sessionId: (0, canonical_contract_1.requireNonEmptyString)(object.sessionId, 'SessionBinding.sessionId'),
39
+ organizationId: (0, canonical_contract_1.requireNonEmptyString)(object.organizationId, 'SessionBinding.organizationId'),
40
+ projectId: (0, canonical_contract_1.requireNonEmptyString)(object.projectId, 'SessionBinding.projectId'),
41
+ userId: (0, canonical_contract_1.requireNonEmptyString)(object.userId, 'SessionBinding.userId'),
42
+ domainRefs: (0, canonical_contract_1.requireResourceBindingRefs)(object.domainRefs, 'SessionBinding.domainRefs'),
43
+ storageAllocationRef: (0, canonical_contract_1.requireNonEmptyString)(object.storageAllocationRef, 'SessionBinding.storageAllocationRef'),
44
+ workingFileSourceRefs: (0, canonical_contract_1.requireStringRefs)(object.workingFileSourceRefs, 'SessionBinding.workingFileSourceRefs'),
45
+ outputRouteRef: (0, canonical_contract_1.requireNonEmptyString)(object.outputRouteRef, 'SessionBinding.outputRouteRef'),
46
+ ...(actorTokenRef === undefined ? {} : { actorTokenRef }),
47
+ ...(serviceTokenRef === undefined ? {} : { serviceTokenRef }),
48
+ providerTokenRefs: (0, canonical_contract_1.requireStringRefs)(object.providerTokenRefs, 'SessionBinding.providerTokenRefs'),
49
+ credentialGrantRefs: (0, canonical_contract_1.requireStringRefs)(object.credentialGrantRefs, 'SessionBinding.credentialGrantRefs'),
50
+ databaseGrantRefs: (0, canonical_contract_1.requireStringRefs)(object.databaseGrantRefs, 'SessionBinding.databaseGrantRefs'),
51
+ dynamicContext: (0, canonical_contract_1.requireSecretFreeJsonObject)(object.dynamicContext, 'SessionBinding.dynamicContext'),
52
+ bindingRevision: (0, canonical_contract_1.requireNonEmptyString)(object.bindingRevision, 'SessionBinding.bindingRevision'),
53
+ bindingEpoch: (0, canonical_contract_1.requireNonNegativeSafeInteger)(object.bindingEpoch, 'SessionBinding.bindingEpoch'),
54
+ });
55
+ }
56
+ function serializeSessionBinding(input) {
57
+ return (0, canonical_contract_1.canonicalContractJson)(createSessionBinding(input));
58
+ }
59
+ function hashSessionBinding(input) {
60
+ return (0, canonical_contract_1.hashCanonicalContract)(createSessionBinding(input));
61
+ }
62
+ //# sourceMappingURL=session-binding.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-binding.js","sourceRoot":"","sources":["../../../src/lib/launch-identity/session-binding.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import { type ResourceBindingRef } from './canonical-contract';
2
+ export declare enum ThreadReusePolicy {
3
+ ExplicitlyShareable = "explicitly-shareable"
4
+ }
5
+ export interface ThreadReuseKey {
6
+ readonly schemaVersion: 1;
7
+ readonly reusePolicy: ThreadReusePolicy.ExplicitlyShareable;
8
+ readonly organizationId: string;
9
+ readonly projectId: string;
10
+ readonly userId: string;
11
+ readonly runtimeTemplateHash: string;
12
+ readonly conversationRef: string;
13
+ readonly workspaceRef: string;
14
+ readonly domainRefs: readonly ResourceBindingRef[];
15
+ }
16
+ export declare function createThreadReuseKey(input: unknown): ThreadReuseKey;
17
+ export declare function serializeThreadReuseKey(input: ThreadReuseKey): string;
18
+ export declare function hashThreadReuseKey(input: ThreadReuseKey): string;
19
+ //# sourceMappingURL=thread-reuse-key.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"thread-reuse-key.d.ts","sourceRoot":"","sources":["../../../src/lib/launch-identity/thread-reuse-key.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,kBAAkB,EAMxB,MAAM,sBAAsB,CAAC;AAE9B,oBAAY,iBAAiB;IAC3B,mBAAmB,yBAAyB;CAC7C;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,aAAa,EAAE,CAAC,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,iBAAiB,CAAC,mBAAmB,CAAC;IAC5D,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,SAAS,kBAAkB,EAAE,CAAC;CACpD;AAmBD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,cAAc,CAwCnE;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAErE;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAEhE"}
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ThreadReusePolicy = void 0;
4
+ exports.createThreadReuseKey = createThreadReuseKey;
5
+ exports.serializeThreadReuseKey = serializeThreadReuseKey;
6
+ exports.hashThreadReuseKey = hashThreadReuseKey;
7
+ const canonical_contract_1 = require("./canonical-contract");
8
+ var ThreadReusePolicy;
9
+ (function (ThreadReusePolicy) {
10
+ ThreadReusePolicy["ExplicitlyShareable"] = "explicitly-shareable";
11
+ })(ThreadReusePolicy || (exports.ThreadReusePolicy = ThreadReusePolicy = {}));
12
+ const REQUIRED_KEYS = [
13
+ 'schemaVersion',
14
+ 'reusePolicy',
15
+ 'organizationId',
16
+ 'projectId',
17
+ 'userId',
18
+ 'runtimeTemplateHash',
19
+ 'conversationRef',
20
+ 'workspaceRef',
21
+ 'domainRefs',
22
+ ];
23
+ function createThreadReuseKey(input) {
24
+ const object = (0, canonical_contract_1.requireExactObject)(input, 'ThreadReuseKey', REQUIRED_KEYS);
25
+ if (object.schemaVersion !== 1) {
26
+ throw new TypeError('ThreadReuseKey.schemaVersion must be 1.');
27
+ }
28
+ return Object.freeze({
29
+ schemaVersion: 1,
30
+ reusePolicy: (0, canonical_contract_1.requireEnumValue)(object.reusePolicy, 'ThreadReuseKey.reusePolicy', [ThreadReusePolicy.ExplicitlyShareable]),
31
+ organizationId: (0, canonical_contract_1.requireNonEmptyString)(object.organizationId, 'ThreadReuseKey.organizationId'),
32
+ projectId: (0, canonical_contract_1.requireNonEmptyString)(object.projectId, 'ThreadReuseKey.projectId'),
33
+ userId: (0, canonical_contract_1.requireNonEmptyString)(object.userId, 'ThreadReuseKey.userId'),
34
+ runtimeTemplateHash: (0, canonical_contract_1.requireSha256)(object.runtimeTemplateHash, 'ThreadReuseKey.runtimeTemplateHash'),
35
+ conversationRef: (0, canonical_contract_1.requireNonEmptyString)(object.conversationRef, 'ThreadReuseKey.conversationRef'),
36
+ workspaceRef: (0, canonical_contract_1.requireNonEmptyString)(object.workspaceRef, 'ThreadReuseKey.workspaceRef'),
37
+ domainRefs: (0, canonical_contract_1.requireResourceBindingRefs)(object.domainRefs, 'ThreadReuseKey.domainRefs'),
38
+ });
39
+ }
40
+ function serializeThreadReuseKey(input) {
41
+ return (0, canonical_contract_1.canonicalContractJson)(createThreadReuseKey(input));
42
+ }
43
+ function hashThreadReuseKey(input) {
44
+ return (0, canonical_contract_1.hashCanonicalContract)(createThreadReuseKey(input));
45
+ }
46
+ //# sourceMappingURL=thread-reuse-key.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"thread-reuse-key.js","sourceRoot":"","sources":["../../../src/lib/launch-identity/thread-reuse-key.ts"],"names":[],"mappings":";;;AA4CA,oDAwCC;AAED,0DAEC;AAED,gDAEC;AA5FD,6DAS8B;AAE9B,IAAY,iBAEX;AAFD,WAAY,iBAAiB;IAC3B,iEAA4C,CAAA;AAC9C,CAAC,EAFW,iBAAiB,iCAAjB,iBAAiB,QAE5B;AAcD,MAAM,aAAa,GAAG;IACpB,eAAe;IACf,aAAa;IACb,gBAAgB;IAChB,WAAW;IACX,QAAQ;IACR,qBAAqB;IACrB,iBAAiB;IACjB,cAAc;IACd,YAAY;CACJ,CAAC;AAOX,SAAgB,oBAAoB,CAAC,KAAc;IACjD,MAAM,MAAM,GAAG,IAAA,uCAAkB,EAAC,KAAK,EAAE,gBAAgB,EAAE,aAAa,CAAC,CAAC;IAE1E,IAAI,MAAM,CAAC,aAAa,KAAK,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,SAAS,CAAC,yCAAyC,CAAC,CAAC;IACjE,CAAC;IAED,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,aAAa,EAAE,CAAC;QAChB,WAAW,EAAE,IAAA,qCAAgB,EAC3B,MAAM,CAAC,WAAW,EAClB,4BAA4B,EAC5B,CAAC,iBAAiB,CAAC,mBAAmB,CAAC,CACxC;QACD,cAAc,EAAE,IAAA,0CAAqB,EACnC,MAAM,CAAC,cAAc,EACrB,+BAA+B,CAChC;QACD,SAAS,EAAE,IAAA,0CAAqB,EAC9B,MAAM,CAAC,SAAS,EAChB,0BAA0B,CAC3B;QACD,MAAM,EAAE,IAAA,0CAAqB,EAAC,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC;QACrE,mBAAmB,EAAE,IAAA,kCAAa,EAChC,MAAM,CAAC,mBAAmB,EAC1B,oCAAoC,CACrC;QACD,eAAe,EAAE,IAAA,0CAAqB,EACpC,MAAM,CAAC,eAAe,EACtB,gCAAgC,CACjC;QACD,YAAY,EAAE,IAAA,0CAAqB,EACjC,MAAM,CAAC,YAAY,EACnB,6BAA6B,CAC9B;QACD,UAAU,EAAE,IAAA,+CAA0B,EACpC,MAAM,CAAC,UAAU,EACjB,2BAA2B,CAC5B;KACF,CAAC,CAAC;AACL,CAAC;AAED,SAAgB,uBAAuB,CAAC,KAAqB;IAC3D,OAAO,IAAA,0CAAqB,EAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC,CAAC;AAC5D,CAAC;AAED,SAAgB,kBAAkB,CAAC,KAAqB;IACtD,OAAO,IAAA,0CAAqB,EAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC,CAAC;AAC5D,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xemahq/agent-session-runtime",
3
- "version": "0.6.7",
3
+ "version": "0.8.0",
4
4
  "description": "Runtime for composing and running Xema agent sessions — workspace manifests, skill bundles, environment resolution, and drift detection.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Neuralchowder Inc. <developer@xema.dev> (https://xema.dev)",
@@ -45,14 +45,16 @@
45
45
  "prettier": "3.6.2",
46
46
  "ts-jest": "^29.4.9",
47
47
  "typescript": "5.9.3",
48
- "@xemahq/kernel-contracts": "^0.58.0"
48
+ "@xemahq/dsl": "^0.6.1",
49
+ "@xemahq/kernel-contracts": "^1.0.0"
49
50
  },
50
51
  "dependencies": {
51
- "@xemahq/dsl": "^0.6.1",
52
- "@xemahq/kernel-contracts": "^0.58.0"
52
+ "@xemahq/declarative-reconciler": "^0.1.1",
53
+ "@xemahq/kernel-contracts": "^1.0.0"
53
54
  },
54
55
  "peerDependencies": {
55
- "@xemahq/kernel-contracts": ">=0.13.0"
56
+ "@xemahq/dsl": ">=0.6.1",
57
+ "@xemahq/kernel-contracts": ">=1.0.0"
56
58
  },
57
59
  "scripts": {
58
60
  "clean": "rm -rf dist",
package/src/index.ts CHANGED
@@ -33,3 +33,4 @@ export * from './lib/environment-resolver';
33
33
  export * from './lib/drift-detector';
34
34
  export * from './lib/lifecycle-state';
35
35
  export * from './lib/dispatch-contract';
36
+ export * from './lib/launch-identity';
@@ -97,10 +97,21 @@ export interface RuntimeAgentConfig {
97
97
  /** Root instructions (+ overlay), normalized; `null` when none. */
98
98
  readonly primaryInstructions: string | null;
99
99
  /**
100
- * How `primaryInstructions` combine with the base kernel's `systemPrompt`
101
- * (the root node's `promptMode`). `null` ⇒ Append (back-compat). `Replace`
102
- * makes `primaryInstructions` the system prompt; the base kernel prompt body
103
- * is dropped (config still inherited). The session overlay always appends.
100
+ * The root node's `promptMode`, carried VERBATIM — `null` means the node
101
+ * DECLARED none, not "defaulted to something here".
102
+ *
103
+ * `NodeOverlayFragment.promptMode` is optional in the kernel contract, so an
104
+ * absent mode is a legal, meaningful state and this projection does NOT
105
+ * resolve it: every consumer spreads the field conditionally
106
+ * (`...(primaryPromptMode ? { promptMode } : {})`), so `null` propagates as
107
+ * "field omitted" and the closed-set default is applied ONCE, at the point
108
+ * that materializes the prompt. Restating the default rule here would be a
109
+ * second source of truth for it; fail-fast would be wrong because "omitted"
110
+ * is contractually valid.
111
+ *
112
+ * `Replace` makes `primaryInstructions` the system prompt; the base agent
113
+ * prompt body is dropped (config still inherited). The session overlay
114
+ * always appends.
104
115
  */
105
116
  readonly primaryPromptMode: PromptMergeMode | null;
106
117
  /** Root permission (+ overlay); `null` when none. */
@@ -83,15 +83,10 @@ export interface CreateAndRunDispatch {
83
83
  readonly jobRunId: string;
84
84
  /** Stable spine identity within the workflow run. */
85
85
  readonly jobKey: string;
86
- /**
87
- * Agent ref (`slug` = latest published, or `slug@version`)
88
- * the new pipeline-owned session should bootstrap from. The dispatch
89
- * service stamps this onto `Session.agentRef`; the session
90
- * lifecycle resolves it via llm-registry-api's `GET /compositions/
91
- * resolve/:ref` for both the agent/skill/tool tree and the workspace
92
- * mount layout.
93
- */
94
- readonly agentRef: string;
86
+ /** Immutable AgentRevision selected by workflow resolution. */
87
+ readonly agentRevisionId: string;
88
+ /** SHA-256 of the selected AgentRevision content. */
89
+ readonly agentContentHash: string;
95
90
  readonly agentSlug: string;
96
91
  readonly promptContext: DispatchPromptContext;
97
92
  }
@@ -0,0 +1,352 @@
1
+ import { canonicalJson, stableHash } from '@xemahq/declarative-reconciler';
2
+ import { Sha256HexSchema } from '@xemahq/kernel-contracts/content-address';
3
+
4
+ export type CanonicalJsonValue =
5
+ | boolean
6
+ | number
7
+ | string
8
+ | null
9
+ | readonly CanonicalJsonValue[]
10
+ | { readonly [key: string]: CanonicalJsonValue };
11
+
12
+ export interface ResourceBindingRef {
13
+ readonly kind: string;
14
+ readonly ref: string;
15
+ }
16
+
17
+ /**
18
+ * OCI immutable-digest prefix. The digest BODY is validated by the canonical
19
+ * {@link Sha256HexSchema} rather than a local `[a-f0-9]{64}` copy, so this
20
+ * package holds no SHA-256 grammar of its own.
21
+ */
22
+ const IMAGE_DIGEST_PREFIX = 'sha256:';
23
+
24
+ const SECRET_FIELD_PATTERN =
25
+ /(?:^|[_-])(api[_-]?key|authorization|cookie|credential|password|private[_-]?key|secret|token)(?:$|[_-])/iu;
26
+ const SECRET_CAMEL_CASE_PATTERN =
27
+ /(?:apiKey|authorization|cookie|credential|password|privateKey|secret|token)/u;
28
+ const SECRET_REFERENCE_SUFFIX_PATTERN = /Refs?$/u;
29
+
30
+ export function canonicalContractJson(value: unknown): string {
31
+ return canonicalJson(value);
32
+ }
33
+
34
+ export function hashCanonicalContract(value: unknown): string {
35
+ return stableHash(value);
36
+ }
37
+
38
+ export function requireExactObject(
39
+ value: unknown,
40
+ path: string,
41
+ requiredKeys: readonly string[],
42
+ optionalKeys: readonly string[] = [],
43
+ ): Readonly<Record<string, unknown>> {
44
+ if (!isPlainObject(value)) {
45
+ throw new TypeError(`${path} must be a plain object.`);
46
+ }
47
+
48
+ const allowedKeys = new Set([...requiredKeys, ...optionalKeys]);
49
+ for (const key of Object.keys(value)) {
50
+ if (!allowedKeys.has(key)) {
51
+ throw new TypeError(`${path}.${key} is not a supported field.`);
52
+ }
53
+ }
54
+
55
+ for (const key of requiredKeys) {
56
+ if (!Object.hasOwn(value, key)) {
57
+ throw new TypeError(`${path}.${key} is required.`);
58
+ }
59
+ }
60
+
61
+ return value;
62
+ }
63
+
64
+ export function requireNonEmptyString(value: unknown, path: string): string {
65
+ if (typeof value !== 'string' || value.trim().length === 0) {
66
+ throw new TypeError(`${path} must be a non-empty string.`);
67
+ }
68
+ return value;
69
+ }
70
+
71
+ export function requireBoolean(value: unknown, path: string): boolean {
72
+ if (typeof value !== 'boolean') {
73
+ throw new TypeError(`${path} must be a boolean.`);
74
+ }
75
+ return value;
76
+ }
77
+
78
+ export function requireSha256(value: unknown, path: string): string {
79
+ const hash = requireNonEmptyString(value, path);
80
+ if (!Sha256HexSchema.safeParse(hash).success) {
81
+ throw new TypeError(`${path} must be a lowercase SHA-256 hex digest.`);
82
+ }
83
+ return hash;
84
+ }
85
+
86
+ /**
87
+ * Validates an OCI IMMUTABLE image reference — `sha256:<64 lowercase hex>`.
88
+ *
89
+ * The single site for this rule. It was previously spelled as an identical
90
+ * `IMAGE_DIGEST_PATTERN` regex in both `runtime-template-key.ts` and
91
+ * `compiled-session-launch-plan.ts`; two copies of a security-relevant
92
+ * "is this reference immutable" check can drift, and each was also a private
93
+ * restatement of the SHA-256 grammar that `@xemahq/kernel-contracts
94
+ * /content-address` now owns canonically.
95
+ */
96
+ export function requireImageDigest(value: unknown, path: string): string {
97
+ const digest = requireNonEmptyString(value, path);
98
+ if (!digest.startsWith(IMAGE_DIGEST_PREFIX)) {
99
+ throw new TypeError(
100
+ `${path} must be an immutable sha256 image digest.`,
101
+ );
102
+ }
103
+ if (
104
+ !Sha256HexSchema.safeParse(digest.slice(IMAGE_DIGEST_PREFIX.length)).success
105
+ ) {
106
+ throw new TypeError(
107
+ `${path} must be an immutable sha256 image digest.`,
108
+ );
109
+ }
110
+ return digest;
111
+ }
112
+
113
+ export function requireNonNegativeSafeInteger(
114
+ value: unknown,
115
+ path: string,
116
+ ): number {
117
+ if (!Number.isSafeInteger(value) || (value as number) < 0) {
118
+ throw new TypeError(`${path} must be a non-negative safe integer.`);
119
+ }
120
+ return value as number;
121
+ }
122
+
123
+ export function requireEnumValue<T extends string>(
124
+ value: unknown,
125
+ path: string,
126
+ values: readonly T[],
127
+ ): T {
128
+ if (typeof value !== 'string' || !values.includes(value as T)) {
129
+ throw new TypeError(
130
+ `${path} must be one of: ${values.map((entry) => `'${entry}'`).join(', ')}.`,
131
+ );
132
+ }
133
+ return value as T;
134
+ }
135
+
136
+ export function requireStringRefs(
137
+ value: unknown,
138
+ path: string,
139
+ ): readonly string[] {
140
+ if (!Array.isArray(value)) {
141
+ throw new TypeError(`${path} must be an array.`);
142
+ }
143
+
144
+ return Object.freeze(
145
+ [
146
+ ...new Set(
147
+ value.map((entry, index) =>
148
+ requireNonEmptyString(entry, `${path}[${index}]`),
149
+ ),
150
+ ),
151
+ ].sort(),
152
+ );
153
+ }
154
+
155
+ export function requireResourceBindingRefs(
156
+ value: unknown,
157
+ path: string,
158
+ ): readonly ResourceBindingRef[] {
159
+ if (!Array.isArray(value)) {
160
+ throw new TypeError(`${path} must be an array.`);
161
+ }
162
+
163
+ const refs = value.map((entry, index) => {
164
+ const entryPath = `${path}[${index}]`;
165
+ const object = requireExactObject(entry, entryPath, ['kind', 'ref']);
166
+ return Object.freeze({
167
+ kind: requireNonEmptyString(object.kind, `${entryPath}.kind`),
168
+ ref: requireNonEmptyString(object.ref, `${entryPath}.ref`),
169
+ });
170
+ });
171
+
172
+ const byCanonicalRef = new Map(
173
+ refs.map((entry) => [canonicalJson(entry), entry] as const),
174
+ );
175
+ return Object.freeze(
176
+ [...byCanonicalRef.entries()]
177
+ .sort(([left], [right]) => left.localeCompare(right))
178
+ .map(([, entry]) => entry),
179
+ );
180
+ }
181
+
182
+ export function requireSecretFreeJsonObject(
183
+ value: unknown,
184
+ path: string,
185
+ ): Readonly<Record<string, CanonicalJsonValue>> {
186
+ const normalized = normalizeCanonicalJson(value, path, true);
187
+ if (
188
+ normalized === null ||
189
+ Array.isArray(normalized) ||
190
+ typeof normalized !== 'object'
191
+ ) {
192
+ throw new TypeError(`${path} must be a plain JSON object.`);
193
+ }
194
+ return normalized as Readonly<Record<string, CanonicalJsonValue>>;
195
+ }
196
+
197
+ export function requireCanonicalJsonObject(
198
+ value: unknown,
199
+ path: string,
200
+ ): Readonly<Record<string, CanonicalJsonValue>> {
201
+ const normalized = normalizeCanonicalJson(value, path, false);
202
+ if (
203
+ normalized === null ||
204
+ Array.isArray(normalized) ||
205
+ typeof normalized !== 'object'
206
+ ) {
207
+ throw new TypeError(`${path} must be a plain JSON object.`);
208
+ }
209
+ return normalized as Readonly<Record<string, CanonicalJsonValue>>;
210
+ }
211
+
212
+ export function assertNoTenantOrSecretTemplateFields(
213
+ value: unknown,
214
+ path: string,
215
+ ): void {
216
+ const visited = new Set<object>();
217
+
218
+ function inspect(current: unknown, currentPath: string): void {
219
+ if (current === null || typeof current !== 'object') {
220
+ return;
221
+ }
222
+ if (visited.has(current)) {
223
+ throw new TypeError(`${currentPath} must not contain cycles.`);
224
+ }
225
+ visited.add(current);
226
+
227
+ if (Array.isArray(current)) {
228
+ current.forEach((entry, index) =>
229
+ inspect(entry, `${currentPath}[${index}]`),
230
+ );
231
+ return;
232
+ }
233
+ if (!isPlainObject(current)) {
234
+ throw new TypeError(`${currentPath} must contain only plain objects.`);
235
+ }
236
+
237
+ for (const [key, entry] of Object.entries(current)) {
238
+ if (isTenantField(key) || isSecretField(key)) {
239
+ throw new TypeError(
240
+ `${currentPath}.${key} is tenant/session/secret state and cannot enter a RuntimeTemplateKey.`,
241
+ );
242
+ }
243
+ inspect(entry, `${currentPath}.${key}`);
244
+ }
245
+ }
246
+
247
+ inspect(value, path);
248
+ }
249
+
250
+ function normalizeCanonicalJson(
251
+ value: unknown,
252
+ path: string,
253
+ rejectSecretFields: boolean,
254
+ visited = new Set<object>(),
255
+ ): CanonicalJsonValue {
256
+ if (
257
+ value === null ||
258
+ typeof value === 'string' ||
259
+ typeof value === 'boolean'
260
+ ) {
261
+ return value;
262
+ }
263
+ if (typeof value === 'number') {
264
+ if (!Number.isFinite(value)) {
265
+ throw new TypeError(`${path} must contain only finite numbers.`);
266
+ }
267
+ return value;
268
+ }
269
+ if (typeof value !== 'object') {
270
+ throw new TypeError(`${path} must contain only JSON values.`);
271
+ }
272
+ if (visited.has(value)) {
273
+ throw new TypeError(`${path} must not contain cycles.`);
274
+ }
275
+ visited.add(value);
276
+
277
+ if (Array.isArray(value)) {
278
+ const normalized = value.map((entry, index) =>
279
+ normalizeCanonicalJson(
280
+ entry,
281
+ `${path}[${index}]`,
282
+ rejectSecretFields,
283
+ visited,
284
+ ),
285
+ );
286
+ visited.delete(value);
287
+ return Object.freeze(normalized);
288
+ }
289
+ if (!isPlainObject(value)) {
290
+ throw new TypeError(`${path} must contain only plain JSON objects.`);
291
+ }
292
+
293
+ const normalized: Record<string, CanonicalJsonValue> = {};
294
+ for (const [key, entry] of Object.entries(value)) {
295
+ if (
296
+ rejectSecretFields &&
297
+ isSecretField(key) &&
298
+ !SECRET_REFERENCE_SUFFIX_PATTERN.test(key)
299
+ ) {
300
+ throw new TypeError(
301
+ `${path}.${key} appears to contain secret material; pass an opaque reference ending in Ref or Refs instead.`,
302
+ );
303
+ }
304
+ normalized[key] = normalizeCanonicalJson(
305
+ entry,
306
+ `${path}.${key}`,
307
+ rejectSecretFields,
308
+ visited,
309
+ );
310
+ }
311
+ visited.delete(value);
312
+ return Object.freeze(normalized);
313
+ }
314
+
315
+ function isTenantField(key: string): boolean {
316
+ const normalized = key.replaceAll(/[_-]/gu, '').toLowerCase();
317
+ return [
318
+ 'binding',
319
+ 'context',
320
+ 'domain',
321
+ 'domainid',
322
+ 'input',
323
+ 'organization',
324
+ 'organizationid',
325
+ 'org',
326
+ 'orgid',
327
+ 'project',
328
+ 'projectid',
329
+ 'session',
330
+ 'sessionid',
331
+ 'tenant',
332
+ 'tenantid',
333
+ 'thread',
334
+ 'threadid',
335
+ 'user',
336
+ 'userid',
337
+ ].includes(normalized);
338
+ }
339
+
340
+ function isSecretField(key: string): boolean {
341
+ return SECRET_FIELD_PATTERN.test(key) || SECRET_CAMEL_CASE_PATTERN.test(key);
342
+ }
343
+
344
+ function isPlainObject(
345
+ value: unknown,
346
+ ): value is Readonly<Record<string, unknown>> {
347
+ if (value === null || typeof value !== 'object' || Array.isArray(value)) {
348
+ return false;
349
+ }
350
+ const prototype = Object.getPrototypeOf(value);
351
+ return prototype === Object.prototype || prototype === null;
352
+ }