@xemahq/agent-session-runtime 0.6.6 → 0.7.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 (52) hide show
  1. package/LICENSE +176 -175
  2. package/README.md +6 -1
  3. package/dist/index.d.ts +1 -0
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +1 -0
  6. package/dist/index.js.map +1 -1
  7. package/dist/lib/dispatch-contract.d.ts +2 -1
  8. package/dist/lib/dispatch-contract.d.ts.map +1 -1
  9. package/dist/lib/launch-identity/canonical-contract.d.ts +21 -0
  10. package/dist/lib/launch-identity/canonical-contract.d.ts.map +1 -0
  11. package/dist/lib/launch-identity/canonical-contract.js +217 -0
  12. package/dist/lib/launch-identity/canonical-contract.js.map +1 -0
  13. package/dist/lib/launch-identity/compiled-session-launch-plan-store.d.ts +44 -0
  14. package/dist/lib/launch-identity/compiled-session-launch-plan-store.d.ts.map +1 -0
  15. package/dist/lib/launch-identity/compiled-session-launch-plan-store.js +116 -0
  16. package/dist/lib/launch-identity/compiled-session-launch-plan-store.js.map +1 -0
  17. package/dist/lib/launch-identity/compiled-session-launch-plan.d.ts +84 -0
  18. package/dist/lib/launch-identity/compiled-session-launch-plan.d.ts.map +1 -0
  19. package/dist/lib/launch-identity/compiled-session-launch-plan.js +386 -0
  20. package/dist/lib/launch-identity/compiled-session-launch-plan.js.map +1 -0
  21. package/dist/lib/launch-identity/index.d.ts +7 -0
  22. package/dist/lib/launch-identity/index.d.ts.map +1 -0
  23. package/dist/lib/launch-identity/index.js +23 -0
  24. package/dist/lib/launch-identity/index.js.map +1 -0
  25. package/dist/lib/launch-identity/runtime-template-key.d.ts +30 -0
  26. package/dist/lib/launch-identity/runtime-template-key.d.ts.map +1 -0
  27. package/dist/lib/launch-identity/runtime-template-key.js +73 -0
  28. package/dist/lib/launch-identity/runtime-template-key.js.map +1 -0
  29. package/dist/lib/launch-identity/session-binding.d.ts +24 -0
  30. package/dist/lib/launch-identity/session-binding.d.ts.map +1 -0
  31. package/dist/lib/launch-identity/session-binding.js +62 -0
  32. package/dist/lib/launch-identity/session-binding.js.map +1 -0
  33. package/dist/lib/launch-identity/thread-reuse-key.d.ts +19 -0
  34. package/dist/lib/launch-identity/thread-reuse-key.d.ts.map +1 -0
  35. package/dist/lib/launch-identity/thread-reuse-key.js +46 -0
  36. package/dist/lib/launch-identity/thread-reuse-key.js.map +1 -0
  37. package/package.json +15 -4
  38. package/src/index.ts +1 -0
  39. package/src/lib/agent-workspace-manifest.ts +2 -2
  40. package/src/lib/composer.ts +2 -2
  41. package/src/lib/dispatch-contract.ts +4 -9
  42. package/src/lib/drift-detector.ts +2 -2
  43. package/src/lib/environment-resolver.ts +3 -3
  44. package/src/lib/launch-identity/canonical-contract.ts +318 -0
  45. package/src/lib/launch-identity/compiled-session-launch-plan-store.ts +178 -0
  46. package/src/lib/launch-identity/compiled-session-launch-plan.ts +689 -0
  47. package/src/lib/launch-identity/index.ts +6 -0
  48. package/src/lib/launch-identity/runtime-template-key.ts +148 -0
  49. package/src/lib/launch-identity/session-binding.ts +152 -0
  50. package/src/lib/launch-identity/thread-reuse-key.ts +93 -0
  51. package/src/lib/skill-bundle-template-resolver.ts +1 -1
  52. package/src/lib/types.ts +1 -1
@@ -0,0 +1,178 @@
1
+ import { requireSha256 } from './canonical-contract';
2
+ import {
3
+ createCompiledSessionLaunchPlan,
4
+ decodeCompiledSessionLaunchPlan,
5
+ encodeCompiledSessionLaunchPlan,
6
+ hashCompiledSessionLaunchPlan,
7
+ type CompiledSessionLaunchPlan,
8
+ } from './compiled-session-launch-plan';
9
+
10
+ /**
11
+ * Storage boundary exposed to session launchers. Reads never degrade to a
12
+ * recompute path: a missing or corrupt plan is an explicit launch failure.
13
+ */
14
+ export interface CompiledSessionLaunchPlanStore {
15
+ getByHash(contentHash: string): Promise<CompiledSessionLaunchPlan>;
16
+ putByHash(
17
+ contentHash: string,
18
+ plan: CompiledSessionLaunchPlan,
19
+ ): Promise<void>;
20
+ }
21
+
22
+ /**
23
+ * Minimal immutable byte-store seam implemented by the eventual database or
24
+ * object-store adapter. `create` must be atomic and must not overwrite.
25
+ */
26
+ export interface ImmutableCompiledSessionLaunchPlanContentStore {
27
+ read(contentHash: string): Promise<string | undefined>;
28
+ create(contentHash: string, encodedPlan: string): Promise<boolean>;
29
+ }
30
+
31
+ export class CompiledSessionLaunchPlanMissingError extends Error {
32
+ override readonly name = 'CompiledSessionLaunchPlanMissingError';
33
+
34
+ constructor(readonly contentHash: string) {
35
+ super(`Compiled session launch plan '${contentHash}' does not exist.`);
36
+ }
37
+ }
38
+
39
+ export class CompiledSessionLaunchPlanAddressMismatchError extends Error {
40
+ override readonly name = 'CompiledSessionLaunchPlanAddressMismatchError';
41
+
42
+ constructor(
43
+ readonly expectedHash: string,
44
+ readonly actualHash: string,
45
+ ) {
46
+ super(
47
+ `Compiled session launch plan address '${expectedHash}' does not match its content hash '${actualHash}'.`,
48
+ );
49
+ }
50
+ }
51
+
52
+ export class CompiledSessionLaunchPlanCollisionError extends Error {
53
+ override readonly name = 'CompiledSessionLaunchPlanCollisionError';
54
+
55
+ constructor(readonly contentHash: string) {
56
+ super(
57
+ `Immutable content collision at compiled session launch plan '${contentHash}'.`,
58
+ );
59
+ }
60
+ }
61
+
62
+ export class CompiledSessionLaunchPlanIntegrityError extends Error {
63
+ override readonly name = 'CompiledSessionLaunchPlanIntegrityError';
64
+
65
+ constructor(
66
+ readonly contentHash: string,
67
+ override readonly cause: unknown,
68
+ ) {
69
+ super(
70
+ `Compiled session launch plan '${contentHash}' failed content verification.`,
71
+ { cause },
72
+ );
73
+ }
74
+ }
75
+
76
+ /**
77
+ * Verifies canonical bytes and content address on every read and write. This
78
+ * keeps corruption and impossible hash collisions observable at the storage
79
+ * boundary instead of passing damaged launch state to a runtime.
80
+ */
81
+ export class VerifyingCompiledSessionLaunchPlanStore
82
+ implements CompiledSessionLaunchPlanStore
83
+ {
84
+ constructor(
85
+ private readonly contentStore: ImmutableCompiledSessionLaunchPlanContentStore,
86
+ ) {}
87
+
88
+ async getByHash(contentHash: string): Promise<CompiledSessionLaunchPlan> {
89
+ const hash = requireSha256(contentHash, 'contentHash');
90
+ const encoded = await this.contentStore.read(hash);
91
+ if (encoded === undefined) {
92
+ throw new CompiledSessionLaunchPlanMissingError(hash);
93
+ }
94
+
95
+ try {
96
+ const plan = decodeCompiledSessionLaunchPlan(encoded);
97
+ const actualHash = hashCompiledSessionLaunchPlan(plan);
98
+ if (actualHash !== hash) {
99
+ throw new CompiledSessionLaunchPlanAddressMismatchError(
100
+ hash,
101
+ actualHash,
102
+ );
103
+ }
104
+ if (encodeCompiledSessionLaunchPlan(plan) !== encoded) {
105
+ throw new TypeError(
106
+ 'Stored launch plan bytes are not in canonical encoding.',
107
+ );
108
+ }
109
+ return plan;
110
+ } catch (error) {
111
+ throw new CompiledSessionLaunchPlanIntegrityError(hash, error);
112
+ }
113
+ }
114
+
115
+ async putByHash(
116
+ contentHash: string,
117
+ plan: CompiledSessionLaunchPlan,
118
+ ): Promise<void> {
119
+ const hash = requireSha256(contentHash, 'contentHash');
120
+ const canonicalPlan = createCompiledSessionLaunchPlan(plan);
121
+ const actualHash = hashCompiledSessionLaunchPlan(canonicalPlan);
122
+ if (actualHash !== hash) {
123
+ throw new CompiledSessionLaunchPlanAddressMismatchError(hash, actualHash);
124
+ }
125
+ const encoded = encodeCompiledSessionLaunchPlan(canonicalPlan);
126
+
127
+ const existing = await this.contentStore.read(hash);
128
+ if (existing !== undefined) {
129
+ this.assertSameContent(hash, existing, encoded);
130
+ return;
131
+ }
132
+
133
+ const created = await this.contentStore.create(hash, encoded);
134
+ if (created) {
135
+ return;
136
+ }
137
+
138
+ const racedExisting = await this.contentStore.read(hash);
139
+ if (racedExisting === undefined) {
140
+ throw new CompiledSessionLaunchPlanIntegrityError(
141
+ hash,
142
+ new Error(
143
+ 'Immutable content store reported an existing value but returned no content.',
144
+ ),
145
+ );
146
+ }
147
+ this.assertSameContent(hash, racedExisting, encoded);
148
+ }
149
+
150
+ private assertSameContent(
151
+ contentHash: string,
152
+ existing: string,
153
+ expected: string,
154
+ ): void {
155
+ if (existing !== expected) {
156
+ throw new CompiledSessionLaunchPlanCollisionError(contentHash);
157
+ }
158
+ }
159
+ }
160
+
161
+ /** Deterministic in-memory adapter for tests and process-local tooling. */
162
+ export class InMemoryCompiledSessionLaunchPlanContentStore
163
+ implements ImmutableCompiledSessionLaunchPlanContentStore
164
+ {
165
+ private readonly values = new Map<string, string>();
166
+
167
+ async read(contentHash: string): Promise<string | undefined> {
168
+ return this.values.get(contentHash);
169
+ }
170
+
171
+ async create(contentHash: string, encodedPlan: string): Promise<boolean> {
172
+ if (this.values.has(contentHash)) {
173
+ return false;
174
+ }
175
+ this.values.set(contentHash, encodedPlan);
176
+ return true;
177
+ }
178
+ }