@opengeni/api-router 0.17.0 → 0.20.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.
@@ -1,3 +1,4 @@
1
+ import { createHash } from "node:crypto";
1
2
  import {
2
3
  KnowledgeMemoryKind,
3
4
  KnowledgeMemoryStatus,
@@ -10,6 +11,8 @@ import {
10
11
  WORKSPACE_STATE_TOPIC_MAX_CHARS,
11
12
  WorkspaceStateResponse,
12
13
  type WorkspaceInstructionPolicyListResponse,
14
+ type WorkspaceInstructionPolicySnapshot,
15
+ type WorkspaceStateGovernanceDriftStatus,
13
16
  type WorkspaceStateGap,
14
17
  type WorkspaceStateMemoryKindCounts,
15
18
  type WorkspaceStateMemoryStatusCounts,
@@ -23,14 +26,213 @@ type KnowledgeProjectionInput = {
23
26
  memories: WorkspaceStateMemoryRecord[];
24
27
  };
25
28
 
29
+ type PreferenceGovernanceIdentity = {
30
+ id: string;
31
+ revisionId: string;
32
+ contentHash: string;
33
+ activeVersion: number;
34
+ scope: "organization" | "workspace" | "user";
35
+ };
36
+
37
+ type AttemptGovernanceProjectionInput =
38
+ | { status: "unavailable" }
39
+ | {
40
+ status: "available";
41
+ attemptId: string;
42
+ executionGeneration: number;
43
+ acceptedAt: string;
44
+ policySnapshot: WorkspaceInstructionPolicySnapshot | null;
45
+ preferenceSnapshot: {
46
+ id: string;
47
+ descriptorHash: string;
48
+ descriptors: PreferenceGovernanceIdentity[];
49
+ truncated: boolean;
50
+ createdAt: string;
51
+ } | null;
52
+ currentPreferences: {
53
+ descriptors: PreferenceGovernanceIdentity[];
54
+ truncated: boolean;
55
+ };
56
+ };
57
+
26
58
  export type WorkspaceStateProjectionInput = {
27
59
  workspaceId: string;
28
60
  generatedAt: string;
29
61
  workspaceAgentInstructions: string | null;
30
62
  policies: WorkspaceInstructionPolicyListResponse;
31
63
  knowledge: KnowledgeProjectionInput | null;
64
+ attemptGovernance?: AttemptGovernanceProjectionInput | null;
32
65
  };
33
66
 
67
+ function hashIdentities(values: readonly string[]): string {
68
+ return createHash("sha256").update(values.join("\n"), "utf8").digest("hex");
69
+ }
70
+
71
+ function policyTargetKey(value: { kind: string; scope: string; roleKey: string | null }): string {
72
+ return `${value.kind}:${value.scope}:${value.roleKey ?? ""}`;
73
+ }
74
+
75
+ function policyTargetKeysForRole(policyRole: string | null): Set<string> {
76
+ const keys = new Set(["charter:global:", "policy:global:"]);
77
+ if (policyRole !== null) keys.add(`policy:role:${policyRole}`);
78
+ return keys;
79
+ }
80
+
81
+ function policyIdentity(value: {
82
+ kind: string;
83
+ scope: string;
84
+ roleKey: string | null;
85
+ revisionId: string;
86
+ contentHash: string;
87
+ activationVersion: number;
88
+ }): string {
89
+ return `${policyTargetKey(value)}:${value.revisionId}:${value.contentHash}:${value.activationVersion}`;
90
+ }
91
+
92
+ function preferenceIdentity(value: PreferenceGovernanceIdentity): string {
93
+ return `${value.scope}:${value.id}:${value.revisionId}:${value.contentHash}:${value.activeVersion}`;
94
+ }
95
+
96
+ function classifyIdentityDrift(
97
+ snapshotIdentities: readonly string[],
98
+ currentIdentities: readonly string[],
99
+ snapshotKeys: readonly string[],
100
+ currentKeys: readonly string[],
101
+ ): "identical" | "changed" | "superseded" {
102
+ if (snapshotIdentities.join("\n") === currentIdentities.join("\n")) return "identical";
103
+ return snapshotKeys.join("\n") === currentKeys.join("\n") ? "superseded" : "changed";
104
+ }
105
+
106
+ function overallDriftStatus(
107
+ policy: WorkspaceStateGovernanceDriftStatus,
108
+ preferences: WorkspaceStateGovernanceDriftStatus,
109
+ ): WorkspaceStateGovernanceDriftStatus {
110
+ for (const status of ["unavailable", "truncated", "missing", "changed", "superseded"] as const) {
111
+ if (policy === status || preferences === status) return status;
112
+ }
113
+ return "identical";
114
+ }
115
+
116
+ function attemptGovernanceProjection(input: WorkspaceStateProjectionInput) {
117
+ const governance = input.attemptGovernance ?? null;
118
+ if (governance === null) return { status: "not_requested" as const };
119
+ if (governance.status === "unavailable") {
120
+ return {
121
+ status: "unavailable" as const,
122
+ reason: "attempt_not_found_or_not_authorized" as const,
123
+ driftStatus: "unavailable" as const,
124
+ };
125
+ }
126
+
127
+ const policySnapshot = governance.policySnapshot;
128
+ let policyStatus: WorkspaceStateGovernanceDriftStatus = "missing";
129
+ let policySnapshotHash: string | null = null;
130
+ let policyCurrentHash: string | null = null;
131
+ let policySnapshotTargetCount = 0;
132
+ let policyCurrentTargetCount = 0;
133
+ if (policySnapshot) {
134
+ const snapshotEntries = [...policySnapshot.entries].sort((left, right) =>
135
+ policyTargetKey(left).localeCompare(policyTargetKey(right)),
136
+ );
137
+ const snapshotKeys = snapshotEntries.map(policyTargetKey);
138
+ const relevantTargetKeys = policyTargetKeysForRole(policySnapshot.policyRole);
139
+ const currentEntries = input.policies.activeHeads
140
+ .filter((head) => relevantTargetKeys.has(policyTargetKey(head)))
141
+ .sort((left, right) => policyTargetKey(left).localeCompare(policyTargetKey(right)));
142
+ const snapshotIdentities = snapshotEntries.map(policyIdentity);
143
+ const currentIdentities = currentEntries.map(policyIdentity);
144
+ const currentKeys = currentEntries.map(policyTargetKey);
145
+ policyStatus = classifyIdentityDrift(
146
+ snapshotIdentities,
147
+ currentIdentities,
148
+ snapshotKeys,
149
+ currentKeys,
150
+ );
151
+ policySnapshotHash = hashIdentities(snapshotIdentities);
152
+ policyCurrentHash = hashIdentities(currentIdentities);
153
+ policySnapshotTargetCount = snapshotEntries.length;
154
+ policyCurrentTargetCount = currentEntries.length;
155
+ }
156
+
157
+ const preferenceSnapshot = governance.preferenceSnapshot;
158
+ const currentPreferences = [...governance.currentPreferences.descriptors].sort((left, right) =>
159
+ preferenceIdentity(left).localeCompare(preferenceIdentity(right)),
160
+ );
161
+ let preferenceStatus: WorkspaceStateGovernanceDriftStatus = "missing";
162
+ let preferenceSnapshotHash: string | null = null;
163
+ const currentPreferenceIdentities = currentPreferences.map(preferenceIdentity);
164
+ const currentPreferenceHash = hashIdentities(currentPreferenceIdentities);
165
+ let snapshotPreferenceCount = 0;
166
+ let snapshotPreferenceTruncated = false;
167
+ if (preferenceSnapshot) {
168
+ const snapshotPreferences = [...preferenceSnapshot.descriptors].sort((left, right) =>
169
+ preferenceIdentity(left).localeCompare(preferenceIdentity(right)),
170
+ );
171
+ const snapshotPreferenceIdentities = snapshotPreferences.map(preferenceIdentity);
172
+ const snapshotPreferenceKeys = snapshotPreferences.map((descriptor) => descriptor.id).sort();
173
+ const currentPreferenceKeys = currentPreferences.map((descriptor) => descriptor.id).sort();
174
+ preferenceSnapshotHash = hashIdentities(snapshotPreferenceIdentities);
175
+ snapshotPreferenceCount = snapshotPreferences.length;
176
+ snapshotPreferenceTruncated = preferenceSnapshot.truncated;
177
+ preferenceStatus =
178
+ preferenceSnapshot.truncated || governance.currentPreferences.truncated
179
+ ? "truncated"
180
+ : classifyIdentityDrift(
181
+ snapshotPreferenceIdentities,
182
+ currentPreferenceIdentities,
183
+ snapshotPreferenceKeys,
184
+ currentPreferenceKeys,
185
+ );
186
+ }
187
+
188
+ return {
189
+ status: "available" as const,
190
+ attemptId: governance.attemptId,
191
+ executionGeneration: governance.executionGeneration,
192
+ acceptedAt: governance.acceptedAt,
193
+ policySnapshot: policySnapshot
194
+ ? {
195
+ status: "available" as const,
196
+ id: policySnapshot.id,
197
+ createdAt: policySnapshot.createdAt,
198
+ entryHash: policySnapshot.entryHash,
199
+ policyRole: policySnapshot.policyRole,
200
+ roleSource: policySnapshot.roleSource,
201
+ entries: policySnapshot.entries,
202
+ }
203
+ : { status: "missing" as const },
204
+ preferenceSnapshot: preferenceSnapshot
205
+ ? {
206
+ status: "available" as const,
207
+ id: preferenceSnapshot.id,
208
+ createdAt: preferenceSnapshot.createdAt,
209
+ descriptorHash: preferenceSnapshot.descriptorHash,
210
+ descriptorCount: preferenceSnapshot.descriptors.length,
211
+ truncated: preferenceSnapshot.truncated,
212
+ }
213
+ : { status: "missing" as const },
214
+ drift: {
215
+ overall: overallDriftStatus(policyStatus, preferenceStatus),
216
+ policy: {
217
+ status: policyStatus,
218
+ snapshotHash: policySnapshotHash,
219
+ currentHash: policyCurrentHash,
220
+ snapshotTargetCount: policySnapshotTargetCount,
221
+ currentTargetCount: policyCurrentTargetCount,
222
+ },
223
+ preferences: {
224
+ status: preferenceStatus,
225
+ snapshotHash: preferenceSnapshotHash,
226
+ currentHash: currentPreferenceHash,
227
+ snapshotDescriptorCount: snapshotPreferenceCount,
228
+ currentDescriptorCount: currentPreferences.length,
229
+ snapshotTruncated: snapshotPreferenceTruncated,
230
+ currentTruncated: governance.currentPreferences.truncated,
231
+ },
232
+ },
233
+ };
234
+ }
235
+
34
236
  function emptyMemoryStatusCounts(): WorkspaceStateMemoryStatusCounts {
35
237
  return Object.fromEntries(
36
238
  KnowledgeMemoryStatus.options.map((status) => [status, 0]),
@@ -227,10 +429,7 @@ export function projectWorkspaceState(
227
429
  generatedAt: input.generatedAt,
228
430
  truth: {
229
431
  current: { source: "read_time_projection", capturedAt: input.generatedAt },
230
- policySnapshot: {
231
- status: "not_captured",
232
- reason: "workspace_instruction_policy_snapshot_not_implemented",
233
- },
432
+ attemptGovernance: attemptGovernanceProjection(input),
234
433
  },
235
434
  policy: policyProjection(input),
236
435
  knowledge: input.knowledge