@arbiterhq/sdk 0.2.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 (59) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/README.md +563 -0
  3. package/dist/approvalMapping.d.ts +26 -0
  4. package/dist/approvalMapping.d.ts.map +1 -0
  5. package/dist/approvalMapping.js +27 -0
  6. package/dist/approvalMapping.js.map +1 -0
  7. package/dist/arbiter.d.ts +23 -0
  8. package/dist/arbiter.d.ts.map +1 -0
  9. package/dist/arbiter.js +58 -0
  10. package/dist/arbiter.js.map +1 -0
  11. package/dist/arbiterAdmin.d.ts +32 -0
  12. package/dist/arbiterAdmin.d.ts.map +1 -0
  13. package/dist/arbiterAdmin.js +125 -0
  14. package/dist/arbiterAdmin.js.map +1 -0
  15. package/dist/errors.d.ts +15 -0
  16. package/dist/errors.d.ts.map +1 -0
  17. package/dist/errors.js +36 -0
  18. package/dist/errors.js.map +1 -0
  19. package/dist/httpClient.d.ts +16 -0
  20. package/dist/httpClient.d.ts.map +1 -0
  21. package/dist/httpClient.js +45 -0
  22. package/dist/httpClient.js.map +1 -0
  23. package/dist/index.d.ts +8 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +7 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/manifest.d.ts +11 -0
  28. package/dist/manifest.d.ts.map +1 -0
  29. package/dist/manifest.js +51 -0
  30. package/dist/manifest.js.map +1 -0
  31. package/dist/manifestValidation.d.ts +9 -0
  32. package/dist/manifestValidation.d.ts.map +1 -0
  33. package/dist/manifestValidation.js +456 -0
  34. package/dist/manifestValidation.js.map +1 -0
  35. package/dist/resolveBaseUrl.d.ts +3 -0
  36. package/dist/resolveBaseUrl.d.ts.map +1 -0
  37. package/dist/resolveBaseUrl.js +12 -0
  38. package/dist/resolveBaseUrl.js.map +1 -0
  39. package/dist/runtime/ArbiterRuntime.d.ts +30 -0
  40. package/dist/runtime/ArbiterRuntime.d.ts.map +1 -0
  41. package/dist/runtime/ArbiterRuntime.js +163 -0
  42. package/dist/runtime/ArbiterRuntime.js.map +1 -0
  43. package/dist/runtime/credentialKind.d.ts +5 -0
  44. package/dist/runtime/credentialKind.d.ts.map +1 -0
  45. package/dist/runtime/credentialKind.js +9 -0
  46. package/dist/runtime/credentialKind.js.map +1 -0
  47. package/dist/runtime/resolveRuntimeAgentExternalId.d.ts +9 -0
  48. package/dist/runtime/resolveRuntimeAgentExternalId.d.ts.map +1 -0
  49. package/dist/runtime/resolveRuntimeAgentExternalId.js +38 -0
  50. package/dist/runtime/resolveRuntimeAgentExternalId.js.map +1 -0
  51. package/dist/types.d.ts +382 -0
  52. package/dist/types.d.ts.map +1 -0
  53. package/dist/types.js +2 -0
  54. package/dist/types.js.map +1 -0
  55. package/dist/version.d.ts +2 -0
  56. package/dist/version.d.ts.map +1 -0
  57. package/dist/version.js +2 -0
  58. package/dist/version.js.map +1 -0
  59. package/package.json +54 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,25 @@
1
+ # Changelog
2
+
3
+ ## 0.2.0 — 2026-06-28
4
+
5
+ First public npm release under **`@arbiterhq/sdk`**. The product name remains **Arbiter**; only the npm scope changed from the previously planned `@arbiter` org.
6
+
7
+ ### Added
8
+
9
+ - `ArbiterRuntime` — connect, heartbeat, disconnect, evaluate, pollApproval, consumeRelease, getReceipt
10
+ - `ArbiterAdmin` — registry, credentials, manifest plan/sync/drift, human approve/reject
11
+ - **Discovery bootstrap** — workspace API key (`arb_test_*`) + `runtime.connect()` discovers unknown agents
12
+ - **Permission discovery** — `runtime.evaluate()` discovers unknown actions (requires adopted agent)
13
+ - **Runtime dual-auth** — backend accepts workspace API key or agent credential on runtime routes
14
+ - Manifest validation, plan, sync, drift, state signature
15
+
16
+ ### Migration
17
+
18
+ - Use `ArbiterAdmin` instead of deprecated `Arbiter` for control-plane operations
19
+ - Use `ArbiterRuntime` with `arb_agent_*` for production runtime loops
20
+ - Discovery-first onboarding: `ArbiterRuntime({ credential: ARBITER_API_KEY })` then adopt in dashboard
21
+ - Set `ARBITER_AGENT` (or `connect({ agent })`) in production for stable identity across redeployments
22
+
23
+ ### Breaking changes
24
+
25
+ - None for new installs. Deprecated `Arbiter` class remains exported with runtime warning.
package/README.md ADDED
@@ -0,0 +1,563 @@
1
+ # @arbiterhq/sdk
2
+
3
+ Official TypeScript SDK for the Arbiter AI governance API.
4
+
5
+ Two clients align with W7.3 runtime identity:
6
+
7
+ - **`ArbiterRuntime`** — autonomous agent execution. Accepts **`arb_agent_*`** (production) or **`arb_test_*`** (discovery bootstrap).
8
+ - **`ArbiterAdmin`** — control plane (`arb_test_*`) including manifest plan/drift
9
+
10
+ ### Runtime authentication model
11
+
12
+ ```
13
+ Discovery bootstrap (first connect)
14
+ Workspace API Key (arb_test_*)
15
+
16
+ runtime.connect()
17
+
18
+ Automatic Agent Discovery
19
+
20
+ Adopt Agent (dashboard)
21
+
22
+ Issue Agent Credential
23
+
24
+ Production runtime
25
+ arb_agent_* → runtime.connect() / evaluate() / heartbeat()
26
+ ```
27
+
28
+ For production deployments, set **`ARBITER_AGENT`** (or pass `connect({ agent })`) to guarantee a stable runtime identity across redeployments. Package name and hostname fallbacks exist for local development convenience only — do not rely on them in production.
29
+
30
+ ## Requirements
31
+
32
+ - Node.js 18+
33
+ - A running Arbiter backend instance
34
+
35
+ ## Install
36
+
37
+ ```bash
38
+ npm install @arbiterhq/sdk
39
+ ```
40
+
41
+ **Discovery-first prerequisite:** Enable **Runtime Discovery** in workspace settings before using a workspace API key with `runtime.connect()`.
42
+
43
+ ## Base URL
44
+
45
+ The SDK resolves the API base URL in this order:
46
+
47
+ 1. `baseUrl` passed to the client constructor
48
+ 2. `ARBITER_BASE_URL` environment variable
49
+ 3. Production default: `https://api.arbitertrust.com`
50
+
51
+ **Production** — omit `baseUrl` or set `ARBITER_BASE_URL=https://api.arbitertrust.com`.
52
+
53
+ **Local development** — set `ARBITER_BASE_URL=http://localhost:3001` or pass `baseUrl: 'http://localhost:3001'` explicitly.
54
+
55
+ ## Credentials
56
+
57
+ | Variable | Used by | Purpose |
58
+ |----------|---------|---------|
59
+ | `ARBITER_AGENT_CREDENTIAL` | `ArbiterRuntime` | Agent runtime auth (`arb_agent_*`) |
60
+ | `ARBITER_AGENT` | `ArbiterRuntime` | Stable agent externalId for discovery bootstrap with workspace API key |
61
+ | `ARBITER_API_KEY` | `ArbiterAdmin`, discovery-first `ArbiterRuntime` | Workspace control plane (`arb_test_*`) |
62
+ | `ARBITER_HUMAN_TOKEN` | `ArbiterAdmin.approve()` / `reject()` | Human session token for authorization actions |
63
+ | `ARBITER_BASE_URL` | Both clients | Override API endpoint |
64
+
65
+ ## Onboarding paths
66
+
67
+ There are two onboarding paths:
68
+
69
+ 1. **Discovery-first** — use a workspace API key with `ArbiterRuntime`, call `runtime.connect()` to discover the agent, adopt in the Discovery Inbox, then call `runtime.evaluate()` to discover permissions.
70
+ 2. **Registry-first** — register agents and permissions with `ArbiterAdmin`, issue an agent credential, then connect with `ARBITER_AGENT_CREDENTIAL`.
71
+
72
+ Both paths converge on the same governed runtime loop after adoption.
73
+
74
+ ## Automatic Discovery
75
+
76
+ Discovery is fully automatic — there are no `discoverAgent()` or `discoverPermission()` APIs.
77
+
78
+ ### Agent discovery (at connect)
79
+
80
+ ```
81
+ Workspace API Key
82
+
83
+ runtime.connect()
84
+
85
+ Agent Discovery
86
+
87
+ Discovery Inbox
88
+
89
+ Adopt
90
+
91
+ Registry
92
+
93
+ (Optional) Agent Credential issued for production
94
+ ```
95
+
96
+ When `ArbiterRuntime` is constructed with a workspace API key (`arb_test_*`), `runtime.connect()` sends the agent identity to the backend. If the agent is unknown and workspace discovery is enabled, it appears in the Discovery Inbox as `pending_review`.
97
+
98
+ ### Permission discovery (at evaluate)
99
+
100
+ ```
101
+ Known active agent
102
+
103
+ runtime.evaluate()
104
+
105
+ Unknown Permission
106
+
107
+ Automatic Permission Discovery
108
+
109
+ Discovery Inbox
110
+
111
+ Adopt
112
+
113
+ Permission becomes available
114
+ ```
115
+
116
+ Permission discovery requires an active runtime identity. Unknown actions discovered during `runtime.evaluate()` appear in the Discovery Inbox for operator adoption.
117
+
118
+ ### Production identity (`ARBITER_AGENT`)
119
+
120
+ Production deployments should set **`ARBITER_AGENT`** to maintain a stable runtime identity across restarts and replicas.
121
+
122
+ When using a workspace API key, the SDK resolves the agent externalId in this order:
123
+
124
+ 1. `connect({ agent })` — explicit argument
125
+ 2. `ARBITER_AGENT` environment variable
126
+ 3. `ARBITER_AGENT_EXTERNAL_ID` environment variable
127
+ 4. `npm_package_name` from `package.json`
128
+ 5. Hostname (development convenience only)
129
+
130
+ Fallbacks (package name / hostname) exist for local development convenience. Do not rely on them in production — set `ARBITER_AGENT` explicitly.
131
+
132
+ ### Discovery-first quickstart
133
+
134
+ ```typescript
135
+ import { ArbiterRuntime, SDK_VERSION } from '@arbiterhq/sdk';
136
+
137
+ // Workspace API key — discovery bootstrap (not production runtime auth)
138
+ const runtime = new ArbiterRuntime({
139
+ credential: process.env.ARBITER_API_KEY!,
140
+ });
141
+
142
+ // Set ARBITER_AGENT in production for stable identity
143
+ await runtime.connect({
144
+ agent: process.env.ARBITER_AGENT ?? 'my-agent',
145
+ framework: 'custom',
146
+ runtimeType: 'node',
147
+ runtimeVersion: process.version,
148
+ sdkVersion: SDK_VERSION,
149
+ });
150
+
151
+ // Agent appears in Discovery Inbox → adopt in dashboard
152
+ // After adoption, evaluate discovers unknown permissions:
153
+ const decision = await runtime.evaluate({ action: 'send_payment', amount: 500 });
154
+ // Permission appears in Discovery Inbox → adopt → governance applies
155
+ ```
156
+
157
+ See [`../../examples/discovery-first/`](../../examples/discovery-first/) for the canonical onboarding script.
158
+
159
+ ## Complete runtime flow
160
+
161
+ End-to-end governed execution: connect → heartbeat → evaluate → approval → poll → consume release → receipt.
162
+
163
+ ```typescript
164
+ import { ArbiterAdmin, ArbiterRuntime, SDK_VERSION } from '@arbiterhq/sdk';
165
+
166
+ // Production: omit baseUrl. Local dev: baseUrl: 'http://localhost:3001'
167
+ const admin = new ArbiterAdmin({
168
+ apiKey: process.env.ARBITER_API_KEY!,
169
+ });
170
+
171
+ const runtime = new ArbiterRuntime({
172
+ credential: process.env.ARBITER_AGENT_CREDENTIAL!,
173
+ environment: 'production',
174
+ });
175
+
176
+ await runtime.connect({
177
+ framework: 'custom',
178
+ runtimeType: 'node',
179
+ runtimeVersion: process.version,
180
+ sdkVersion: SDK_VERSION,
181
+ });
182
+
183
+ await runtime.heartbeat();
184
+
185
+ const evaluationPayload = {
186
+ action: 'send_payment',
187
+ amount: 5000,
188
+ } as const;
189
+
190
+ const decision = await runtime.evaluate(evaluationPayload);
191
+
192
+ if (decision.decision === 'hold' && decision.approvalRequestId) {
193
+ // Human operator approves via admin + session token
194
+ await admin.approve(decision.approvalRequestId, {
195
+ humanToken: process.env.ARBITER_HUMAN_TOKEN!,
196
+ });
197
+
198
+ const approval = await runtime.pollApproval(decision.approvalRequestId);
199
+
200
+ if (approval.status === 'approved') {
201
+ const release = await runtime.consumeRelease({
202
+ approvalRequestId: decision.approvalRequestId,
203
+ originalPayload: evaluationPayload,
204
+ });
205
+
206
+ const receipt = await runtime.getReceipt(release.evaluationId);
207
+ console.log(receipt.receiptHash);
208
+ }
209
+ }
210
+ ```
211
+
212
+ Obtain `ARBITER_HUMAN_TOKEN` from a workspace session (`POST /auth/session` or dashboard login). Obtain `ARBITER_AGENT_CREDENTIAL` via `createAgentCredentialByExternalId()` or the dashboard.
213
+
214
+ ## Runtime Quickstart
215
+
216
+ ```typescript
217
+ import { ArbiterRuntime, SDK_VERSION } from '@arbiterhq/sdk';
218
+
219
+ const runtime = new ArbiterRuntime({
220
+ credential: process.env.ARBITER_AGENT_CREDENTIAL!,
221
+ });
222
+
223
+ await runtime.connect({
224
+ framework: 'langgraph',
225
+ runtimeType: 'node',
226
+ runtimeVersion: process.version,
227
+ sdkVersion: SDK_VERSION,
228
+ environment: 'production',
229
+ });
230
+
231
+ const result = await runtime.evaluate({
232
+ action: 'send_payment',
233
+ amount: 5000,
234
+ });
235
+
236
+ console.log(result.decision, result.evaluationId);
237
+ ```
238
+
239
+ ### Local development
240
+
241
+ ```typescript
242
+ const runtime = new ArbiterRuntime({
243
+ credential: process.env.ARBITER_AGENT_CREDENTIAL!,
244
+ baseUrl: 'http://localhost:3001',
245
+ });
246
+ ```
247
+
248
+ ## Admin Quickstart
249
+
250
+ ```typescript
251
+ import { ArbiterAdmin } from '@arbiterhq/sdk';
252
+
253
+ const admin = new ArbiterAdmin({
254
+ apiKey: process.env.ARBITER_API_KEY!,
255
+ });
256
+
257
+ await admin.registerAgent({ externalId: 'finance-agent' });
258
+ await admin.registerPermission({ action: 'send_payment' });
259
+ await admin.grantPermission({ agent: 'finance-agent', action: 'send_payment' });
260
+
261
+ const { credential } = await admin.createAgentCredentialByExternalId({
262
+ externalId: 'finance-agent',
263
+ name: 'Runtime credential',
264
+ createdByUserId: 'owner-user-id',
265
+ });
266
+ ```
267
+
268
+ ### Local development
269
+
270
+ ```typescript
271
+ const admin = new ArbiterAdmin({
272
+ apiKey: process.env.ARBITER_API_KEY!,
273
+ baseUrl: 'http://localhost:3001',
274
+ });
275
+ ```
276
+
277
+ ## Manifest lifecycle
278
+
279
+ Manifest SDK methods accept a typed **`ManifestWorkspace`** object — not a YAML string, file path, or full `arbiter.yaml` document.
280
+
281
+ ```
282
+ arbiter.yaml
283
+
284
+ parse YAML
285
+
286
+ doc.spec
287
+
288
+ ManifestWorkspace
289
+
290
+ plan()
291
+
292
+ syncRegistryManifest()
293
+ ```
294
+
295
+ The SDK does **not** read files. The CLI reads and parses `arbiter.yaml` for you. When using the SDK directly, parse the file, extract `doc.spec`, and optionally validate with `validateManifestWorkspace()`.
296
+
297
+ ```typescript
298
+ interface ManifestWorkspace {
299
+ agents: ManifestAgent[];
300
+ permissions: ManifestPermission[];
301
+ policies: ManifestPolicy[];
302
+ }
303
+ ```
304
+
305
+ Use `validateManifestWorkspace(manifest)` before calling SDK methods to get actionable validation errors that mirror the backend contract.
306
+
307
+ ## Manifest fields
308
+
309
+ ### Agent (`agents[]`)
310
+
311
+ | Field | Required | Description |
312
+ |-------|----------|-------------|
313
+ | `externalId` | For sync/plan | Stable agent identifier used by sync and plan |
314
+ | `name` | Yes | Display name |
315
+ | `description` | No | Human-readable summary |
316
+ | `source` | No | Provenance: `dashboard`, `sdk`, `discovered` |
317
+ | `management` | No | Ownership mode: `dashboard`, `sdk`, `manifest`, `discovered` |
318
+ | `owner` | No | Structured owner `{ slug, type }` where `type` is `user`, `team`, or `service_account` |
319
+ | `ownerSlug` | No | Owner slug when not using the `owner` object |
320
+ | `ownerType` | No | Owner type when using `ownerSlug` |
321
+ | `riskTier` | No | `low`, `medium`, `high`, or `critical` |
322
+ | `status` | No | `pending_review`, `active`, `disabled`, `expired`, or `archived` |
323
+ | `expiresAt` | No | ISO 8601 datetime |
324
+ | `approvedBy` | No | Approver identity for governed onboarding |
325
+ | `grants` | No | Permission grants to apply with the agent (see Grants) |
326
+
327
+ ### Permission (`permissions[]`)
328
+
329
+ | Field | Required | Description |
330
+ |-------|----------|-------------|
331
+ | `action` | Yes | Snake_case action identifier |
332
+ | `description` | No | Human-readable summary |
333
+ | `status` | No | `pending_review`, `allowed`, `denied`, or `approval_required` |
334
+ | `source` | No | Provenance: `dashboard`, `sdk`, `discovered` |
335
+ | `management` | No | Ownership mode: `dashboard`, `sdk`, `manifest`, `discovered` |
336
+ | `assignedAgents` | No | Agent `externalId` values assigned to this permission |
337
+ | `displayName` | No | UI-friendly label |
338
+ | `category` | No | Grouping label (for example Financial) |
339
+ | `documentation` | No | Documentation URL |
340
+ | `tags` | No | String tags for discovery and filtering |
341
+ | `metadata` | No | Arbitrary key/value metadata object |
342
+
343
+ ### Policy (`policies[]`)
344
+
345
+ | Field | Required | Description |
346
+ |-------|----------|-------------|
347
+ | `id` | For sync/plan | Stable policy slug |
348
+ | `action` | Yes | Snake_case action this policy governs |
349
+ | `field` | Legacy style | Field path for single-condition policies |
350
+ | `operator` | Legacy style | Comparison operator |
351
+ | `value` | Legacy style | Scalar or array value |
352
+ | `conditions` | Modern style | Array of `{ field, operator, value?, type? }` |
353
+ | `conditionOperator` | Modern style | `AND` or `OR` when using multiple `conditions` |
354
+ | `priority` | No | Integer priority (lower runs first) |
355
+ | `displayName` | No | UI-friendly label |
356
+ | `decision` | Yes | `allow`, `deny`, or `hold` |
357
+ | `source` | No | Provenance: `dashboard`, `sdk`, `discovered` |
358
+ | `management` | No | Ownership mode: `dashboard`, `sdk`, `manifest`, `discovered` |
359
+
360
+ Every policy must declare **either** legacy `field` + `operator` + `value` **or** a non-empty `conditions[]` array.
361
+
362
+ #### Legacy policy style
363
+
364
+ Use a single field comparison when the rule is simple:
365
+
366
+ ```yaml
367
+ - id: payment-amount-hold
368
+ action: send_payment
369
+ field: amount
370
+ operator: '>'
371
+ value: 1000
372
+ decision: hold
373
+ ```
374
+
375
+ #### Modern policy style
376
+
377
+ Use `conditions[]` when you need multiple predicates or richer operators:
378
+
379
+ ```yaml
380
+ - id: payment-region-deny
381
+ action: send_payment
382
+ conditions:
383
+ - field: region
384
+ operator: in
385
+ value: [sanctioned, blocked]
386
+ - field: amount
387
+ operator: '>='
388
+ value: 100
389
+ conditionOperator: AND
390
+ decision: deny
391
+ ```
392
+
393
+ Prefer legacy style for single comparisons. Prefer modern style for compound rules or operator sets like `in`, `between`, and valueless operators (`exists`, `is_null`, etc.).
394
+
395
+ ### Grants
396
+
397
+ `grants` on an agent replace that agent's permission grants during sync:
398
+
399
+ ```yaml
400
+ grants:
401
+ - action: send_payment
402
+ grantedBy: platform-ops
403
+ grantedReason: Baseline finance automation access
404
+ ```
405
+
406
+ Each grant requires `action` (snake_case). Optional `grantedBy` and `grantedReason` document provenance.
407
+
408
+ ### Ownership and risk
409
+
410
+ - **`owner`** — structured `{ slug, type }` for accountable ownership
411
+ - **`ownerSlug` / `ownerType`** — flat alternative to the `owner` object
412
+ - **`riskTier`** — classifies agent blast radius: `low`, `medium`, `high`, `critical`
413
+
414
+ ### Source and management semantics
415
+
416
+ - **`source`** — where the record originated (`dashboard`, `sdk`, `discovered`)
417
+ - **`management`** — who may mutate the record (`dashboard`, `sdk`, `manifest`, `discovered`)
418
+
419
+ Manifest-managed resources typically use `management: manifest` so the CLI/SDK owns changes and the dashboard stays read-only for those records.
420
+
421
+ ## Manifest SDK workflow
422
+
423
+ Install a YAML parser in your project:
424
+
425
+ ```bash
426
+ npm install yaml
427
+ ```
428
+
429
+ ### Plan
430
+
431
+ ```javascript
432
+ import fs from 'node:fs';
433
+ import { parse as parseYaml } from 'yaml';
434
+ import { ArbiterAdmin, validateManifestWorkspace } from '@arbiterhq/sdk';
435
+
436
+ const admin = new ArbiterAdmin({
437
+ apiKey: process.env.ARBITER_API_KEY,
438
+ });
439
+
440
+ const doc = parseYaml(fs.readFileSync('./arbiter.yaml', 'utf8'));
441
+ const manifest = validateManifestWorkspace(doc.spec);
442
+
443
+ const plan = await admin.plan(manifest);
444
+ console.log(JSON.stringify(plan, null, 2));
445
+ ```
446
+
447
+ ### Sync (apply manifest)
448
+
449
+ High-level API — pass a parsed `ManifestWorkspace`:
450
+
451
+ ```javascript
452
+ import fs from 'node:fs';
453
+ import { parse as parseYaml } from 'yaml';
454
+ import { ArbiterAdmin, validateManifestWorkspace } from '@arbiterhq/sdk';
455
+
456
+ const admin = new ArbiterAdmin({
457
+ apiKey: process.env.ARBITER_API_KEY,
458
+ });
459
+
460
+ const doc = parseYaml(fs.readFileSync('./arbiter.yaml', 'utf8'));
461
+ const manifest = validateManifestWorkspace(doc.spec);
462
+
463
+ const applied = await admin.syncRegistryManifest(manifest);
464
+ console.log(JSON.stringify(applied, null, 2));
465
+ ```
466
+
467
+ ### Drift
468
+
469
+ Drift is workspace-scoped — no manifest input:
470
+
471
+ ```javascript
472
+ import { ArbiterAdmin } from '@arbiterhq/sdk';
473
+
474
+ const admin = new ArbiterAdmin({
475
+ apiKey: process.env.ARBITER_API_KEY,
476
+ });
477
+
478
+ const drift = await admin.getDrift();
479
+ console.log(JSON.stringify(drift, null, 2));
480
+ ```
481
+
482
+ ### State signature
483
+
484
+ ```javascript
485
+ import { ArbiterAdmin } from '@arbiterhq/sdk';
486
+
487
+ const admin = new ArbiterAdmin({
488
+ apiKey: process.env.ARBITER_API_KEY,
489
+ });
490
+
491
+ const signature = await admin.getStateSignature();
492
+ console.log(signature.stateSignature);
493
+ ```
494
+
495
+ ## Manifest API surface
496
+
497
+ | API | Level | Input | Use when |
498
+ |-----|-------|-------|----------|
499
+ | `plan(manifest)` | High-level | `ManifestWorkspace` | Preview changes from parsed manifest |
500
+ | `syncRegistryManifest(manifest)` | High-level | `ManifestWorkspace` | Apply parsed manifest to workspace |
501
+ | `getDrift()` | High-level | none | Compare live workspace drift |
502
+ | `getStateSignature()` | High-level | none | Read workspace governance fingerprint |
503
+ | `syncRegistry(input)` | Low-level transport | `SyncRegistryInput` | You already built the typed sync payload |
504
+
505
+ Prefer **`syncRegistryManifest()`** for manifest-driven workflows. Use **`syncRegistry()`** only when you construct the transport payload yourself.
506
+
507
+ ## Runnable examples
508
+
509
+ See [`../../examples/discovery-first/`](../../examples/discovery-first/) for the canonical discovery-first onboarding flow.
510
+
511
+ See [`../../examples/manifest/`](../../examples/manifest/) for complete manifest scripts:
512
+
513
+ - `plan.mjs` — preview manifest changes
514
+ - `sync.mjs` — apply manifest changes
515
+ - `drift.mjs` — inspect workspace drift
516
+ - `state-signature.mjs` — read workspace governance fingerprint
517
+ - `loadManifest.mjs` — shared YAML loader with SDK validation
518
+ - `arbiter.yaml` — canonical manifest demonstrating supported fields
519
+
520
+ ```bash
521
+ cd examples/manifest
522
+ npm install
523
+ export ARBITER_API_KEY=your_key
524
+ npm run plan
525
+ npm run sync
526
+ npm run drift
527
+ npm run state-signature
528
+ ```
529
+
530
+ ## API Reference
531
+
532
+ ### `ArbiterRuntime`
533
+
534
+ | Method | Description |
535
+ |--------|-------------|
536
+ | `connect(input?)` | `POST /runtime/connect` — agent discovery with workspace API key |
537
+ | `heartbeat()` | `POST /runtime/heartbeat` |
538
+ | `evaluate(input)` | `POST /evaluate` — permission discovery for unknown actions |
539
+ | `getApproval(id)` | `GET /approvals/:id` |
540
+ | `pollApproval(id, options?)` | Poll until approved/rejected/expired |
541
+ | `consumeRelease(input)` | `POST /releases/consume` |
542
+ | `getReceipt(evaluationId)` | `GET /evaluations/:id/receipt` |
543
+
544
+ ### `ArbiterAdmin`
545
+
546
+ | Method | Description |
547
+ |--------|-------------|
548
+ | `registerAgent` | `POST /sdk/register-agent` |
549
+ | `registerPermission` | `POST /sdk/register-permission` |
550
+ | `grantPermission` | `POST /sdk/register-agent-permission` |
551
+ | `registerPolicy` | `POST /sdk/register-policy` |
552
+ | `plan(manifest)` | `POST /sdk/plan` — requires `ManifestWorkspace` |
553
+ | `syncRegistryManifest(manifest)` | `POST /sdk/sync-registry` — requires `ManifestWorkspace` |
554
+ | `syncRegistry(input)` | `POST /sdk/sync-registry` — low-level typed payload |
555
+ | `getDrift()` | `GET /manifest/drift` |
556
+ | `getStateSignature()` | `GET /state-signature` |
557
+ | `createAgentCredential` | `POST /agents/:id/credentials` |
558
+ | `createAgentCredentialByExternalId` | Resolve agent + create credential |
559
+ | `approve` / `reject` | Human session required |
560
+
561
+ ## License
562
+
563
+ ISC
@@ -0,0 +1,26 @@
1
+ import type { ApprovalResult, EvaluateResult } from './types.js';
2
+ export interface ApprovalApiResponse {
3
+ id: string;
4
+ status: string;
5
+ evaluationId: string;
6
+ requestedAt: string;
7
+ approvedAt: string | null;
8
+ rejectedAt: string | null;
9
+ evaluation: {
10
+ agent: string;
11
+ action: string;
12
+ decision: EvaluateResult['decision'];
13
+ amount: number | null;
14
+ };
15
+ executionRelease: {
16
+ id: string;
17
+ status: string;
18
+ issuedAt: string;
19
+ expiresAt: string;
20
+ consumedAt: string | null;
21
+ } | null;
22
+ }
23
+ export declare function mapApproval(response: ApprovalApiResponse): ApprovalResult;
24
+ export declare function isTerminalApprovalStatus(status: string): boolean;
25
+ export declare function resolveTerminalApprovalStatus(approval: ApprovalResult): string;
26
+ //# sourceMappingURL=approvalMapping.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"approvalMapping.d.ts","sourceRoot":"","sources":["../src/approvalMapping.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjE,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE;QACV,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;QACrC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;KACvB,CAAC;IACF,gBAAgB,EAAE;QAChB,EAAE,EAAE,MAAM,CAAC;QACX,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;KAC3B,GAAG,IAAI,CAAC;CACV;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,mBAAmB,GAAG,cAAc,CAgBzE;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEhE;AAED,wBAAgB,6BAA6B,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,CAM9E"}
@@ -0,0 +1,27 @@
1
+ export function mapApproval(response) {
2
+ return {
3
+ id: response.id,
4
+ status: response.status,
5
+ evaluationId: response.evaluationId,
6
+ requestedAt: response.requestedAt,
7
+ approvedAt: response.approvedAt,
8
+ rejectedAt: response.rejectedAt,
9
+ evaluation: {
10
+ agent: response.evaluation.agent,
11
+ action: response.evaluation.action,
12
+ decision: response.evaluation.decision,
13
+ amount: response.evaluation.amount,
14
+ },
15
+ executionRelease: response.executionRelease,
16
+ };
17
+ }
18
+ export function isTerminalApprovalStatus(status) {
19
+ return status === 'approved' || status === 'rejected' || status === 'expired';
20
+ }
21
+ export function resolveTerminalApprovalStatus(approval) {
22
+ if (approval.executionRelease?.status === 'expired') {
23
+ return 'expired';
24
+ }
25
+ return approval.status;
26
+ }
27
+ //# sourceMappingURL=approvalMapping.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"approvalMapping.js","sourceRoot":"","sources":["../src/approvalMapping.ts"],"names":[],"mappings":"AAwBA,MAAM,UAAU,WAAW,CAAC,QAA6B;IACvD,OAAO;QACL,EAAE,EAAE,QAAQ,CAAC,EAAE;QACf,MAAM,EAAE,QAAQ,CAAC,MAAM;QACvB,YAAY,EAAE,QAAQ,CAAC,YAAY;QACnC,WAAW,EAAE,QAAQ,CAAC,WAAW;QACjC,UAAU,EAAE,QAAQ,CAAC,UAAU;QAC/B,UAAU,EAAE,QAAQ,CAAC,UAAU;QAC/B,UAAU,EAAE;YACV,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC,KAAK;YAChC,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,MAAM;YAClC,QAAQ,EAAE,QAAQ,CAAC,UAAU,CAAC,QAAQ;YACtC,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,MAAM;SACnC;QACD,gBAAgB,EAAE,QAAQ,CAAC,gBAAgB;KAC5C,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,MAAc;IACrD,OAAO,MAAM,KAAK,UAAU,IAAI,MAAM,KAAK,UAAU,IAAI,MAAM,KAAK,SAAS,CAAC;AAChF,CAAC;AAED,MAAM,UAAU,6BAA6B,CAAC,QAAwB;IACpE,IAAI,QAAQ,CAAC,gBAAgB,EAAE,MAAM,KAAK,SAAS,EAAE,CAAC;QACpD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO,QAAQ,CAAC,MAAM,CAAC;AACzB,CAAC"}
@@ -0,0 +1,23 @@
1
+ import type { ApprovalResult, ArbiterOptions, ConsumeReleaseInput, ConsumeReleaseResult, DriftResult, EvaluateInput, EvaluateResult, GrantPermissionInput, GrantPermissionResult, HumanActionOptions, ListApprovalsOptions, ManifestWorkspace, PlanResult, RegisterAgentInput, RegisterAgentResult, RegisterPermissionInput, RegisterPermissionResult, RegisterPolicyInput, RegisterPolicyResult, RejectApprovalOptions, StateSignatureResult, SyncRegistryResult } from './types.js';
2
+ /**
3
+ * @deprecated Use {@link ArbiterAdmin} for control-plane operations and {@link ArbiterRuntime} for autonomous agent execution.
4
+ */
5
+ export declare class Arbiter {
6
+ private readonly admin;
7
+ constructor(options: ArbiterOptions);
8
+ registerAgent(input: RegisterAgentInput): Promise<RegisterAgentResult>;
9
+ registerPermission(input: RegisterPermissionInput): Promise<RegisterPermissionResult>;
10
+ grantPermission(input: GrantPermissionInput): Promise<GrantPermissionResult>;
11
+ registerPolicy(input: RegisterPolicyInput): Promise<RegisterPolicyResult>;
12
+ evaluate(input: EvaluateInput): Promise<EvaluateResult>;
13
+ getApproval(id: string): Promise<ApprovalResult>;
14
+ listApprovals(options?: ListApprovalsOptions): Promise<ApprovalResult[]>;
15
+ approve(approvalRequestId: string, options: HumanActionOptions): Promise<ApprovalResult>;
16
+ reject(approvalRequestId: string, options: RejectApprovalOptions): Promise<ApprovalResult>;
17
+ consumeRelease(input: ConsumeReleaseInput): Promise<ConsumeReleaseResult>;
18
+ syncRegistry(manifest: ManifestWorkspace): Promise<SyncRegistryResult>;
19
+ plan(manifest: ManifestWorkspace): Promise<PlanResult>;
20
+ getDrift(): Promise<DriftResult>;
21
+ getStateSignature(): Promise<StateSignatureResult>;
22
+ }
23
+ //# sourceMappingURL=arbiter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"arbiter.d.ts","sourceRoot":"","sources":["../src/arbiter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,cAAc,EACd,cAAc,EACd,mBAAmB,EACnB,oBAAoB,EACpB,WAAW,EACX,aAAa,EACb,cAAc,EACd,oBAAoB,EACpB,qBAAqB,EACrB,kBAAkB,EAClB,oBAAoB,EACpB,iBAAiB,EACjB,UAAU,EACV,kBAAkB,EAClB,mBAAmB,EACnB,uBAAuB,EACvB,wBAAwB,EACxB,mBAAmB,EACnB,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,EACpB,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAIpB;;GAEG;AACH,qBAAa,OAAO;IAClB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAe;gBAElB,OAAO,EAAE,cAAc;IAW7B,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAItE,kBAAkB,CAC7B,KAAK,EAAE,uBAAuB,GAC7B,OAAO,CAAC,wBAAwB,CAAC;IAIvB,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAI5E,cAAc,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAIzE,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC;IAIvD,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAIhD,aAAa,CACxB,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,cAAc,EAAE,CAAC;IAIf,OAAO,CAClB,iBAAiB,EAAE,MAAM,EACzB,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,cAAc,CAAC;IAIb,MAAM,CACjB,iBAAiB,EAAE,MAAM,EACzB,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,cAAc,CAAC;IAIb,cAAc,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAIzE,YAAY,CAAC,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAItE,IAAI,CAAC,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAAC,UAAU,CAAC;IAItD,QAAQ,IAAI,OAAO,CAAC,WAAW,CAAC;IAIhC,iBAAiB,IAAI,OAAO,CAAC,oBAAoB,CAAC;CAGhE"}