@scopebond/hook 0.8.0 → 0.9.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 (102) hide show
  1. package/README.md +210 -0
  2. package/dist/budget-load.d.ts +68 -0
  3. package/dist/budget-load.d.ts.map +1 -0
  4. package/dist/budget-load.js +164 -0
  5. package/dist/budget-load.js.map +1 -0
  6. package/dist/capabilities.d.ts +103 -0
  7. package/dist/capabilities.d.ts.map +1 -0
  8. package/dist/capabilities.js +212 -0
  9. package/dist/capabilities.js.map +1 -0
  10. package/dist/classify.d.ts +17 -0
  11. package/dist/classify.d.ts.map +1 -0
  12. package/dist/classify.js +78 -0
  13. package/dist/classify.js.map +1 -0
  14. package/dist/cli.d.ts.map +1 -1
  15. package/dist/cli.js +546 -16
  16. package/dist/cli.js.map +1 -1
  17. package/dist/cloud.d.ts +8 -0
  18. package/dist/cloud.d.ts.map +1 -1
  19. package/dist/cloud.js.map +1 -1
  20. package/dist/dispatch-cli.d.ts +2 -0
  21. package/dist/dispatch-cli.d.ts.map +1 -0
  22. package/dist/dispatch-cli.js +128 -0
  23. package/dist/dispatch-cli.js.map +1 -0
  24. package/dist/explain.d.ts.map +1 -1
  25. package/dist/explain.js +2 -1
  26. package/dist/explain.js.map +1 -1
  27. package/dist/group.d.ts +12 -0
  28. package/dist/group.d.ts.map +1 -0
  29. package/dist/group.js +55 -0
  30. package/dist/group.js.map +1 -0
  31. package/dist/index.d.ts +25 -0
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.js +17 -0
  34. package/dist/index.js.map +1 -1
  35. package/dist/install.d.ts +10 -0
  36. package/dist/install.d.ts.map +1 -1
  37. package/dist/install.js +56 -0
  38. package/dist/install.js.map +1 -1
  39. package/dist/map.d.ts +4 -0
  40. package/dist/map.d.ts.map +1 -1
  41. package/dist/map.js +29 -1
  42. package/dist/map.js.map +1 -1
  43. package/dist/obs-emitter.d.ts +132 -0
  44. package/dist/obs-emitter.d.ts.map +1 -0
  45. package/dist/obs-emitter.js +415 -0
  46. package/dist/obs-emitter.js.map +1 -0
  47. package/dist/obs-store.d.ts +160 -0
  48. package/dist/obs-store.d.ts.map +1 -0
  49. package/dist/obs-store.js +367 -0
  50. package/dist/obs-store.js.map +1 -0
  51. package/dist/obs-upload.d.ts +24 -0
  52. package/dist/obs-upload.d.ts.map +1 -0
  53. package/dist/obs-upload.js +231 -0
  54. package/dist/obs-upload.js.map +1 -0
  55. package/dist/observation.d.ts +232 -0
  56. package/dist/observation.d.ts.map +1 -0
  57. package/dist/observation.js +308 -0
  58. package/dist/observation.js.map +1 -0
  59. package/dist/paths.d.ts +15 -0
  60. package/dist/paths.d.ts.map +1 -0
  61. package/dist/paths.js +79 -0
  62. package/dist/paths.js.map +1 -0
  63. package/dist/policy-load.d.ts +60 -0
  64. package/dist/policy-load.d.ts.map +1 -0
  65. package/dist/policy-load.js +151 -0
  66. package/dist/policy-load.js.map +1 -0
  67. package/dist/proof.d.ts +30 -0
  68. package/dist/proof.d.ts.map +1 -0
  69. package/dist/proof.js +186 -0
  70. package/dist/proof.js.map +1 -0
  71. package/dist/rules.d.ts +20 -0
  72. package/dist/rules.d.ts.map +1 -1
  73. package/dist/rules.js +50 -0
  74. package/dist/rules.js.map +1 -1
  75. package/dist/runtime.d.ts +18 -1
  76. package/dist/runtime.d.ts.map +1 -1
  77. package/dist/runtime.js +74 -10
  78. package/dist/runtime.js.map +1 -1
  79. package/dist/scan.d.ts +7 -0
  80. package/dist/scan.d.ts.map +1 -0
  81. package/dist/scan.js +38 -0
  82. package/dist/scan.js.map +1 -0
  83. package/dist/shell.d.ts.map +1 -1
  84. package/dist/shell.js +12 -3
  85. package/dist/shell.js.map +1 -1
  86. package/dist/sql-classify.d.ts +11 -0
  87. package/dist/sql-classify.d.ts.map +1 -0
  88. package/dist/sql-classify.js +251 -0
  89. package/dist/sql-classify.js.map +1 -0
  90. package/dist/typed-infra.d.ts +73 -0
  91. package/dist/typed-infra.d.ts.map +1 -0
  92. package/dist/typed-infra.js +758 -0
  93. package/dist/typed-infra.js.map +1 -0
  94. package/dist/typed-ops.d.ts +140 -0
  95. package/dist/typed-ops.d.ts.map +1 -0
  96. package/dist/typed-ops.js +549 -0
  97. package/dist/typed-ops.js.map +1 -0
  98. package/dist/vectors.d.ts +40 -0
  99. package/dist/vectors.d.ts.map +1 -0
  100. package/dist/vectors.js +219 -0
  101. package/dist/vectors.js.map +1 -0
  102. package/package.json +4 -4
@@ -0,0 +1 @@
1
+ {"version":3,"file":"obs-upload.d.ts","sourceRoot":"","sources":["../src/obs-upload.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,gBAAgB,EAAc,MAAM,gBAAgB,CAAC;AAEnE,eAAO,MAAM,iBAAiB,qBAAqB,CAAC;AACpD,eAAO,MAAM,aAAa,QAAQ,CAAC;AASnC,MAAM,WAAW,aAAa;IAC5B,6CAA6C;IAC7C,MAAM,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,aAAa,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;IACtF,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kDAAkD;IAClD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,0FAA0F;AAC1F,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAOtF;AA4BD,wBAAsB,aAAa,CAAC,KAAK,EAAE,gBAAgB,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,CA0H3G"}
@@ -0,0 +1,231 @@
1
+ // Batch upload of the local observation outbox to `POST /v1/observations`.
2
+ //
3
+ // Request: `{ version: "1.0", items: [SignedObservation] }`, at most 100 items and 1 MiB.
4
+ // Response (HTTP 200): `{ version: "1.0", results: [{ index, observation_id, status, code,
5
+ // retryable, observation_hash? }], retry_after_seconds? }`.
6
+ //
7
+ // What the client does with each answer:
8
+ //
9
+ // accepted / duplicate / pending_link durably acknowledged: removed from the outbox
10
+ // deferred kept and retried later, same id and sequence
11
+ // rejected permanent: moved to the local terminal-error
12
+ // queue (visible in `status`), never retried
13
+ // no result for an item, an unknown status, or an item id that does not match the one
14
+ // sent at that index: treated as NOT acknowledged and kept
15
+ //
16
+ // Request-level answers: 429 keeps everything and waits for Retry-After; 402 (plan-paused agent)
17
+ // keeps everything and looks again in half an hour or more; 401/403 keep
18
+ // everything and back off (credential or plan problem, reported honestly); 413 halves the
19
+ // batch size; 400 keeps everything and backs off; 422 (unsupported batch version) and
20
+ // 404/405 (no such route: an older workspace) mark the capability unsupported. A stale
21
+ // generation in any item blocks further upload until the enrollment generation moves.
22
+ //
23
+ // Nothing here can change or delay a policy decision: the caller bounds it with a timeout
24
+ // and treats every failure as "try again later".
25
+ import { MAX_BATCH_BODY_BYTES, MAX_BATCH_ITEMS } from "./observation.js";
26
+ export const OBSERVATIONS_PATH = "/v1/observations";
27
+ export const BATCH_VERSION = "1.0";
28
+ const ACKNOWLEDGED = new Set(["accepted", "duplicate", "pending_link"]);
29
+ const MAX_BACKOFF_MS = 60 * 60 * 1000;
30
+ const BASE_BACKOFF_MS = 15 * 1000;
31
+ /** Upper bound honoured for a server-supplied Retry-After, so a hostile or mistaken value
32
+ * cannot park the queue for days. */
33
+ const MAX_RETRY_AFTER_MS = 6 * 60 * 60 * 1000;
34
+ /** Parse Retry-After: delta-seconds or an HTTP date. Bounded; undefined when unusable. */
35
+ export function parseRetryAfter(header, now) {
36
+ if (!header)
37
+ return undefined;
38
+ const value = header.trim();
39
+ let ms;
40
+ if (/^\d{1,9}$/.test(value))
41
+ ms = Number(value) * 1000;
42
+ else {
43
+ const date = Date.parse(value);
44
+ if (Number.isFinite(date))
45
+ ms = date - now;
46
+ }
47
+ return ms === undefined ? undefined : Math.max(0, Math.min(ms, MAX_RETRY_AFTER_MS));
48
+ }
49
+ const backoffFor = (attempts) => Math.min(MAX_BACKOFF_MS, BASE_BACKOFF_MS * 2 ** Math.min(attempts, 12));
50
+ function parseResults(body, sent) {
51
+ if (typeof body !== "object" || body === null)
52
+ return null;
53
+ const b = body;
54
+ if (b.version !== BATCH_VERSION || !Array.isArray(b.results) || b.results.length > MAX_BATCH_ITEMS)
55
+ return null;
56
+ const results = new Map();
57
+ for (const raw of b.results) {
58
+ if (typeof raw !== "object" || raw === null)
59
+ continue;
60
+ const r = raw;
61
+ if (!Number.isInteger(r.index) || r.index < 0 || r.index >= sent.length)
62
+ continue;
63
+ if (typeof r.status !== "string")
64
+ continue;
65
+ // A result only counts for the item it names at that index. The workspace reports a null
66
+ // id only for an item it refused before it could read one, and only as refused or
67
+ // deferred; that answer is bound to the item by its index. A durable acknowledgement
68
+ // always names the item.
69
+ if (r.observation_id === null) {
70
+ if (r.status !== "rejected" && r.status !== "deferred")
71
+ continue;
72
+ }
73
+ else if (typeof r.observation_id !== "string" || r.observation_id !== sent[r.index].observation_id)
74
+ continue;
75
+ if (!results.has(r.index))
76
+ results.set(r.index, r);
77
+ }
78
+ const retryAfterSeconds = typeof b.retry_after_seconds === "number" && Number.isFinite(b.retry_after_seconds) && b.retry_after_seconds >= 0 ? b.retry_after_seconds : undefined;
79
+ return { results, retryAfterSeconds };
80
+ }
81
+ export async function uploadPending(store, options) {
82
+ const now = options.now ?? Date.now;
83
+ const doFetch = options.fetch ?? fetch;
84
+ const outcome = { result: "empty", acknowledged: 0, deferred: 0, rejected: 0 };
85
+ const endpoint = new URL(OBSERVATIONS_PATH, options.url);
86
+ if (endpoint.protocol !== "https:" && endpoint.hostname !== "localhost" && endpoint.hostname !== "127.0.0.1") {
87
+ store.setCapability("unsupported", "the workspace URL is not HTTPS");
88
+ return { ...outcome, result: "unsupported", detail: "the workspace URL is not HTTPS" };
89
+ }
90
+ const deadline = now() + (options.timeoutMs ?? 5000);
91
+ for (let round = 0; round < (options.maxBatches ?? 10); round += 1) {
92
+ const state = store.state();
93
+ if (!state)
94
+ return outcome;
95
+ if (state.capability !== "active")
96
+ return { ...outcome, result: state.capability === "unsupported" ? "unsupported" : "blocked", detail: state.reason ?? undefined };
97
+ const batch = store.nextBatch(undefined, true);
98
+ if (batch.length === 0)
99
+ return outcome.acknowledged || outcome.rejected || outcome.deferred ? { ...outcome, result: "sent" } : (state.backoff_until > now() ? { ...outcome, result: "paused" } : outcome);
100
+ const remaining = deadline - now();
101
+ if (remaining <= 0) {
102
+ store.release(batch.map((r) => r.observation_id));
103
+ return { ...outcome, result: "sent" };
104
+ }
105
+ const body = JSON.stringify({ version: BATCH_VERSION, items: batch.map((row) => row.wrapper) });
106
+ if (Buffer.byteLength(body, "utf8") > MAX_BATCH_BODY_BYTES) {
107
+ store.release(batch.map((r) => r.observation_id));
108
+ store.setBatchLimit(Math.max(1, Math.floor(batch.length / 2)));
109
+ continue;
110
+ }
111
+ const controller = new AbortController();
112
+ const timer = setTimeout(() => controller.abort(), remaining);
113
+ let response;
114
+ try {
115
+ response = await doFetch(endpoint, {
116
+ method: "POST", redirect: "error", signal: controller.signal,
117
+ headers: { "content-type": "application/json", authorization: `Bearer ${options.credential}` },
118
+ body,
119
+ });
120
+ }
121
+ catch (error) {
122
+ clearTimeout(timer);
123
+ const attempts = Math.max(...batch.map((r) => r.attempts)) + 1;
124
+ store.defer(batch.map((r) => r.observation_id), backoffFor(attempts));
125
+ store.setBackoff(now() + backoffFor(attempts), `send failed: ${error.name === "AbortError" ? "timeout" : error.message.slice(0, 120)}`);
126
+ return { ...outcome, result: "error", detail: "the workspace could not be reached" };
127
+ }
128
+ clearTimeout(timer);
129
+ if (response.status === 429) {
130
+ const wait = parseRetryAfter(response.headers.get("retry-after"), now()) ?? backoffFor(1);
131
+ store.release(batch.map((r) => r.observation_id));
132
+ store.setBackoff(now() + wait, "rate limited (429)");
133
+ return { ...outcome, result: "backoff", detail: `rate limited; retry after ${Math.ceil(wait / 1000)}s` };
134
+ }
135
+ if (response.status === 404 || response.status === 405) {
136
+ store.release(batch.map((r) => r.observation_id));
137
+ store.setCapability("unsupported", `the workspace does not offer ${OBSERVATIONS_PATH} (HTTP ${response.status})`);
138
+ return { ...outcome, result: "unsupported", detail: `the workspace does not offer ${OBSERVATIONS_PATH}` };
139
+ }
140
+ if (response.status === 422) {
141
+ store.release(batch.map((r) => r.observation_id));
142
+ store.setCapability("unsupported", "the workspace does not accept this observation batch version (HTTP 422)");
143
+ return { ...outcome, result: "unsupported", detail: "batch version not accepted" };
144
+ }
145
+ if (response.status === 413) {
146
+ if (batch.length === 1) {
147
+ store.reject([{ observation_id: batch[0].observation_id, code: "oversize" }]);
148
+ outcome.rejected += 1;
149
+ continue;
150
+ }
151
+ store.release(batch.map((r) => r.observation_id));
152
+ store.setBatchLimit(Math.floor(batch.length / 2));
153
+ continue;
154
+ }
155
+ if (response.status === 402) {
156
+ // The workspace's plan has paused this agent. Nothing is lost: keep the queue, look again later.
157
+ const attempts = Math.max(...batch.map((r) => r.attempts)) + 1;
158
+ const wait = Math.max(backoffFor(attempts), 30 * 60 * 1000);
159
+ store.defer(batch.map((r) => r.observation_id), wait);
160
+ store.setBackoff(now() + wait, "the workspace plan has paused this agent (HTTP 402)");
161
+ return { ...outcome, result: "error", detail: "HTTP 402: the workspace plan has paused this agent" };
162
+ }
163
+ if (response.status === 401 || response.status === 403 || response.status === 400 || response.status >= 500 || response.status !== 200) {
164
+ const attempts = Math.max(...batch.map((r) => r.attempts)) + 1;
165
+ const wait = response.status === 401 || response.status === 403 ? Math.max(backoffFor(attempts), 5 * 60 * 1000) : backoffFor(attempts);
166
+ store.defer(batch.map((r) => r.observation_id), wait);
167
+ store.setBackoff(now() + wait, `HTTP ${response.status}`);
168
+ return { ...outcome, result: "error", detail: `HTTP ${response.status}` };
169
+ }
170
+ let json;
171
+ try {
172
+ json = await response.json();
173
+ }
174
+ catch {
175
+ json = null;
176
+ }
177
+ const parsed = parseResults(json, batch);
178
+ if (!parsed) {
179
+ // A 200 we cannot read acknowledges nothing: keep the whole batch and resend it
180
+ // unchanged; the server dedupes per item.
181
+ const attempts = Math.max(...batch.map((r) => r.attempts)) + 1;
182
+ store.defer(batch.map((r) => r.observation_id), backoffFor(attempts));
183
+ store.setBackoff(now() + backoffFor(attempts), "unreadable batch response");
184
+ return { ...outcome, result: "error", detail: "unreadable response" };
185
+ }
186
+ const acked = [];
187
+ const rejected = [];
188
+ const deferred = [];
189
+ let staleGeneration = false;
190
+ batch.forEach((row, index) => {
191
+ const r = parsed.results.get(index);
192
+ if (!r) {
193
+ deferred.push(row.observation_id);
194
+ return;
195
+ }
196
+ if (ACKNOWLEDGED.has(r.status))
197
+ acked.push(row.observation_id);
198
+ else if (r.status === "rejected") {
199
+ rejected.push({ observation_id: row.observation_id, code: typeof r.code === "string" && r.code ? r.code.slice(0, 64) : "rejected" });
200
+ if (r.code === "stale_generation")
201
+ staleGeneration = true;
202
+ }
203
+ else
204
+ deferred.push(row.observation_id); // deferred, or a status this client does not know
205
+ });
206
+ if (acked.length)
207
+ store.acknowledge(acked);
208
+ if (rejected.length)
209
+ store.reject(rejected);
210
+ if (deferred.length) {
211
+ const attempts = Math.max(...batch.filter((r) => deferred.includes(r.observation_id)).map((r) => r.attempts)) + 1;
212
+ const wait = parsed.retryAfterSeconds !== undefined ? Math.min(parsed.retryAfterSeconds * 1000, MAX_RETRY_AFTER_MS) : backoffFor(attempts);
213
+ store.defer(deferred, wait);
214
+ store.setBackoff(now() + wait, null);
215
+ }
216
+ outcome.acknowledged += acked.length;
217
+ outcome.rejected += rejected.length;
218
+ outcome.deferred += deferred.length;
219
+ if (staleGeneration) {
220
+ // Everything under this generation is unsendable. Keep it locally for a separately
221
+ // authorized archive import and stop until enrollment moves the generation.
222
+ outcome.rejected += store.rejectAllPending("stale_generation");
223
+ store.setCapability("blocked", "the workspace reports this installation generation is stale; reconnect to enroll a new one");
224
+ return { ...outcome, result: "blocked", detail: "stale generation" };
225
+ }
226
+ if (deferred.length)
227
+ return { ...outcome, result: "sent" };
228
+ }
229
+ return { ...outcome, result: "sent" };
230
+ }
231
+ //# sourceMappingURL=obs-upload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"obs-upload.js","sourceRoot":"","sources":["../src/obs-upload.ts"],"names":[],"mappings":"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","sourcesContent":["// Batch upload of the local observation outbox to `POST /v1/observations`.\n//\n// Request: `{ version: \"1.0\", items: [SignedObservation] }`, at most 100 items and 1 MiB.\n// Response (HTTP 200): `{ version: \"1.0\", results: [{ index, observation_id, status, code,\n// retryable, observation_hash? }], retry_after_seconds? }`.\n//\n// What the client does with each answer:\n//\n// accepted / duplicate / pending_link durably acknowledged: removed from the outbox\n// deferred kept and retried later, same id and sequence\n// rejected permanent: moved to the local terminal-error\n// queue (visible in `status`), never retried\n// no result for an item, an unknown status, or an item id that does not match the one\n// sent at that index: treated as NOT acknowledged and kept\n//\n// Request-level answers: 429 keeps everything and waits for Retry-After; 402 (plan-paused agent)\n// keeps everything and looks again in half an hour or more; 401/403 keep\n// everything and back off (credential or plan problem, reported honestly); 413 halves the\n// batch size; 400 keeps everything and backs off; 422 (unsupported batch version) and\n// 404/405 (no such route: an older workspace) mark the capability unsupported. A stale\n// generation in any item blocks further upload until the enrollment generation moves.\n//\n// Nothing here can change or delay a policy decision: the caller bounds it with a timeout\n// and treats every failure as \"try again later\".\n\nimport { MAX_BATCH_BODY_BYTES, MAX_BATCH_ITEMS } from \"./observation.js\";\nimport type { ObservationStore, PendingRow } from \"./obs-store.js\";\n\nexport const OBSERVATIONS_PATH = \"/v1/observations\";\nexport const BATCH_VERSION = \"1.0\";\n\nconst ACKNOWLEDGED = new Set([\"accepted\", \"duplicate\", \"pending_link\"]);\nconst MAX_BACKOFF_MS = 60 * 60 * 1000;\nconst BASE_BACKOFF_MS = 15 * 1000;\n/** Upper bound honoured for a server-supplied Retry-After, so a hostile or mistaken value\n * cannot park the queue for days. */\nconst MAX_RETRY_AFTER_MS = 6 * 60 * 60 * 1000;\n\nexport interface UploadOutcome {\n /** What happened, for `status` and tests. */\n result: \"empty\" | \"paused\" | \"sent\" | \"unsupported\" | \"blocked\" | \"backoff\" | \"error\";\n acknowledged: number;\n deferred: number;\n rejected: number;\n detail?: string;\n}\n\nexport interface UploadOptions {\n url: string;\n credential: string;\n fetch?: typeof fetch;\n now?: () => number;\n timeoutMs?: number;\n /** Send at most this many batches in one call. */\n maxBatches?: number;\n}\n\n/** Parse Retry-After: delta-seconds or an HTTP date. Bounded; undefined when unusable. */\nexport function parseRetryAfter(header: string | null, now: number): number | undefined {\n if (!header) return undefined;\n const value = header.trim();\n let ms: number | undefined;\n if (/^\\d{1,9}$/.test(value)) ms = Number(value) * 1000;\n else { const date = Date.parse(value); if (Number.isFinite(date)) ms = date - now; }\n return ms === undefined ? undefined : Math.max(0, Math.min(ms, MAX_RETRY_AFTER_MS));\n}\n\nconst backoffFor = (attempts: number): number => Math.min(MAX_BACKOFF_MS, BASE_BACKOFF_MS * 2 ** Math.min(attempts, 12));\n\ninterface ItemResult { index: number; observation_id: string | null; status: string; code?: string; retryable?: boolean }\n\nfunction parseResults(body: unknown, sent: PendingRow[]): { results: Map<number, ItemResult>; retryAfterSeconds?: number } | null {\n if (typeof body !== \"object\" || body === null) return null;\n const b = body as { version?: unknown; results?: unknown; retry_after_seconds?: unknown };\n if (b.version !== BATCH_VERSION || !Array.isArray(b.results) || b.results.length > MAX_BATCH_ITEMS) return null;\n const results = new Map<number, ItemResult>();\n for (const raw of b.results) {\n if (typeof raw !== \"object\" || raw === null) continue;\n const r = raw as Partial<ItemResult>;\n if (!Number.isInteger(r.index) || (r.index as number) < 0 || (r.index as number) >= sent.length) continue;\n if (typeof r.status !== \"string\") continue;\n // A result only counts for the item it names at that index. The workspace reports a null\n // id only for an item it refused before it could read one, and only as refused or\n // deferred; that answer is bound to the item by its index. A durable acknowledgement\n // always names the item.\n if (r.observation_id === null) { if (r.status !== \"rejected\" && r.status !== \"deferred\") continue; }\n else if (typeof r.observation_id !== \"string\" || r.observation_id !== sent[r.index as number]!.observation_id) continue;\n if (!results.has(r.index as number)) results.set(r.index as number, r as ItemResult);\n }\n const retryAfterSeconds = typeof b.retry_after_seconds === \"number\" && Number.isFinite(b.retry_after_seconds) && b.retry_after_seconds >= 0 ? b.retry_after_seconds : undefined;\n return { results, retryAfterSeconds };\n}\n\nexport async function uploadPending(store: ObservationStore, options: UploadOptions): Promise<UploadOutcome> {\n const now = options.now ?? Date.now;\n const doFetch = options.fetch ?? fetch;\n const outcome: UploadOutcome = { result: \"empty\", acknowledged: 0, deferred: 0, rejected: 0 };\n const endpoint = new URL(OBSERVATIONS_PATH, options.url);\n if (endpoint.protocol !== \"https:\" && endpoint.hostname !== \"localhost\" && endpoint.hostname !== \"127.0.0.1\") {\n store.setCapability(\"unsupported\", \"the workspace URL is not HTTPS\");\n return { ...outcome, result: \"unsupported\", detail: \"the workspace URL is not HTTPS\" };\n }\n const deadline = now() + (options.timeoutMs ?? 5000);\n for (let round = 0; round < (options.maxBatches ?? 10); round += 1) {\n const state = store.state();\n if (!state) return outcome;\n if (state.capability !== \"active\") return { ...outcome, result: state.capability === \"unsupported\" ? \"unsupported\" : \"blocked\", detail: state.reason ?? undefined };\n const batch = store.nextBatch(undefined, true);\n if (batch.length === 0) return outcome.acknowledged || outcome.rejected || outcome.deferred ? { ...outcome, result: \"sent\" } : (state.backoff_until > now() ? { ...outcome, result: \"paused\" } : outcome);\n const remaining = deadline - now();\n if (remaining <= 0) { store.release(batch.map((r) => r.observation_id)); return { ...outcome, result: \"sent\" }; }\n\n const body = JSON.stringify({ version: BATCH_VERSION, items: batch.map((row) => row.wrapper) });\n if (Buffer.byteLength(body, \"utf8\") > MAX_BATCH_BODY_BYTES) { store.release(batch.map((r) => r.observation_id)); store.setBatchLimit(Math.max(1, Math.floor(batch.length / 2))); continue; }\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), remaining);\n let response: Response;\n try {\n response = await doFetch(endpoint, {\n method: \"POST\", redirect: \"error\", signal: controller.signal,\n headers: { \"content-type\": \"application/json\", authorization: `Bearer ${options.credential}` },\n body,\n });\n } catch (error) {\n clearTimeout(timer);\n const attempts = Math.max(...batch.map((r) => r.attempts)) + 1;\n store.defer(batch.map((r) => r.observation_id), backoffFor(attempts));\n store.setBackoff(now() + backoffFor(attempts), `send failed: ${(error as Error).name === \"AbortError\" ? \"timeout\" : (error as Error).message.slice(0, 120)}`);\n return { ...outcome, result: \"error\", detail: \"the workspace could not be reached\" };\n }\n clearTimeout(timer);\n\n if (response.status === 429) {\n const wait = parseRetryAfter(response.headers.get(\"retry-after\"), now()) ?? backoffFor(1);\n store.release(batch.map((r) => r.observation_id));\n store.setBackoff(now() + wait, \"rate limited (429)\");\n return { ...outcome, result: \"backoff\", detail: `rate limited; retry after ${Math.ceil(wait / 1000)}s` };\n }\n if (response.status === 404 || response.status === 405) {\n store.release(batch.map((r) => r.observation_id));\n store.setCapability(\"unsupported\", `the workspace does not offer ${OBSERVATIONS_PATH} (HTTP ${response.status})`);\n return { ...outcome, result: \"unsupported\", detail: `the workspace does not offer ${OBSERVATIONS_PATH}` };\n }\n if (response.status === 422) {\n store.release(batch.map((r) => r.observation_id));\n store.setCapability(\"unsupported\", \"the workspace does not accept this observation batch version (HTTP 422)\");\n return { ...outcome, result: \"unsupported\", detail: \"batch version not accepted\" };\n }\n if (response.status === 413) {\n if (batch.length === 1) { store.reject([{ observation_id: batch[0]!.observation_id, code: \"oversize\" }]); outcome.rejected += 1; continue; }\n store.release(batch.map((r) => r.observation_id));\n store.setBatchLimit(Math.floor(batch.length / 2));\n continue;\n }\n if (response.status === 402) {\n // The workspace's plan has paused this agent. Nothing is lost: keep the queue, look again later.\n const attempts = Math.max(...batch.map((r) => r.attempts)) + 1;\n const wait = Math.max(backoffFor(attempts), 30 * 60 * 1000);\n store.defer(batch.map((r) => r.observation_id), wait);\n store.setBackoff(now() + wait, \"the workspace plan has paused this agent (HTTP 402)\");\n return { ...outcome, result: \"error\", detail: \"HTTP 402: the workspace plan has paused this agent\" };\n }\n if (response.status === 401 || response.status === 403 || response.status === 400 || response.status >= 500 || response.status !== 200) {\n const attempts = Math.max(...batch.map((r) => r.attempts)) + 1;\n const wait = response.status === 401 || response.status === 403 ? Math.max(backoffFor(attempts), 5 * 60 * 1000) : backoffFor(attempts);\n store.defer(batch.map((r) => r.observation_id), wait);\n store.setBackoff(now() + wait, `HTTP ${response.status}`);\n return { ...outcome, result: \"error\", detail: `HTTP ${response.status}` };\n }\n\n let json: unknown;\n try { json = await response.json(); } catch { json = null; }\n const parsed = parseResults(json, batch);\n if (!parsed) {\n // A 200 we cannot read acknowledges nothing: keep the whole batch and resend it\n // unchanged; the server dedupes per item.\n const attempts = Math.max(...batch.map((r) => r.attempts)) + 1;\n store.defer(batch.map((r) => r.observation_id), backoffFor(attempts));\n store.setBackoff(now() + backoffFor(attempts), \"unreadable batch response\");\n return { ...outcome, result: \"error\", detail: \"unreadable response\" };\n }\n const acked: string[] = [];\n const rejected: Array<{ observation_id: string; code: string }> = [];\n const deferred: string[] = [];\n let staleGeneration = false;\n batch.forEach((row, index) => {\n const r = parsed.results.get(index);\n if (!r) { deferred.push(row.observation_id); return; }\n if (ACKNOWLEDGED.has(r.status)) acked.push(row.observation_id);\n else if (r.status === \"rejected\") {\n rejected.push({ observation_id: row.observation_id, code: typeof r.code === \"string\" && r.code ? r.code.slice(0, 64) : \"rejected\" });\n if (r.code === \"stale_generation\") staleGeneration = true;\n } else deferred.push(row.observation_id); // deferred, or a status this client does not know\n });\n if (acked.length) store.acknowledge(acked);\n if (rejected.length) store.reject(rejected);\n if (deferred.length) {\n const attempts = Math.max(...batch.filter((r) => deferred.includes(r.observation_id)).map((r) => r.attempts)) + 1;\n const wait = parsed.retryAfterSeconds !== undefined ? Math.min(parsed.retryAfterSeconds * 1000, MAX_RETRY_AFTER_MS) : backoffFor(attempts);\n store.defer(deferred, wait);\n store.setBackoff(now() + wait, null);\n }\n outcome.acknowledged += acked.length;\n outcome.rejected += rejected.length;\n outcome.deferred += deferred.length;\n if (staleGeneration) {\n // Everything under this generation is unsendable. Keep it locally for a separately\n // authorized archive import and stop until enrollment moves the generation.\n outcome.rejected += store.rejectAllPending(\"stale_generation\");\n store.setCapability(\"blocked\", \"the workspace reports this installation generation is stale; reconnect to enroll a new one\");\n return { ...outcome, result: \"blocked\", detail: \"stale generation\" };\n }\n if (deferred.length) return { ...outcome, result: \"sent\" };\n }\n return { ...outcome, result: \"sent\" };\n}\n"]}
@@ -0,0 +1,232 @@
1
+ import type { FileProbe } from "./typed-infra.js";
2
+ import { type CallRequest, type GitProbe, type TypedContext } from "./typed-ops.js";
3
+ export type { CallRequest } from "./typed-ops.js";
4
+ import { OBSERVATION_TYPE, OBSERVATION_VERSION } from "@scopebond/policy-schema";
5
+ /** The kinds an agent-adapter key may emit. Anything else is another source's to send. */
6
+ export declare const AGENT_KINDS: readonly ["session", "capability", "health", "policy_ack", "tool_intent", "tool_outcome"];
7
+ export type AgentKind = (typeof AGENT_KINDS)[number];
8
+ export declare function assertAgentKind(kind: string): asserts kind is AgentKind;
9
+ export interface ObservationPayload {
10
+ type: typeof OBSERVATION_TYPE;
11
+ version: typeof OBSERVATION_VERSION;
12
+ observation_id: string;
13
+ installation_id: string;
14
+ installation_generation: number;
15
+ session_id?: string;
16
+ parent_action_id?: string;
17
+ source_receipt_hash?: string;
18
+ kind: AgentKind;
19
+ occurred_at: string;
20
+ sequence: number;
21
+ data: Record<string, unknown>;
22
+ }
23
+ export interface SignedObservation {
24
+ payload: ObservationPayload;
25
+ signature: {
26
+ alg: "Ed25519";
27
+ kid: string;
28
+ value: string;
29
+ };
30
+ }
31
+ export declare const MAX_OBSERVATION_BYTES: number;
32
+ export declare const MAX_BATCH_ITEMS: 100;
33
+ export declare const MAX_BATCH_BODY_BYTES: number;
34
+ export interface ObservationSigner {
35
+ kid: string;
36
+ /** Ed25519 over the given UTF-8 text; unpadded base64url. */
37
+ sign(text: string): string;
38
+ }
39
+ /** A signer from the enrolled agent key's PEM. `kid` is the id the workspace registered
40
+ * for this key at enrollment; it is never derived or guessed here. */
41
+ export declare function observationSigner(privateKeyPem: string, kid: string): ObservationSigner;
42
+ /** The bytes a signature (and the observation hash) cover: domain, then canonical payload. */
43
+ export declare const signingBytes: (payload: ObservationPayload) => Buffer;
44
+ /** SHA-256 of the signing bytes: 64 lowercase hex. Not proof of signature validity. */
45
+ export declare const observationHash: (payload: ObservationPayload) => string;
46
+ /** SHA-256 of `scopebond:source-receipt/v1\n` + canonical full signed receipt envelope. */
47
+ export declare const sourceReceiptHash: (receipt: unknown) => string;
48
+ /** Sign a payload into its wire wrapper. Throws on a payload the server would refuse
49
+ * outright: the wrong kind, or larger than one observation may be. */
50
+ export declare function signObservation(payload: ObservationPayload, signer: ObservationSigner): SignedObservation;
51
+ /** RFC 3339 UTC with millisecond precision, as the schema requires (`...Z`). */
52
+ export declare const utc: (ms: number) => string;
53
+ export declare const newObservationId: () => string;
54
+ /** The installation-local correlation key: 32 random bytes that never leave this machine.
55
+ * Its generation id is derived from the key, so rotating the key changes it and ids from
56
+ * two keys can never be joined. */
57
+ export declare const BINDING_KEY_FILE = "observation-binding.key";
58
+ export declare const REQUEST_BINDING_DOMAIN = "scopebond:request-binding/v1\n";
59
+ export interface BindingKey {
60
+ /** Opaque id of this key generation; safe to upload (it reveals nothing of the key). */
61
+ generation: string;
62
+ /** HMAC-SHA-256 request binding: domain + canonical actual dispatch request. */
63
+ requestDigest(request: unknown): string;
64
+ /** A keyed opaque id for a resource (a path, a ref, a host-local target). */
65
+ resourceId(kind: string, value: string): string;
66
+ /** A keyed opaque id for a harness session id, stable across hook processes. */
67
+ sessionId(harnessSessionId: string): string;
68
+ }
69
+ export declare function bindingKeyFromHex(hex: string): BindingKey;
70
+ /** Load (or create, 0600) the installation-local key beside the other hook keys. */
71
+ export declare function loadOrCreateBindingKey(dir: string): BindingKey;
72
+ export interface EnvelopeContext {
73
+ installationId: string;
74
+ generation: number;
75
+ }
76
+ export interface ObservationDraft {
77
+ kind: AgentKind;
78
+ occurredAt: number;
79
+ /** Already-derived opaque session id, when the observation belongs to one. */
80
+ sessionId?: string;
81
+ parentActionId?: string;
82
+ sourceReceiptHash?: string;
83
+ /** Kind-specific data. `sequence` is filled in by the outbox where the union repeats it. */
84
+ data: Record<string, unknown>;
85
+ /** Give a retry the same id. Defaults to a new UUID. */
86
+ observationId?: string;
87
+ }
88
+ /** Drop undefined so the payload is a closed object with absent optionals omitted. */
89
+ export declare function compact<T extends Record<string, unknown>>(value: T): T;
90
+ /** Build the payload for a draft at an allocated sequence. Repeated fields in `data`
91
+ * (session id, generation, sequence, linkage) are set from the envelope, so they cannot
92
+ * disagree with it. */
93
+ export declare function buildPayload(draft: ObservationDraft, context: EnvelopeContext, sequence: number): ObservationPayload;
94
+ export declare const SESSION_STOP_REASONS: readonly ["completed", "failed", "cancelled", "sleep", "unknown"];
95
+ export type SessionStopReason = (typeof SESSION_STOP_REASONS)[number];
96
+ export declare const sessionStartData: (repositoryId?: string) => {
97
+ event: string;
98
+ repository_id: string | undefined;
99
+ };
100
+ export declare const sessionStopData: (reason: SessionStopReason, repositoryId?: string) => {
101
+ event: string;
102
+ stop_reason: "unknown" | "completed" | "failed" | "cancelled" | "sleep";
103
+ repository_id: string | undefined;
104
+ };
105
+ export declare const heartbeatData: (leaseActive: boolean, extra?: {
106
+ policyDigest?: string;
107
+ clockOffsetMs?: number;
108
+ }) => {
109
+ event: string;
110
+ lease_active: boolean;
111
+ policy_digest: string | undefined;
112
+ clock_offset_ms: number | undefined;
113
+ };
114
+ /** Oldest pending receipt time and backlog size. `count` 0 reports a drained queue
115
+ * (the timestamp is then the report time: the schema requires one). */
116
+ export declare const queueData: (oldestPendingAtMs: number, pendingCount: number, policyDigest?: string) => {
117
+ event: string;
118
+ oldest_pending_at: string;
119
+ pending_count: number;
120
+ policy_digest: string | undefined;
121
+ };
122
+ export declare const POLICY_LOAD_ERRORS: readonly ["schema_invalid", "signature_invalid", "scope_mismatch", "unsupported"];
123
+ export type PolicyLoadError = (typeof POLICY_LOAD_ERRORS)[number];
124
+ export interface PolicyAckInput {
125
+ exportId: string;
126
+ policyId: string;
127
+ policyVersion: number;
128
+ policyDigest: string;
129
+ scopeDigest: string;
130
+ /** Absent means loaded; a value means the hook refused the export for that reason. */
131
+ error?: PolicyLoadError;
132
+ }
133
+ export declare const policyAckData: (input: PolicyAckInput) => {
134
+ event: string;
135
+ export_id: string;
136
+ policy_id: string;
137
+ policy_version: number;
138
+ policy_digest: string;
139
+ scope_digest: string;
140
+ load_result: string;
141
+ error: "schema_invalid" | "signature_invalid" | "scope_mismatch" | "unsupported" | undefined;
142
+ };
143
+ /** SHA-256 hex of a policy's canonical JSON. */
144
+ export declare const digestPolicy: (policy: unknown) => string;
145
+ export interface CapabilityProofInput {
146
+ adapterVersion: string;
147
+ hostVariant: string;
148
+ actionType: string;
149
+ phase: "pre_action" | "after_action";
150
+ requiredFields: string[];
151
+ /** `fixture/<digest>` for a local fixture run, so a fixture is never read as live. */
152
+ fixtureVersion: string;
153
+ passed: boolean;
154
+ /** `source_receipt_hash` of each fixture receipt (the allow fixture and, for a before-action
155
+ * cell, the deny fixture) this proof stands on. The workspace resolves them against the
156
+ * receipts it accepted for this installation, so they are sent only once those receipts
157
+ * were delivered. */
158
+ proofDigests?: string[];
159
+ }
160
+ export declare const capabilityProofData: (input: CapabilityProofInput) => {
161
+ proof_digests?: string[] | undefined;
162
+ event: string;
163
+ connector: string;
164
+ adapter_version: string;
165
+ host_variant: string;
166
+ action_type: string;
167
+ phase: string;
168
+ required_fields: string[];
169
+ fixture_version: string;
170
+ proof_result: string;
171
+ };
172
+ /** What the hook saw about one dispatched action, before reduction to an operation. */
173
+ export interface DispatchedAction {
174
+ action_type: string;
175
+ params: Record<string, unknown>;
176
+ }
177
+ export declare const REFERENCE_SET_VERSION = "hook-1";
178
+ export declare const HOSTNAME: RegExp;
179
+ export interface OperationContext {
180
+ key: BindingKey;
181
+ /** Working directory, used only to derive a keyed workspace-root id. */
182
+ cwd: string;
183
+ /** HEAD commit of the workspace repository, when readable; required for a git operation. */
184
+ headSha?: string | null;
185
+ /** Keyed id of the workspace repository. */
186
+ repositoryId?: string;
187
+ /** Read-only view of the local repository; the system git when absent. */
188
+ probe?: GitProbe;
189
+ /** Whether a pushed ref is protected under the loaded rules; the default names main, master and release/*. */
190
+ isProtectedRef?: (ref: string) => boolean;
191
+ /** Local files and environment the Cloudflare, database and network derivations read; the real ones when absent. */
192
+ files?: FileProbe;
193
+ env?: (name: string) => string | undefined;
194
+ }
195
+ /** The context the typed-operation builders take, from an operation context. */
196
+ export declare const typedContext: (context: OperationContext) => TypedContext;
197
+ /**
198
+ * Reduce one dispatched action to its closed typed operation, or null when this hook
199
+ * cannot describe it honestly (an unmapped tool, a git push whose HEAD is unreadable, a
200
+ * host or tool name that is not a plain identifier). The request digest is the request
201
+ * binding over the actual dispatch request, `{action_type, params}` exactly as evaluated.
202
+ */
203
+ export declare function buildOperation(action: DispatchedAction, context: OperationContext): Record<string, unknown> | null;
204
+ /**
205
+ * One operation (or null) per dispatched item of a tool call. A typed operation derived from
206
+ * the actual request (git commit, package install, GitHub pull request or release) replaces
207
+ * the plain one for the same item; every other item keeps the operation `buildOperation` gives it.
208
+ */
209
+ export declare function operationsForCall(input: {
210
+ dispatched: Array<{
211
+ action: DispatchedAction;
212
+ }>;
213
+ request?: CallRequest;
214
+ }, context: OperationContext & {
215
+ requiredCheckPolicyVersion?: string;
216
+ resolvePullRequest?: TypedContext["resolvePullRequest"];
217
+ packageManagerVersion?: TypedContext["packageManagerVersion"];
218
+ }): Array<Record<string, unknown> | null>;
219
+ export declare const intentData: (operation: Record<string, unknown>) => {
220
+ event: string;
221
+ operation: Record<string, unknown>;
222
+ request_digest: unknown;
223
+ };
224
+ export type ExitCategory = "ok" | "error" | "timeout" | "cancelled" | "unknown";
225
+ export declare const outcomeData: (operation: Record<string, unknown>, exit: ExitCategory, adapterVersion: string, durationMs?: number) => {
226
+ event: string;
227
+ operation: Record<string, unknown>;
228
+ exit_category: ExitCategory;
229
+ adapter_version: string;
230
+ duration_ms: number | undefined;
231
+ };
232
+ //# sourceMappingURL=observation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observation.d.ts","sourceRoot":"","sources":["../src/observation.ts"],"names":[],"mappings":"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"}