@agentplat/inference-control 0.3.0-beta.2 → 0.3.0-beta.3

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 (150) hide show
  1. package/README.md +360 -0
  2. package/dist/anytime-semantic-guarantees.d.ts +216 -0
  3. package/dist/anytime-semantic-guarantees.d.ts.map +1 -0
  4. package/dist/anytime-semantic-guarantees.js +817 -0
  5. package/dist/anytime-semantic-guarantees.js.map +1 -0
  6. package/dist/assessor-ensemble-contracts.d.ts +145 -0
  7. package/dist/assessor-ensemble-contracts.d.ts.map +1 -0
  8. package/dist/assessor-ensemble-contracts.js +29 -0
  9. package/dist/assessor-ensemble-contracts.js.map +1 -0
  10. package/dist/assessor-ensemble-runtime.d.ts +55 -0
  11. package/dist/assessor-ensemble-runtime.d.ts.map +1 -0
  12. package/dist/assessor-ensemble-runtime.js +308 -0
  13. package/dist/assessor-ensemble-runtime.js.map +1 -0
  14. package/dist/assessor-ensemble-validation.d.ts +12 -0
  15. package/dist/assessor-ensemble-validation.d.ts.map +1 -0
  16. package/dist/assessor-ensemble-validation.js +156 -0
  17. package/dist/assessor-ensemble-validation.js.map +1 -0
  18. package/dist/assessor-ensemble.d.ts +4 -0
  19. package/dist/assessor-ensemble.d.ts.map +1 -0
  20. package/dist/assessor-ensemble.js +4 -0
  21. package/dist/assessor-ensemble.js.map +1 -0
  22. package/dist/cognitive-adapters.d.ts +92 -0
  23. package/dist/cognitive-adapters.d.ts.map +1 -0
  24. package/dist/cognitive-adapters.js +263 -0
  25. package/dist/cognitive-adapters.js.map +1 -0
  26. package/dist/context-integrity-analyzers.d.ts +35 -0
  27. package/dist/context-integrity-analyzers.d.ts.map +1 -0
  28. package/dist/context-integrity-analyzers.js +387 -0
  29. package/dist/context-integrity-analyzers.js.map +1 -0
  30. package/dist/context-integrity-contracts.d.ts +304 -0
  31. package/dist/context-integrity-contracts.d.ts.map +1 -0
  32. package/dist/context-integrity-contracts.js +24 -0
  33. package/dist/context-integrity-contracts.js.map +1 -0
  34. package/dist/context-integrity-model.d.ts +25 -0
  35. package/dist/context-integrity-model.d.ts.map +1 -0
  36. package/dist/context-integrity-model.js +192 -0
  37. package/dist/context-integrity-model.js.map +1 -0
  38. package/dist/context-integrity-portable-agent.d.ts +79 -0
  39. package/dist/context-integrity-portable-agent.d.ts.map +1 -0
  40. package/dist/context-integrity-portable-agent.js +511 -0
  41. package/dist/context-integrity-portable-agent.js.map +1 -0
  42. package/dist/context-integrity-role-alignment.d.ts +28 -0
  43. package/dist/context-integrity-role-alignment.d.ts.map +1 -0
  44. package/dist/context-integrity-role-alignment.js +95 -0
  45. package/dist/context-integrity-role-alignment.js.map +1 -0
  46. package/dist/context-integrity-runtime.d.ts +95 -0
  47. package/dist/context-integrity-runtime.d.ts.map +1 -0
  48. package/dist/context-integrity-runtime.js +1512 -0
  49. package/dist/context-integrity-runtime.js.map +1 -0
  50. package/dist/context-integrity.d.ts +5 -0
  51. package/dist/context-integrity.d.ts.map +1 -0
  52. package/dist/context-integrity.js +5 -0
  53. package/dist/context-integrity.js.map +1 -0
  54. package/dist/governed-role-evolution.d.ts +172 -0
  55. package/dist/governed-role-evolution.d.ts.map +1 -0
  56. package/dist/governed-role-evolution.js +613 -0
  57. package/dist/governed-role-evolution.js.map +1 -0
  58. package/dist/heterogeneous-agent-composition.d.ts +96 -0
  59. package/dist/heterogeneous-agent-composition.d.ts.map +1 -0
  60. package/dist/heterogeneous-agent-composition.js +512 -0
  61. package/dist/heterogeneous-agent-composition.js.map +1 -0
  62. package/dist/index.d.ts +21 -13
  63. package/dist/index.d.ts.map +1 -1
  64. package/dist/index.js +21 -13
  65. package/dist/index.js.map +1 -1
  66. package/dist/intervention-adapters.d.ts +29 -0
  67. package/dist/intervention-adapters.d.ts.map +1 -0
  68. package/dist/intervention-adapters.js +107 -0
  69. package/dist/intervention-adapters.js.map +1 -0
  70. package/dist/intervention-contracts.d.ts +311 -0
  71. package/dist/intervention-contracts.d.ts.map +1 -0
  72. package/dist/intervention-contracts.js +28 -0
  73. package/dist/intervention-contracts.js.map +1 -0
  74. package/dist/intervention-runtime.d.ts +86 -0
  75. package/dist/intervention-runtime.d.ts.map +1 -0
  76. package/dist/intervention-runtime.js +958 -0
  77. package/dist/intervention-runtime.js.map +1 -0
  78. package/dist/intervention-validation.d.ts +27 -0
  79. package/dist/intervention-validation.d.ts.map +1 -0
  80. package/dist/intervention-validation.js +273 -0
  81. package/dist/intervention-validation.js.map +1 -0
  82. package/dist/intervention.d.ts +6 -0
  83. package/dist/intervention.d.ts.map +1 -0
  84. package/dist/intervention.js +6 -0
  85. package/dist/intervention.js.map +1 -0
  86. package/dist/model.d.ts +18 -0
  87. package/dist/model.d.ts.map +1 -1
  88. package/dist/model.js +60 -2
  89. package/dist/model.js.map +1 -1
  90. package/dist/operational-cognitive-control.d.ts +208 -0
  91. package/dist/operational-cognitive-control.d.ts.map +1 -0
  92. package/dist/operational-cognitive-control.js +590 -0
  93. package/dist/operational-cognitive-control.js.map +1 -0
  94. package/dist/portable-agent.d.ts +50 -0
  95. package/dist/portable-agent.d.ts.map +1 -0
  96. package/dist/portable-agent.js +243 -0
  97. package/dist/portable-agent.js.map +1 -0
  98. package/dist/reference-controllers.d.ts +121 -0
  99. package/dist/reference-controllers.d.ts.map +1 -0
  100. package/dist/reference-controllers.js +411 -0
  101. package/dist/reference-controllers.js.map +1 -0
  102. package/dist/role-alignment-portable-agent.d.ts +145 -0
  103. package/dist/role-alignment-portable-agent.d.ts.map +1 -0
  104. package/dist/role-alignment-portable-agent.js +484 -0
  105. package/dist/role-alignment-portable-agent.js.map +1 -0
  106. package/dist/role-alignment.d.ts +226 -0
  107. package/dist/role-alignment.d.ts.map +1 -0
  108. package/dist/role-alignment.js +1074 -0
  109. package/dist/role-alignment.js.map +1 -0
  110. package/dist/role-realignment-portable-agent.d.ts +163 -0
  111. package/dist/role-realignment-portable-agent.d.ts.map +1 -0
  112. package/dist/role-realignment-portable-agent.js +634 -0
  113. package/dist/role-realignment-portable-agent.js.map +1 -0
  114. package/dist/role-realignment.d.ts +368 -0
  115. package/dist/role-realignment.d.ts.map +1 -0
  116. package/dist/role-realignment.js +1609 -0
  117. package/dist/role-realignment.js.map +1 -0
  118. package/dist/semantic-alignment-assessors.d.ts +12 -0
  119. package/dist/semantic-alignment-assessors.d.ts.map +1 -0
  120. package/dist/semantic-alignment-assessors.js +55 -0
  121. package/dist/semantic-alignment-assessors.js.map +1 -0
  122. package/dist/semantic-alignment-contracts.d.ts +385 -0
  123. package/dist/semantic-alignment-contracts.d.ts.map +1 -0
  124. package/dist/semantic-alignment-contracts.js +16 -0
  125. package/dist/semantic-alignment-contracts.js.map +1 -0
  126. package/dist/semantic-alignment-memory.d.ts +53 -0
  127. package/dist/semantic-alignment-memory.d.ts.map +1 -0
  128. package/dist/semantic-alignment-memory.js +170 -0
  129. package/dist/semantic-alignment-memory.js.map +1 -0
  130. package/dist/semantic-alignment-runtime.d.ts +67 -0
  131. package/dist/semantic-alignment-runtime.d.ts.map +1 -0
  132. package/dist/semantic-alignment-runtime.js +778 -0
  133. package/dist/semantic-alignment-runtime.js.map +1 -0
  134. package/dist/semantic-alignment-validation.d.ts +31 -0
  135. package/dist/semantic-alignment-validation.d.ts.map +1 -0
  136. package/dist/semantic-alignment-validation.js +477 -0
  137. package/dist/semantic-alignment-validation.js.map +1 -0
  138. package/dist/semantic-alignment.d.ts +8 -0
  139. package/dist/semantic-alignment.d.ts.map +1 -0
  140. package/dist/semantic-alignment.js +8 -0
  141. package/dist/semantic-alignment.js.map +1 -0
  142. package/dist/semantic-horizon-budget.d.ts +118 -0
  143. package/dist/semantic-horizon-budget.d.ts.map +1 -0
  144. package/dist/semantic-horizon-budget.js +536 -0
  145. package/dist/semantic-horizon-budget.js.map +1 -0
  146. package/dist/semantic-metric-engine.d.ts +96 -0
  147. package/dist/semantic-metric-engine.d.ts.map +1 -0
  148. package/dist/semantic-metric-engine.js +396 -0
  149. package/dist/semantic-metric-engine.js.map +1 -0
  150. package/package.json +79 -7
@@ -0,0 +1,634 @@
1
+ import { normalizeCheckpointTransferV1, normalizeRoleBindingV1, } from "@agentplat/runtime/adapter";
2
+ import { digestTrustEligibilityDecisionV1, validateTrustEligibilityDecisionV1, } from "@agentplat/trust";
3
+ import { assertRoleAlignmentStateV1, createRoleAlignmentPolicyRecordV1, createRoleAlignmentRoleAnchorV1, } from "./role-alignment.js";
4
+ import { admitRoleCandidateV1, assertTrustedRoleDefinitionWithinAuthorityCeilingV1, assertRoleRealignmentStateV1, beginRoleRealignmentActivationV1, certifyRoleRealignmentSelectionV1, completeRoleRealignmentActivationV1, createRoleCandidateEvaluationV1, createRoleRealignmentPolicyRecordV1, createRoleRealignmentRequestV1, createRoleRealignmentStateV1, digestRoleRealignmentJsonV1, expireRoleRealignmentV1, recordRoleCandidateEvaluationV1, rebindRoleRealignmentSessionV1, selectRoleCandidateV1, validateTrustedRoleDefinitionV1, } from "./role-realignment.js";
5
+ import { assertDigest, assertExactKeys, assertIdentifier, assertSafeInteger, deepFreeze, } from "./validation.js";
6
+ export class RoleRealignmentStoreConflictErrorV1 extends Error {
7
+ name = "RoleRealignmentStoreConflictErrorV1";
8
+ constructor(message = "role realignment state revision conflict") {
9
+ super(message);
10
+ }
11
+ }
12
+ export class InMemoryRoleRealignmentStateStoreV1 {
13
+ states = new Map();
14
+ async load(sessionId) {
15
+ assertIdentifier(sessionId, "sessionId");
16
+ return this.states.get(sessionId);
17
+ }
18
+ async save(state, expectedRevision) {
19
+ const current = this.states.get(state.activeSessionId);
20
+ if ((expectedRevision === null && current !== undefined) ||
21
+ (expectedRevision !== null && current?.revision !== expectedRevision))
22
+ throw new RoleRealignmentStoreConflictErrorV1();
23
+ this.states.set(state.activeSessionId, state);
24
+ }
25
+ async rebind(input) {
26
+ const source = this.states.get(input.sourceSessionId);
27
+ if (source?.revision !== input.expectedSourceRevision ||
28
+ this.states.has(input.targetState.activeSessionId) ||
29
+ input.sourceSessionId === input.targetState.activeSessionId)
30
+ throw new RoleRealignmentStoreConflictErrorV1();
31
+ this.states.delete(input.sourceSessionId);
32
+ this.states.set(input.targetState.activeSessionId, input.targetState);
33
+ }
34
+ }
35
+ export function createRoleRealignmentPortableAgentV1(options) {
36
+ return new RoleRealignmentPortableAgent(options);
37
+ }
38
+ class RoleRealignmentPortableAgent {
39
+ binding;
40
+ options;
41
+ policy;
42
+ alignmentPolicy;
43
+ stateStore;
44
+ constructor(options) {
45
+ validatePortableOptions(options);
46
+ const policyRecord = createRoleRealignmentPolicyRecordV1(options.policy);
47
+ const alignmentPolicyRecord = createRoleAlignmentPolicyRecordV1(options.alignmentPolicy);
48
+ this.options = options;
49
+ this.policy = policyRecord.policy;
50
+ this.alignmentPolicy = alignmentPolicyRecord.policy;
51
+ this.stateStore =
52
+ options.stateStore ?? new InMemoryRoleRealignmentStateStoreV1();
53
+ this.binding = deepFreeze({
54
+ controllerId: options.controllerId,
55
+ controllerVersion: options.controllerVersion,
56
+ implementationId: options.implementationId,
57
+ policyId: policyRecord.policy.policyId,
58
+ policyVersion: policyRecord.policy.policyVersion,
59
+ policyDigest: policyRecord.policyDigest,
60
+ alignmentPolicyDigest: alignmentPolicyRecord.policyDigest,
61
+ });
62
+ }
63
+ async getState(sessionId) {
64
+ assertIdentifier(sessionId, "sessionId");
65
+ const state = await this.stateStore.load(sessionId);
66
+ if (!state)
67
+ return undefined;
68
+ assertRoleRealignmentStateV1(state, this.policy, {
69
+ controllerId: this.binding.controllerId,
70
+ controllerVersion: this.binding.controllerVersion,
71
+ implementationId: this.binding.implementationId,
72
+ activeSessionId: sessionId,
73
+ });
74
+ return state;
75
+ }
76
+ async run(input) {
77
+ validateRunInput(input);
78
+ let state = await this.getState(input.sessionId);
79
+ if (!state)
80
+ state = await this.start(input);
81
+ if (state.status === "expired" || state.status === "failed")
82
+ return state;
83
+ if (input.logicalTimeMs >= state.request.expiresAtLogicalMs) {
84
+ const expired = expireRoleRealignmentV1(state, {
85
+ expectedRevision: state.revision,
86
+ logicalTimeMs: input.logicalTimeMs,
87
+ }, this.policy);
88
+ await this.persistTransition(state, expired);
89
+ return expired.state;
90
+ }
91
+ if (state.status === "requested" || state.status === "collecting")
92
+ state = await this.discoverAndEvaluate(state, input);
93
+ if (state.status === "collecting") {
94
+ const selected = selectRoleCandidateV1(state, {
95
+ expectedRevision: state.revision,
96
+ selectionId: input.selectionId,
97
+ logicalTimeMs: input.logicalTimeMs,
98
+ }, this.policy);
99
+ await this.persistTransition(state, selected);
100
+ state = selected.state;
101
+ }
102
+ if (state.status === "selected") {
103
+ const certificate = await this.options.certification.certify({
104
+ state,
105
+ policy: this.policy,
106
+ logicalTimeMs: input.logicalTimeMs,
107
+ expiresAtLogicalMs: Math.min(state.request.expiresAtLogicalMs, input.logicalTimeMs + this.options.certificationTtlMs),
108
+ signal: input.signal,
109
+ });
110
+ if (!certificate)
111
+ return state;
112
+ const certified = certifyRoleRealignmentSelectionV1(state, {
113
+ expectedRevision: state.revision,
114
+ certificate,
115
+ logicalTimeMs: input.logicalTimeMs,
116
+ }, this.policy);
117
+ await this.persistTransition(state, certified);
118
+ state = certified.state;
119
+ }
120
+ if (state.status === "certified") {
121
+ const selection = state.selection;
122
+ if (!selection)
123
+ throw new TypeError("role_realignment_selection_required");
124
+ const selectedCandidate = state.candidates.find(({ candidateDigest }) => candidateDigest === selection.selectedCandidateDigest);
125
+ if (!selectedCandidate)
126
+ throw new TypeError("role_realignment_selected_candidate_missing");
127
+ const definition = await this.resolveCandidateDefinition(selectedCandidate, input.logicalTimeMs, state.request.authorityCeiling);
128
+ const activating = beginRoleRealignmentActivationV1(state, {
129
+ expectedRevision: state.revision,
130
+ activationId: input.activationId,
131
+ definition,
132
+ logicalTimeMs: input.logicalTimeMs,
133
+ }, this.policy);
134
+ await this.persistTransition(state, activating);
135
+ state = activating.state;
136
+ }
137
+ if (state.status === "activating")
138
+ state = await this.resumeActivation(state, input.logicalTimeMs);
139
+ return state;
140
+ }
141
+ async exportHandoff(input) {
142
+ const state = await this.requireState(input.sessionId);
143
+ const transfer = normalizeCheckpointTransferV1(input.checkpointTransfer, {
144
+ maximumStateBytes: this.policy.limits.maximumStateBytes,
145
+ });
146
+ assertSafeInteger(input.logicalTimeMs, "logicalTimeMs");
147
+ if (input.logicalTimeMs < state.lastLogicalTimeMs ||
148
+ transfer.sourceSessionId !== state.activeSessionId ||
149
+ transfer.sourceAgentId !== state.activeAgentId ||
150
+ transfer.objectiveId !== state.objectiveId ||
151
+ transfer.roleBindingId !==
152
+ (state.status === "activated"
153
+ ? state.activation.roleBinding.roleBindingId
154
+ : state.request.currentRoleBindingId))
155
+ throw new TypeError("role_realignment_handoff_binding_invalid");
156
+ const checkpointTransferDigest = digestRoleRealignmentJsonV1("handoff", transfer);
157
+ const body = {
158
+ schemaVersion: 1,
159
+ contentClass: "role_realignment_state",
160
+ controllerId: this.binding.controllerId,
161
+ controllerVersion: this.binding.controllerVersion,
162
+ implementationId: this.binding.implementationId,
163
+ policyDigest: this.binding.policyDigest,
164
+ sourceSessionId: state.activeSessionId,
165
+ sourceAgentId: state.activeAgentId,
166
+ sourceRoleAnchorDigest: state.activeRoleAnchorDigest,
167
+ checkpointTransferDigest,
168
+ sourceState: state,
169
+ exportedAtLogicalMs: input.logicalTimeMs,
170
+ };
171
+ return deepFreeze({
172
+ ...body,
173
+ handoffDigest: digestRoleRealignmentJsonV1("handoff", body),
174
+ });
175
+ }
176
+ async importHandoff(input) {
177
+ const transfer = normalizeCheckpointTransferV1(input.checkpointTransfer, {
178
+ maximumStateBytes: this.policy.limits.maximumStateBytes,
179
+ });
180
+ const handoff = this.validateHandoff(input.handoff, transfer);
181
+ for (const candidate of handoff.sourceState.candidates)
182
+ await this.resolveCandidateDefinition(candidate, input.logicalTimeMs, handoff.sourceState.request.authorityCeiling);
183
+ if (handoff.sourceState.activation)
184
+ await this.validateLocalDefinition(handoff.sourceState.activation.definition, input.logicalTimeMs, handoff.sourceState.request.authorityCeiling);
185
+ const target = input.targetAlignmentState;
186
+ assertRoleAlignmentStateV1(target, this.alignmentPolicy, {
187
+ sessionId: target.sessionId,
188
+ });
189
+ assertSafeInteger(input.logicalTimeMs, "logicalTimeMs");
190
+ if (input.logicalTimeMs < handoff.exportedAtLogicalMs ||
191
+ target.tenantId !== handoff.sourceState.tenantId ||
192
+ target.objectiveId !== handoff.sourceState.objectiveId ||
193
+ target.sessionId === handoff.sourceSessionId ||
194
+ transfer.sourceSessionId !== handoff.sourceSessionId)
195
+ throw new TypeError("role_realignment_handoff_binding_invalid");
196
+ const activated = handoff.sourceState.status === "activated";
197
+ const expectedRole = activated
198
+ ? handoff.sourceState.activation.roleBinding
199
+ : null;
200
+ if ((activated &&
201
+ (target.roleAnchor.roleBindingId !== expectedRole.roleBindingId ||
202
+ target.roleAnchor.roleRevision !== expectedRole.roleRevision)) ||
203
+ (!activated &&
204
+ (target.roleAnchor.roleBindingId !==
205
+ handoff.sourceState.request.currentRoleBindingId ||
206
+ target.roleAnchor.roleRevision !==
207
+ handoff.sourceState.request.currentRoleRevision ||
208
+ target.roleAnchor.roleContentDigest !==
209
+ handoff.sourceState.request.currentRoleContentDigest)))
210
+ throw new TypeError("role_realignment_handoff_role_mismatch");
211
+ const rebound = rebindRoleRealignmentSessionV1(handoff.sourceState, {
212
+ expectedRevision: handoff.sourceState.revision,
213
+ targetSessionId: target.sessionId,
214
+ targetAgentId: target.agentId,
215
+ targetRoleAnchorDigest: target.roleAnchor.anchorDigest,
216
+ transferDigest: handoff.checkpointTransferDigest,
217
+ logicalTimeMs: input.logicalTimeMs,
218
+ }, this.policy);
219
+ await this.stateStore.rebind({
220
+ sourceSessionId: handoff.sourceSessionId,
221
+ targetState: rebound.state,
222
+ expectedSourceRevision: handoff.sourceState.revision,
223
+ });
224
+ await this.observe(rebound);
225
+ return rebound.state;
226
+ }
227
+ async start(input) {
228
+ const alignment = await this.options.alignment.getState(input.sessionId);
229
+ if (!alignment)
230
+ throw new TypeError("role_alignment_state_unavailable");
231
+ const request = createRoleRealignmentRequestV1({
232
+ requestId: input.requestId,
233
+ policy: this.policy,
234
+ alignmentPolicy: this.alignmentPolicy,
235
+ alignmentState: alignment,
236
+ authorityCeiling: input.authorityCeiling,
237
+ createdAtLogicalMs: input.logicalTimeMs,
238
+ expiresAtLogicalMs: input.logicalTimeMs + this.options.requestTtlMs,
239
+ });
240
+ const state = createRoleRealignmentStateV1({
241
+ controllerId: this.binding.controllerId,
242
+ controllerVersion: this.binding.controllerVersion,
243
+ implementationId: this.binding.implementationId,
244
+ policy: this.policy,
245
+ request,
246
+ createdAtLogicalMs: input.logicalTimeMs,
247
+ });
248
+ await this.stateStore.save(state, null);
249
+ await this.observe({ state, event: state.events[0] });
250
+ return state;
251
+ }
252
+ async discoverAndEvaluate(stateInput, input) {
253
+ let state = stateInput;
254
+ const proposalSets = await Promise.all(this.options.discovery.map(async (strategy) => ({
255
+ strategy,
256
+ proposals: await strategy.propose({
257
+ request: state.request,
258
+ logicalTimeMs: input.logicalTimeMs,
259
+ signal: input.signal,
260
+ }),
261
+ })));
262
+ const proposals = proposalSets
263
+ .flatMap(({ strategy, proposals: values }) => values.map((proposal) => ({ strategy, proposal })))
264
+ .sort((left, right) => compare(left.proposal.proposalDigest, right.proposal.proposalDigest));
265
+ for (const { strategy, proposal } of proposals) {
266
+ if (state.candidates.some((candidate) => candidate.proposal.proposalDigest === proposal.proposalDigest ||
267
+ candidate.proposal.definitionDigest === proposal.definitionDigest))
268
+ continue;
269
+ if (proposal.proposerId !== strategy.proposerId ||
270
+ proposal.proposerVersion !== strategy.proposerVersion ||
271
+ proposal.proposerBindingDigest !== strategy.proposerBindingDigest)
272
+ throw new TypeError("role_discovery_strategy_binding_mismatch");
273
+ const trustDigest = await this.eligibleSubjectDigest({
274
+ tenantId: state.tenantId,
275
+ subjectKind: "proposer",
276
+ subjectId: strategy.proposerId,
277
+ subjectBindingDigest: strategy.proposerBindingDigest,
278
+ requestDigest: state.request.requestDigest,
279
+ candidateDigest: null,
280
+ logicalTimeMs: input.logicalTimeMs,
281
+ });
282
+ if (!trustDigest)
283
+ continue;
284
+ const definition = await this.options.catalog.resolve({
285
+ definitionId: proposal.definitionId,
286
+ definitionRevision: proposal.definitionRevision,
287
+ definitionDigest: proposal.definitionDigest,
288
+ logicalTimeMs: input.logicalTimeMs,
289
+ });
290
+ if (!definition)
291
+ continue;
292
+ const admitted = admitRoleCandidateV1(state, {
293
+ expectedRevision: state.revision,
294
+ proposal,
295
+ proposerEligibilityDecisionDigest: trustDigest,
296
+ definition,
297
+ logicalTimeMs: input.logicalTimeMs,
298
+ }, this.policy);
299
+ await this.persistTransition(state, admitted);
300
+ state = admitted.state;
301
+ }
302
+ for (const candidate of state.candidates) {
303
+ const definition = await this.resolveCandidateDefinition(candidate, input.logicalTimeMs, state.request.authorityCeiling);
304
+ for (const evaluator of this.options.evaluators) {
305
+ if (state.evaluations.some((evaluation) => evaluation.candidateDigest === candidate.candidateDigest &&
306
+ evaluation.evaluatorBindingDigest ===
307
+ evaluator.evaluatorBindingDigest))
308
+ continue;
309
+ const trustDigest = await this.eligibleSubjectDigest({
310
+ tenantId: state.tenantId,
311
+ subjectKind: "evaluator",
312
+ subjectId: evaluator.evaluatorId,
313
+ subjectBindingDigest: evaluator.evaluatorBindingDigest,
314
+ requestDigest: state.request.requestDigest,
315
+ candidateDigest: candidate.candidateDigest,
316
+ logicalTimeMs: input.logicalTimeMs,
317
+ });
318
+ if (!trustDigest)
319
+ continue;
320
+ const result = await evaluator.evaluate({
321
+ request: state.request,
322
+ candidate,
323
+ definition,
324
+ logicalTimeMs: input.logicalTimeMs,
325
+ signal: input.signal,
326
+ });
327
+ const evaluation = createRoleCandidateEvaluationV1({
328
+ evaluationId: `evaluation-${candidate.candidateDigest.slice(7, 23)}-${evaluator.evaluatorBindingDigest.slice(7, 23)}`,
329
+ requestDigest: state.request.requestDigest,
330
+ candidateDigest: candidate.candidateDigest,
331
+ definitionDigest: candidate.proposal.definitionDigest,
332
+ evaluatorId: evaluator.evaluatorId,
333
+ evaluatorVersion: evaluator.evaluatorVersion,
334
+ evaluatorBindingDigest: evaluator.evaluatorBindingDigest,
335
+ eligibilityDecisionDigest: trustDigest,
336
+ eligible: result.eligible,
337
+ roleFitBps: result.roleFitBps,
338
+ missionContributionBps: result.missionContributionBps,
339
+ uncertaintyBps: result.uncertaintyBps,
340
+ transitionRiskBps: result.transitionRiskBps,
341
+ reasonCodes: result.reasonCodes,
342
+ evidenceReferenceIds: result.evidenceReferenceIds,
343
+ evaluatedAtLogicalMs: input.logicalTimeMs,
344
+ expiresAtLogicalMs: Math.min(state.request.expiresAtLogicalMs, input.logicalTimeMs + this.options.evaluationTtlMs),
345
+ });
346
+ const recorded = recordRoleCandidateEvaluationV1(state, {
347
+ expectedRevision: state.revision,
348
+ evaluation,
349
+ logicalTimeMs: input.logicalTimeMs,
350
+ }, this.policy);
351
+ await this.persistTransition(state, recorded);
352
+ state = recorded.state;
353
+ }
354
+ }
355
+ return state;
356
+ }
357
+ async resolveCandidateDefinition(candidate, logicalTimeMs, authorityCeiling) {
358
+ const definition = await this.options.catalog.resolve({
359
+ catalogId: candidate.catalogId,
360
+ definitionId: candidate.proposal.definitionId,
361
+ definitionRevision: candidate.proposal.definitionRevision,
362
+ definitionDigest: candidate.proposal.definitionDigest,
363
+ logicalTimeMs,
364
+ });
365
+ if (!definition)
366
+ throw new TypeError("trusted_role_definition_unavailable");
367
+ const validated = validateTrustedRoleDefinitionV1(definition, this.policy);
368
+ if (validated.catalogId !== candidate.catalogId ||
369
+ validated.definitionId !== candidate.proposal.definitionId ||
370
+ validated.definitionRevision !== candidate.proposal.definitionRevision ||
371
+ validated.definitionDigest !== candidate.proposal.definitionDigest)
372
+ throw new TypeError("trusted_role_definition_binding_mismatch");
373
+ assertTrustedRoleDefinitionWithinAuthorityCeilingV1(validated, authorityCeiling);
374
+ return validated;
375
+ }
376
+ async validateLocalDefinition(sourceDefinition, logicalTimeMs, authorityCeiling) {
377
+ const definition = validateTrustedRoleDefinitionV1(sourceDefinition, this.policy);
378
+ const local = await this.options.catalog.resolve({
379
+ catalogId: definition.catalogId,
380
+ definitionId: definition.definitionId,
381
+ definitionRevision: definition.definitionRevision,
382
+ definitionDigest: definition.definitionDigest,
383
+ logicalTimeMs,
384
+ });
385
+ if (!local)
386
+ throw new TypeError("trusted_role_definition_unavailable");
387
+ const validated = validateTrustedRoleDefinitionV1(local, this.policy);
388
+ if (validated.definitionDigest !== definition.definitionDigest)
389
+ throw new TypeError("trusted_role_definition_binding_mismatch");
390
+ assertTrustedRoleDefinitionWithinAuthorityCeilingV1(validated, authorityCeiling);
391
+ return validated;
392
+ }
393
+ async eligibleSubjectDigest(input) {
394
+ const raw = await this.options.trustEligibility.evaluate(input);
395
+ if (!raw)
396
+ return null;
397
+ let decision;
398
+ try {
399
+ decision = validateTrustEligibilityDecisionV1(raw);
400
+ }
401
+ catch {
402
+ return null;
403
+ }
404
+ if (decision.disposition !== "eligible" ||
405
+ decision.evaluatedAtLogicalMs > input.logicalTimeMs)
406
+ return null;
407
+ return `sha256:${digestTrustEligibilityDecisionV1(decision)}`;
408
+ }
409
+ async resumeActivation(state, logicalTimeMs) {
410
+ const activation = state.activation;
411
+ if (!activation)
412
+ throw new TypeError("role_realignment_activation_missing");
413
+ const targetRole = normalizeRoleBindingV1(activation.roleBinding);
414
+ let session = await this.options.runtime.getSession(state.activeSessionId);
415
+ if (!session)
416
+ throw new TypeError("portable_agent_session_unavailable");
417
+ assertRuntimeBinding(state, session);
418
+ if (!sameRole(session.role, targetRole)) {
419
+ if (session.role.roleBindingId !== state.request.currentRoleBindingId ||
420
+ session.role.roleRevision !== state.request.currentRoleRevision)
421
+ throw new TypeError("portable_agent_role_transition_conflict");
422
+ session = await this.options.runtime.updateRole(state.activeSessionId, targetRole, session.revision);
423
+ }
424
+ let alignment = await this.options.alignment.getState(state.activeSessionId);
425
+ if (!alignment)
426
+ throw new TypeError("role_alignment_state_unavailable");
427
+ const targetAnchor = roleAnchorFor(session, targetRole);
428
+ if (alignment.roleAnchor.anchorDigest !== targetAnchor.anchorDigest) {
429
+ alignment = await this.options.alignment.activateSessionRole({
430
+ sessionId: state.activeSessionId,
431
+ expectedRevision: alignment.revision,
432
+ tenantId: state.tenantId,
433
+ agentId: state.activeAgentId,
434
+ role: targetRole,
435
+ logicalTimeMs,
436
+ });
437
+ }
438
+ if (alignment.roleAnchor.anchorDigest !== targetAnchor.anchorDigest)
439
+ throw new TypeError("role_alignment_activation_mismatch");
440
+ const completed = completeRoleRealignmentActivationV1(state, {
441
+ expectedRevision: state.revision,
442
+ runtimeSessionRevision: session.revision,
443
+ alignmentStateRevision: alignment.revision,
444
+ alignmentRoleAnchorDigest: alignment.roleAnchor.anchorDigest,
445
+ logicalTimeMs,
446
+ }, this.policy);
447
+ await this.persistTransition(state, completed);
448
+ return completed.state;
449
+ }
450
+ async persistTransition(previous, transition) {
451
+ await this.stateStore.save(transition.state, previous.revision);
452
+ await this.observe(transition);
453
+ }
454
+ async observe(transition) {
455
+ if (!this.options.observer)
456
+ return;
457
+ try {
458
+ await this.options.observer.observe({
459
+ activeSessionId: transition.state.activeSessionId,
460
+ status: transition.state.status,
461
+ revision: transition.state.revision,
462
+ stateDigest: transition.state.stateDigest,
463
+ event: transition.event,
464
+ });
465
+ }
466
+ catch {
467
+ // Enforcement state is already durable; observation is non-authoritative.
468
+ }
469
+ }
470
+ validateHandoff(input, transfer) {
471
+ assertExactKeys(input, [
472
+ "schemaVersion",
473
+ "contentClass",
474
+ "controllerId",
475
+ "controllerVersion",
476
+ "implementationId",
477
+ "policyDigest",
478
+ "sourceSessionId",
479
+ "sourceAgentId",
480
+ "sourceRoleAnchorDigest",
481
+ "checkpointTransferDigest",
482
+ "sourceState",
483
+ "exportedAtLogicalMs",
484
+ "handoffDigest",
485
+ ], "role realignment handoff");
486
+ assertRoleRealignmentStateV1(input.sourceState, this.policy, {
487
+ controllerId: this.binding.controllerId,
488
+ controllerVersion: this.binding.controllerVersion,
489
+ implementationId: this.binding.implementationId,
490
+ activeSessionId: input.sourceSessionId,
491
+ });
492
+ const { handoffDigest, ...body } = input;
493
+ if (input.schemaVersion !== 1 ||
494
+ input.contentClass !== "role_realignment_state" ||
495
+ input.policyDigest !== this.binding.policyDigest ||
496
+ input.sourceAgentId !== input.sourceState.activeAgentId ||
497
+ input.sourceRoleAnchorDigest !==
498
+ input.sourceState.activeRoleAnchorDigest ||
499
+ input.checkpointTransferDigest !==
500
+ digestRoleRealignmentJsonV1("handoff", transfer) ||
501
+ transfer.sourceSessionId !== input.sourceSessionId ||
502
+ transfer.sourceAgentId !== input.sourceAgentId ||
503
+ transfer.objectiveId !== input.sourceState.objectiveId ||
504
+ digestRoleRealignmentJsonV1("handoff", body) !==
505
+ handoffDigest)
506
+ throw new TypeError("role_realignment_handoff_invalid");
507
+ return input;
508
+ }
509
+ async requireState(sessionId) {
510
+ const state = await this.getState(sessionId);
511
+ if (!state)
512
+ throw new TypeError("role_realignment_state_unavailable");
513
+ return state;
514
+ }
515
+ }
516
+ function validatePortableOptions(options) {
517
+ if (!options || typeof options !== "object")
518
+ throw new TypeError("role_realignment_options_required");
519
+ assertIdentifier(options.controllerId, "controllerId");
520
+ assertSafeInteger(options.controllerVersion, "controllerVersion", 1);
521
+ assertIdentifier(options.implementationId, "implementationId");
522
+ const policy = createRoleRealignmentPolicyRecordV1(options.policy).policy;
523
+ createRoleAlignmentPolicyRecordV1(options.alignmentPolicy);
524
+ if (!options.alignment ||
525
+ typeof options.alignment.getState !== "function" ||
526
+ typeof options.alignment.activateSessionRole !== "function" ||
527
+ !options.runtime ||
528
+ typeof options.runtime.getSession !== "function" ||
529
+ typeof options.runtime.updateRole !== "function" ||
530
+ !Array.isArray(options.discovery) ||
531
+ !options.discovery.length ||
532
+ options.discovery.length > policy.limits.maximumProposers ||
533
+ !Array.isArray(options.evaluators) ||
534
+ options.evaluators.length < policy.minimumIndependentEvaluations ||
535
+ options.evaluators.length > policy.limits.maximumEvaluationsPerCandidate ||
536
+ !options.catalog ||
537
+ typeof options.catalog.resolve !== "function" ||
538
+ !options.trustEligibility ||
539
+ typeof options.trustEligibility.evaluate !== "function" ||
540
+ !options.certification ||
541
+ typeof options.certification.certify !== "function")
542
+ throw new TypeError("role_realignment_port_invalid");
543
+ const proposerBindings = new Set();
544
+ for (const proposer of options.discovery) {
545
+ assertIdentifier(proposer.proposerId, "proposerId");
546
+ assertSafeInteger(proposer.proposerVersion, "proposerVersion", 1);
547
+ assertDigest(proposer.proposerBindingDigest, "proposerBindingDigest");
548
+ if (typeof proposer.propose !== "function" ||
549
+ proposerBindings.has(proposer.proposerBindingDigest))
550
+ throw new TypeError("role_discovery_strategy_invalid");
551
+ proposerBindings.add(proposer.proposerBindingDigest);
552
+ }
553
+ const evaluatorBindings = new Set();
554
+ for (const evaluator of options.evaluators) {
555
+ assertIdentifier(evaluator.evaluatorId, "evaluatorId");
556
+ assertSafeInteger(evaluator.evaluatorVersion, "evaluatorVersion", 1);
557
+ assertDigest(evaluator.evaluatorBindingDigest, "evaluatorBindingDigest");
558
+ if (typeof evaluator.evaluate !== "function" ||
559
+ evaluatorBindings.has(evaluator.evaluatorBindingDigest))
560
+ throw new TypeError("role_candidate_evaluator_invalid");
561
+ evaluatorBindings.add(evaluator.evaluatorBindingDigest);
562
+ }
563
+ for (const [label, value, maximum] of [
564
+ ["requestTtlMs", options.requestTtlMs, policy.limits.maximumRequestTtlMs],
565
+ [
566
+ "evaluationTtlMs",
567
+ options.evaluationTtlMs,
568
+ policy.limits.maximumEvaluationTtlMs,
569
+ ],
570
+ [
571
+ "certificationTtlMs",
572
+ options.certificationTtlMs,
573
+ policy.limits.maximumCertificationTtlMs,
574
+ ],
575
+ ]) {
576
+ assertSafeInteger(value, label, 1);
577
+ if (value > maximum)
578
+ throw new TypeError(`${label}_exceeds_policy`);
579
+ }
580
+ if (options.stateStore !== undefined &&
581
+ (typeof options.stateStore.load !== "function" ||
582
+ typeof options.stateStore.save !== "function" ||
583
+ typeof options.stateStore.rebind !== "function"))
584
+ throw new TypeError("role_realignment_state_store_invalid");
585
+ if (options.observer !== undefined &&
586
+ typeof options.observer.observe !== "function")
587
+ throw new TypeError("role_realignment_observer_invalid");
588
+ }
589
+ function validateRunInput(input) {
590
+ if (!input || typeof input !== "object")
591
+ throw new TypeError("role_realignment_run_input_required");
592
+ for (const [label, value] of [
593
+ ["sessionId", input.sessionId],
594
+ ["requestId", input.requestId],
595
+ ["selectionId", input.selectionId],
596
+ ["activationId", input.activationId],
597
+ ])
598
+ assertIdentifier(value, label);
599
+ assertSafeInteger(input.logicalTimeMs, "logicalTimeMs");
600
+ }
601
+ function roleAnchorFor(session, role) {
602
+ return createRoleAlignmentRoleAnchorV1({
603
+ tenantId: session.tenantId,
604
+ sessionId: session.sessionId,
605
+ agentId: session.agentId,
606
+ objectiveId: role.objectiveId,
607
+ roleBindingId: role.roleBindingId,
608
+ roleRevision: role.roleRevision,
609
+ predecessorRoleBindingId: role.predecessorRoleBindingId,
610
+ roleKey: role.roleKey,
611
+ roleContent: {
612
+ instructions: [...role.instructions],
613
+ constraints: role.constraints,
614
+ validFromLogicalMs: role.validFromLogicalMs,
615
+ validUntilLogicalMs: role.validUntilLogicalMs,
616
+ },
617
+ });
618
+ }
619
+ function assertRuntimeBinding(state, session) {
620
+ if (session.sessionId !== state.activeSessionId ||
621
+ session.tenantId !== state.tenantId ||
622
+ session.agentId !== state.activeAgentId ||
623
+ session.objectiveId !== state.objectiveId ||
624
+ (session.status !== "active" && session.status !== "paused"))
625
+ throw new TypeError("portable_agent_session_binding_mismatch");
626
+ }
627
+ function sameRole(left, right) {
628
+ return (digestRoleRealignmentJsonV1("role_binding", left) ===
629
+ digestRoleRealignmentJsonV1("role_binding", right));
630
+ }
631
+ function compare(left, right) {
632
+ return left < right ? -1 : left > right ? 1 : 0;
633
+ }
634
+ //# sourceMappingURL=role-realignment-portable-agent.js.map