@aexhq/sdk 0.40.16 → 0.41.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 (130) hide show
  1. package/README.md +25 -25
  2. package/dist/_contracts/api-key.d.ts +6 -4
  3. package/dist/_contracts/api-key.js +20 -7
  4. package/dist/_contracts/connection-ticket.d.ts +5 -5
  5. package/dist/_contracts/connection-ticket.js +7 -7
  6. package/dist/_contracts/error-codes.d.ts +1 -1
  7. package/dist/_contracts/error-codes.js +4 -4
  8. package/dist/_contracts/error-factory.js +1 -1
  9. package/dist/_contracts/event-envelope.d.ts +41 -41
  10. package/dist/_contracts/event-envelope.js +49 -49
  11. package/dist/_contracts/event-stream-client.d.ts +9 -9
  12. package/dist/_contracts/event-stream-client.js +5 -5
  13. package/dist/_contracts/event-view.d.ts +6 -6
  14. package/dist/_contracts/event-view.js +12 -12
  15. package/dist/_contracts/http.js +1 -1
  16. package/dist/_contracts/index.d.ts +10 -10
  17. package/dist/_contracts/index.js +9 -9
  18. package/dist/_contracts/models.d.ts +17 -17
  19. package/dist/_contracts/models.js +14 -14
  20. package/dist/_contracts/operations.d.ts +79 -82
  21. package/dist/_contracts/operations.js +233 -243
  22. package/dist/_contracts/provider-support.d.ts +2 -2
  23. package/dist/_contracts/runner-event.d.ts +8 -8
  24. package/dist/_contracts/runner-event.js +9 -9
  25. package/dist/_contracts/runtime-manifest.d.ts +12 -12
  26. package/dist/_contracts/runtime-manifest.js +1 -1
  27. package/dist/_contracts/runtime-sizes.d.ts +12 -12
  28. package/dist/_contracts/runtime-sizes.js +18 -18
  29. package/dist/_contracts/runtime-types.d.ts +117 -117
  30. package/dist/_contracts/runtime-types.js +2 -2
  31. package/dist/_contracts/sdk-errors.d.ts +3 -3
  32. package/dist/_contracts/sdk-errors.js +4 -4
  33. package/dist/_contracts/sdk-secrets.js +10 -10
  34. package/dist/_contracts/session-artifacts.d.ts +151 -0
  35. package/dist/_contracts/session-artifacts.js +234 -0
  36. package/dist/_contracts/{run-config.d.ts → session-config.d.ts} +29 -29
  37. package/dist/_contracts/{run-config.js → session-config.js} +37 -37
  38. package/dist/_contracts/session-cost.d.ts +140 -0
  39. package/dist/_contracts/{run-cost.js → session-cost.js} +94 -94
  40. package/dist/_contracts/{run-custody.d.ts → session-custody.d.ts} +16 -16
  41. package/dist/_contracts/{run-custody.js → session-custody.js} +42 -42
  42. package/dist/_contracts/session-record.d.ts +112 -0
  43. package/dist/_contracts/{run-record.js → session-record.js} +23 -23
  44. package/dist/_contracts/session-retention.d.ts +209 -0
  45. package/dist/_contracts/{run-retention.js → session-retention.js} +116 -116
  46. package/dist/_contracts/{run-unit.d.ts → session-unit.d.ts} +38 -38
  47. package/dist/_contracts/{run-unit.js → session-unit.js} +33 -33
  48. package/dist/_contracts/side-effect-audit.d.ts +14 -14
  49. package/dist/_contracts/side-effect-audit.js +38 -38
  50. package/dist/_contracts/sse.d.ts +1 -1
  51. package/dist/_contracts/sse.js +0 -0
  52. package/dist/_contracts/stable.d.ts +1 -1
  53. package/dist/_contracts/stable.js +1 -1
  54. package/dist/_contracts/status.d.ts +18 -18
  55. package/dist/_contracts/status.js +19 -19
  56. package/dist/_contracts/submission.d.ts +101 -99
  57. package/dist/_contracts/submission.js +96 -96
  58. package/dist/_contracts/{run-trace.d.ts → turn-trace.d.ts} +1 -1
  59. package/dist/_contracts/webhook-verify.d.ts +1 -1
  60. package/dist/_contracts/webhook-verify.js +1 -1
  61. package/dist/agents-md.d.ts +4 -4
  62. package/dist/agents-md.js +5 -5
  63. package/dist/agents-md.js.map +1 -1
  64. package/dist/bundle.d.ts +1 -1
  65. package/dist/bundle.js +1 -1
  66. package/dist/bundle.js.map +1 -1
  67. package/dist/cli.mjs +578 -621
  68. package/dist/cli.mjs.sha256 +1 -1
  69. package/dist/client.d.ts +141 -155
  70. package/dist/client.js +236 -245
  71. package/dist/client.js.map +1 -1
  72. package/dist/fetch-archive.js +3 -3
  73. package/dist/file.d.ts +7 -7
  74. package/dist/file.js +8 -8
  75. package/dist/file.js.map +1 -1
  76. package/dist/index.d.ts +10 -10
  77. package/dist/index.js +8 -8
  78. package/dist/index.js.map +1 -1
  79. package/dist/mcp-server.d.ts +1 -1
  80. package/dist/retry.d.ts +1 -1
  81. package/dist/secret.d.ts +6 -6
  82. package/dist/secret.js +6 -6
  83. package/dist/secret.js.map +1 -1
  84. package/dist/skill.d.ts +2 -2
  85. package/dist/skill.js +3 -3
  86. package/dist/skill.js.map +1 -1
  87. package/dist/tool.js +2 -2
  88. package/dist/tool.js.map +1 -1
  89. package/dist/version.d.ts +1 -1
  90. package/dist/version.js +1 -1
  91. package/dist/version.js.map +1 -1
  92. package/docs/authentication.md +11 -11
  93. package/docs/billing.md +3 -3
  94. package/docs/cleanup.md +5 -5
  95. package/docs/concepts/agent-tools.md +5 -5
  96. package/docs/concepts/composition.md +3 -3
  97. package/docs/concepts/providers-and-runtimes.md +3 -3
  98. package/docs/concepts/{runs.md → sessions.md} +8 -8
  99. package/docs/concepts/subagents.md +16 -16
  100. package/docs/credentials.md +7 -7
  101. package/docs/defaults.md +14 -14
  102. package/docs/errors.md +10 -10
  103. package/docs/events.md +26 -26
  104. package/docs/files.md +267 -0
  105. package/docs/limits-and-quotas.md +35 -35
  106. package/docs/limits.md +6 -6
  107. package/docs/mcp.md +3 -3
  108. package/docs/networking.md +24 -24
  109. package/docs/provider-runtime-capabilities.md +1 -1
  110. package/docs/public-surface.json +6 -6
  111. package/docs/quickstart.md +13 -13
  112. package/docs/release.md +5 -5
  113. package/docs/retries.md +3 -3
  114. package/docs/secrets.md +16 -16
  115. package/docs/session-config.md +58 -0
  116. package/docs/{run-record.md → session-record.md} +16 -16
  117. package/docs/skills.md +9 -9
  118. package/docs/vision-skills.md +7 -7
  119. package/docs/webhooks.md +11 -11
  120. package/examples/feature-tour.ts +17 -17
  121. package/examples/spike-settle-latency.ts +11 -11
  122. package/package.json +1 -1
  123. package/dist/_contracts/run-artifacts.d.ts +0 -49
  124. package/dist/_contracts/run-artifacts.js +0 -102
  125. package/dist/_contracts/run-cost.d.ts +0 -140
  126. package/dist/_contracts/run-record.d.ts +0 -116
  127. package/dist/_contracts/run-retention.d.ts +0 -209
  128. package/docs/outputs.md +0 -267
  129. package/docs/run-config.md +0 -58
  130. /package/dist/_contracts/{run-trace.js → turn-trace.js} +0 -0
@@ -2,7 +2,7 @@ export const CUSTODY_MANIFEST_SCHEMA_VERSION = 1;
2
2
  export const CUSTODY_REDACTION_SCANNER_VERSION = 1;
3
3
  export const CUSTODY_MANIFEST_KIND = "aex.custody_manifest.v1";
4
4
  export const CUSTODY_MANIFEST_CONTENT_TYPE = "application/json; charset=utf-8";
5
- export const CUSTODY_MANIFEST_RUN_REL_PATH = "metadata/custody.json";
5
+ export const CUSTODY_MANIFEST_SESSION_REL_PATH = "metadata/custody.json";
6
6
  export const CUSTODY_SECRET_CLASSES = [
7
7
  "provider_api_key",
8
8
  "mcp_credential",
@@ -15,9 +15,9 @@ export const CUSTODY_RESOURCE_CLASSES = [
15
15
  "proxy_token",
16
16
  "execution_secret",
17
17
  "event_archive",
18
- "run_output",
19
- "run_log",
20
- "run_asset"
18
+ "session_file",
19
+ "session_log",
20
+ "session_asset"
21
21
  ];
22
22
  export const CUSTODY_EXPOSURE_SURFACES = [
23
23
  "aex_vault",
@@ -27,7 +27,7 @@ export const CUSTODY_EXPOSURE_SURFACES = [
27
27
  "dashboard_proxy",
28
28
  "api_provider_proxy",
29
29
  "api_mcp_proxy",
30
- "run_artifact_store",
30
+ "session_artifact_store",
31
31
  "coordinator_event_archive"
32
32
  ];
33
33
  export const CUSTODY_EXPOSURE_ACCESS_KINDS = [
@@ -63,11 +63,11 @@ export const CUSTODY_CLEANUP_STATUSES = [
63
63
  "pending"
64
64
  ];
65
65
  export const CUSTODY_EVIDENCE_SOURCES = [
66
- "run_row",
66
+ "session_row",
67
67
  "runtime_manifest",
68
68
  "terminal_event",
69
69
  "cleanup_step",
70
- "output_capture",
70
+ "file_capture",
71
71
  "proxy_audit",
72
72
  "provider_cleanup_summary"
73
73
  ];
@@ -95,8 +95,8 @@ export class FakeCustodyManifestObjectStore {
95
95
  assertPublicSafeCustodyPayload(object.manifest);
96
96
  this.#objects.set(object.key, cloneJson(object.manifest));
97
97
  }
98
- getByRunId(runId) {
99
- return this.get(custodyManifestObjectKey(runId));
98
+ getBySessionId(sessionId) {
99
+ return this.get(custodyManifestObjectKey(sessionId));
100
100
  }
101
101
  get(key) {
102
102
  const object = this.#objects.get(key);
@@ -106,9 +106,9 @@ export class FakeCustodyManifestObjectStore {
106
106
  return Object.freeze([...this.#objects.keys()].sort());
107
107
  }
108
108
  }
109
- export function custodyManifestObjectKey(runId) {
110
- assertSafeIdentifier(runId, "runId");
111
- return `runs/${runId}/${CUSTODY_MANIFEST_RUN_REL_PATH}`;
109
+ export function custodyManifestObjectKey(sessionId) {
110
+ assertSafeIdentifier(sessionId, "sessionId");
111
+ return `sessions/${sessionId}/${CUSTODY_MANIFEST_SESSION_REL_PATH}`;
112
112
  }
113
113
  export function createCustodyManifestWriter(store) {
114
114
  return {
@@ -119,7 +119,7 @@ export function createCustodyManifestWriter(store) {
119
119
  }
120
120
  export async function writeCustodyManifest(store, input) {
121
121
  const manifest = buildCustodyManifest(input);
122
- const key = custodyManifestObjectKey(manifest.run.runId);
122
+ const key = custodyManifestObjectKey(manifest.session.sessionId);
123
123
  await store.putCustodyManifestObject({
124
124
  key,
125
125
  contentType: CUSTODY_MANIFEST_CONTENT_TYPE,
@@ -128,8 +128,8 @@ export async function writeCustodyManifest(store, input) {
128
128
  return Object.freeze({
129
129
  status: "written",
130
130
  schemaVersion: CUSTODY_MANIFEST_SCHEMA_VERSION,
131
- runId: manifest.run.runId,
132
- workspaceId: manifest.run.workspaceId,
131
+ sessionId: manifest.session.sessionId,
132
+ workspaceId: manifest.session.workspaceId,
133
133
  key,
134
134
  writtenAt: manifest.finalizedAt ?? manifest.generatedAt
135
135
  });
@@ -143,7 +143,7 @@ export function buildCustodyManifest(input) {
143
143
  kind: CUSTODY_MANIFEST_KIND,
144
144
  generatedAt: assertTimestamp(input.generatedAt, "generatedAt"),
145
145
  ...(input.finalizedAt ? { finalizedAt: assertTimestamp(input.finalizedAt, "finalizedAt") } : {}),
146
- run: normalizeRun(input.run),
146
+ session: normalizeSession(input.session),
147
147
  secrets,
148
148
  resources,
149
149
  cleanup,
@@ -168,14 +168,14 @@ export function assertPublicSafeCustodyPayload(input) {
168
168
  throw new CustodyManifestRedactionError(findings);
169
169
  }
170
170
  }
171
- function normalizeRun(input) {
171
+ function normalizeSession(input) {
172
172
  return Object.freeze({
173
- runId: assertSafeIdentifier(input.runId, "run.runId"),
174
- workspaceId: assertSafeIdentifier(input.workspaceId, "run.workspaceId"),
175
- provider: assertSafeMetadataString(input.provider, "run.provider"),
176
- terminalStatus: assertSafeMetadataString(input.terminalStatus, "run.terminalStatus"),
177
- ...(input.createdAt ? { createdAt: assertTimestamp(input.createdAt, "run.createdAt") } : {}),
178
- ...(input.terminalAt ? { terminalAt: assertTimestamp(input.terminalAt, "run.terminalAt") } : {})
173
+ sessionId: assertSafeIdentifier(input.sessionId, "session.sessionId"),
174
+ workspaceId: assertSafeIdentifier(input.workspaceId, "session.workspaceId"),
175
+ provider: assertSafeMetadataString(input.provider, "session.provider"),
176
+ terminalStatus: assertSafeMetadataString(input.terminalStatus, "session.terminalStatus"),
177
+ ...(input.createdAt ? { createdAt: assertTimestamp(input.createdAt, "session.createdAt") } : {}),
178
+ ...(input.terminalAt ? { terminalAt: assertTimestamp(input.terminalAt, "session.terminalAt") } : {})
179
179
  });
180
180
  }
181
181
  function normalizeSecretClass(input) {
@@ -329,8 +329,8 @@ function scanStringValue(value, path, findings) {
329
329
  }
330
330
  /**
331
331
  * A pattern fires on a value if its `regex` matches AND — when the pattern
332
- * carries an `accept` predicate — at least one matched run is accepted by it.
333
- * The predicate lets a shape-matched run be VETOED per-match (the entropy
332
+ * carries an `accept` predicate — at least one matched sequence is accepted by it.
333
+ * The predicate lets a shape-matched sequence be VETOED per-match (the entropy
334
334
  * catch-all uses it to skip content-addressed hashes and low-entropy slugs that
335
335
  * its coarse regex would otherwise flag); shape-only patterns have no predicate.
336
336
  */
@@ -362,56 +362,56 @@ const forbiddenStringPatterns = Object.freeze([
362
362
  regex: /\b(?:sk-[A-Za-z0-9_-]{16,}|xox[baprs]-[A-Za-z0-9-]{8,}|AIza[A-Za-z0-9_-]{8,})/i
363
363
  },
364
364
  { reason: "signed_url", regex: /[?&](?:X-Amz-Signature|X-Amz-Credential|X-Amz-Algorithm|AWSAccessKeyId)=/i },
365
- { reason: "object_store_key", regex: /(^|[\s"'`])(?:runs|assets)\/[^?<#\s"'`]+/i },
365
+ { reason: "object_store_key", regex: /(^|[\s"'`])(?:sessions|assets)\/[^?<#\s"'`]+/i },
366
366
  { reason: "vault_id", regex: /\b(?:vault|vlt|secret)[_:-][A-Za-z0-9][A-Za-z0-9_-]{7,}\b/i },
367
367
  {
368
368
  reason: "private_resource_handle",
369
- // `<keyword><sep><id>` opaque handles (`session_a1B2c3D4e5`, `file_9f8e7d…`).
369
+ // `<keyword><sep><id>` opaque handles (`machine_a1B2c3D4e5`, `resource_9f8e7d...`).
370
370
  // The keyword set overlaps ordinary prose, so require the id segment to
371
371
  // carry a digit. That keeps genuine minted handles flagged while avoiding
372
372
  // dictionary-word chains such as `agent_decision_failure`.
373
- regex: /\b(?:machine|session|agent|file|skill|env|resource|handle|token_hash|bearer_hash)[_:-][A-Za-z0-9][A-Za-z0-9_-]{7,}\b/i,
373
+ regex: /\b(?:machine|agent|resource|handle|token_hash|bearer_hash)[_:-][A-Za-z0-9][A-Za-z0-9_-]{7,}\b/i,
374
374
  accept: isMintedResourceHandle
375
375
  },
376
376
  {
377
377
  reason: "high_entropy_token",
378
- // Catch-all for an unrecognised opaque secret blob. The candidate run
378
+ // Catch-all for an unrecognised opaque secret blob. The candidate sequence
379
379
  // EXCLUDES `_` (so `SCREAMING_SNAKE` env names and `slug_with_words` URL
380
- // segments split instead of fusing into a phantom 40-char run — the live
380
+ // segments split instead of fusing into a phantom 40-char sequence — the live
381
381
  // false positive was `ted_season_2_peacock_official_discussion_thread` in
382
382
  // web-search result text and a fetched URL), and the `accept` predicate
383
383
  // vetoes content-addressed hashes (md5/sha1/sha256 digests — the platform's
384
- // OWN asset filenames) and low-entropy / single-class runs so only genuine
384
+ // OWN asset filenames) and low-entropy / single-class sessions so only genuine
385
385
  // opaque secrets remain. Slash-bearing secrets (signed URLs, connection
386
386
  // strings, `Bearer …`) are covered by the named patterns above.
387
387
  regex: /\b[A-Za-z0-9-]{40,}\b/,
388
- accept: isHighEntropySecretRun
388
+ accept: isHighEntropySecretSequence
389
389
  }
390
390
  ]);
391
391
  /** A content-addressed hash (md5/sha1/sha256 hex digest) — the platform's own
392
392
  * asset filenames and content references. Exempt from the entropy catch-all so
393
- * a captured output named after its sha256 (or a hash echoed in tool-result
394
- * text) is not misclassified as a leaked secret. */
395
- const CONTENT_HASH_RUN = /^(?:[0-9a-f]{32}|[0-9a-f]{40}|[0-9a-f]{64})$/i;
393
+ * a captured file named after its sha256 (or a hash echoed in tool-result text)
394
+ * is not misclassified as a leaked secret. */
395
+ const CONTENT_HASH_SEQUENCE = /^(?:[0-9a-f]{32}|[0-9a-f]{40}|[0-9a-f]{64})$/i;
396
396
  /**
397
- * Decide whether a coarse `[A-Za-z0-9-]{40,}` run is a genuine opaque secret.
397
+ * Decide whether a coarse `[A-Za-z0-9-]{40,}` sequence is a genuine opaque secret.
398
398
  * Rejects content-addressed hashes, then requires both character-class
399
399
  * diversity (≥2 of lower/upper/digit) and high Shannon entropy — the property
400
400
  * that separates an opaque key blob from a long dictionary-ish identifier. A
401
401
  * real prefixless secret (base64url/alnum-mixed) clears both gates; a hash, a
402
- * hyphenated slug, or a single-class run does not.
402
+ * hyphenated slug, or a single-class sequence does not.
403
403
  */
404
- function isHighEntropySecretRun(run) {
405
- if (CONTENT_HASH_RUN.test(run)) {
404
+ function isHighEntropySecretSequence(sequence) {
405
+ if (CONTENT_HASH_SEQUENCE.test(sequence)) {
406
406
  return false;
407
407
  }
408
- if (!/[A-Za-z]/.test(run) || !/\d/.test(run)) {
408
+ if (!/[A-Za-z]/.test(sequence) || !/\d/.test(sequence)) {
409
409
  return false;
410
410
  }
411
- if (highEntropyCharClassCount(run) < 2) {
411
+ if (highEntropyCharClassCount(sequence) < 2) {
412
412
  return false;
413
413
  }
414
- return highEntropyShannonBits(run) >= 3.0;
414
+ return highEntropyShannonBits(sequence) >= 3.0;
415
415
  }
416
416
  function isMintedResourceHandle(match) {
417
417
  const separatorIndex = match.search(/[_:-]/);
@@ -0,0 +1,112 @@
1
+ import type { SessionCostTelemetry } from "./session-cost.js";
2
+ import { type CustodyManifestV1, type CustodyRedactionFinding } from "./session-custody.js";
3
+ import type { AexEvent } from "./event-envelope.js";
4
+ import type { SessionRecord, SessionFile } from "./runtime-types.js";
5
+ import type { PlatformSubmission } from "./submission.js";
6
+ export declare const SESSION_RECORD_SCHEMA_VERSION: "aex.session-record.v1";
7
+ export declare const SESSION_RECORD_MANIFEST_SCHEMA_VERSION: "aex.session-record.manifest.v1";
8
+ export type SessionRecordArchiveNamespaceV1 = "metadata" | "events" | "files";
9
+ export type SessionRecordFileStatusV1 = "present" | "absent" | "pending" | "unavailable" | "not_applicable" | "error";
10
+ export type SessionRecordArchiveFileRoleV1 = "session_metadata" | "submission_snapshot" | "cost" | "custody" | "typed_events" | "coordinator_events_manifest" | "file";
11
+ export interface SessionRecordSubmissionSnapshotV1 {
12
+ readonly submission: PlatformSubmission;
13
+ }
14
+ export interface SessionRecordCostV1 {
15
+ readonly status: SessionRecordFileStatusV1;
16
+ readonly telemetry?: SessionCostTelemetry;
17
+ }
18
+ export interface SessionRecordMetadataV1 {
19
+ readonly session: SessionRecord;
20
+ readonly submission?: SessionRecordSubmissionSnapshotV1;
21
+ readonly cost?: SessionRecordCostV1;
22
+ readonly custody?: CustodyManifestV1;
23
+ }
24
+ export interface SessionRecordEventsV1 {
25
+ /** Typed `channel: "event"` records in the SDK `events/events.jsonl` export. */
26
+ readonly typed: readonly AexEvent[];
27
+ }
28
+ export interface SessionRecordV1 {
29
+ readonly schemaVersion: typeof SESSION_RECORD_SCHEMA_VERSION;
30
+ readonly sessionId: string;
31
+ readonly metadata: SessionRecordMetadataV1;
32
+ readonly events: SessionRecordEventsV1;
33
+ readonly sessionFiles: readonly SessionFile[];
34
+ readonly manifest: SessionRecordManifestV1;
35
+ }
36
+ export interface SessionRecordNamespaceV1 {
37
+ readonly name: SessionRecordArchiveNamespaceV1;
38
+ readonly prefix: `${SessionRecordArchiveNamespaceV1}/`;
39
+ readonly status: SessionRecordFileStatusV1;
40
+ readonly description: string;
41
+ }
42
+ export interface SessionRecordArchiveFileV1 {
43
+ readonly namespace: SessionRecordArchiveNamespaceV1;
44
+ readonly path: string;
45
+ readonly role: SessionRecordArchiveFileRoleV1;
46
+ readonly status: SessionRecordFileStatusV1;
47
+ readonly id?: string;
48
+ readonly filename?: string | null;
49
+ readonly sizeBytes?: number;
50
+ readonly contentType?: string;
51
+ readonly recordCount?: number;
52
+ }
53
+ export interface SessionRecordArtifactSummaryV1 {
54
+ readonly id: string;
55
+ readonly filename: string | null;
56
+ readonly sizeBytes?: number;
57
+ readonly contentType?: string;
58
+ }
59
+ export interface SessionRecordDownloadErrorV1 {
60
+ readonly namespace: "files";
61
+ readonly id: string;
62
+ readonly filename: string | null;
63
+ readonly message: string;
64
+ }
65
+ export interface SessionRecordManifestV1 {
66
+ readonly schemaVersion: typeof SESSION_RECORD_MANIFEST_SCHEMA_VERSION;
67
+ readonly sessionRecordSchemaVersion: typeof SESSION_RECORD_SCHEMA_VERSION;
68
+ readonly sessionId: string;
69
+ readonly namespaces: readonly SessionRecordNamespaceV1[];
70
+ readonly files: readonly SessionRecordArchiveFileV1[];
71
+ /** Captured session files included in the archive. */
72
+ readonly sessionFiles: readonly SessionRecordArtifactSummaryV1[];
73
+ readonly errors: readonly SessionRecordDownloadErrorV1[];
74
+ }
75
+ export interface BuildSessionRecordDownloadManifestV1Input {
76
+ readonly sessionId: string;
77
+ readonly sessionFiles: readonly SessionRecordArtifactSummaryV1[];
78
+ readonly errors?: readonly SessionRecordDownloadErrorV1[];
79
+ readonly typedEventCount?: number;
80
+ readonly submission?: SessionRecordFileManifestInputV1;
81
+ readonly cost?: SessionRecordFileManifestInputV1;
82
+ readonly custody?: SessionRecordFileManifestInputV1;
83
+ readonly coordinatorEventsManifest?: SessionRecordFileManifestInputV1;
84
+ }
85
+ export interface SessionRecordFileManifestInputV1 {
86
+ readonly status: SessionRecordFileStatusV1;
87
+ readonly recordCount?: number;
88
+ }
89
+ export interface SessionRecordArchiveEntryForRedactionV1 {
90
+ readonly path: string;
91
+ readonly bytes: Uint8Array;
92
+ readonly contentType?: string;
93
+ /**
94
+ * Customer-authored file bytes are intentionally outside the public-record
95
+ * redaction guarantee. Metadata, event exports, and manifests remain scanned.
96
+ */
97
+ readonly customerContent?: boolean;
98
+ }
99
+ export interface SessionRecordArchiveRedactionFindingV1 {
100
+ readonly entryPath: string;
101
+ readonly path: string;
102
+ readonly reason: CustodyRedactionFinding["reason"];
103
+ readonly valueLength?: number;
104
+ }
105
+ export declare class SessionRecordArchiveRedactionError extends Error {
106
+ readonly code = "session_record_archive_not_public_safe";
107
+ readonly findings: readonly SessionRecordArchiveRedactionFindingV1[];
108
+ constructor(findings: readonly SessionRecordArchiveRedactionFindingV1[]);
109
+ }
110
+ export declare function buildSessionRecordDownloadManifestV1(input: BuildSessionRecordDownloadManifestV1Input): SessionRecordManifestV1;
111
+ export declare function scanSessionRecordArchiveEntriesV1(entries: readonly SessionRecordArchiveEntryForRedactionV1[]): readonly SessionRecordArchiveRedactionFindingV1[];
112
+ export declare function assertSessionRecordArchivePublicSafeV1(entries: readonly SessionRecordArchiveEntryForRedactionV1[]): void;
@@ -1,29 +1,29 @@
1
- import { scanCustodyPayloadForSensitiveValues } from "./run-custody.js";
2
- export const RUN_RECORD_SCHEMA_VERSION = "aex.run-record.v1";
3
- export const RUN_RECORD_MANIFEST_SCHEMA_VERSION = "aex.run-record.manifest.v1";
4
- export class RunRecordArchiveRedactionError extends Error {
5
- code = "run_record_archive_not_public_safe";
1
+ import { scanCustodyPayloadForSensitiveValues } from "./session-custody.js";
2
+ export const SESSION_RECORD_SCHEMA_VERSION = "aex.session-record.v1";
3
+ export const SESSION_RECORD_MANIFEST_SCHEMA_VERSION = "aex.session-record.manifest.v1";
4
+ export class SessionRecordArchiveRedactionError extends Error {
5
+ code = "session_record_archive_not_public_safe";
6
6
  findings;
7
7
  constructor(findings) {
8
- super(`run record archive contains non-public data at ${formatArchiveFindingPaths(findings)}`);
9
- this.name = "RunRecordArchiveRedactionError";
8
+ super(`session record archive contains non-public data at ${formatArchiveFindingPaths(findings)}`);
9
+ this.name = "SessionRecordArchiveRedactionError";
10
10
  this.findings = Object.freeze([...findings]);
11
11
  }
12
12
  }
13
- export function buildRunRecordDownloadManifestV1(input) {
14
- const outputs = input.outputs.map((file) => normalizeArtifactSummary(file));
13
+ export function buildSessionRecordDownloadManifestV1(input) {
14
+ const sessionFiles = input.sessionFiles.map((file) => normalizeArtifactSummary(file));
15
15
  const errors = (input.errors ?? []).map((error) => Object.freeze({ ...error }));
16
16
  return Object.freeze({
17
- schemaVersion: RUN_RECORD_MANIFEST_SCHEMA_VERSION,
18
- runRecordSchemaVersion: RUN_RECORD_SCHEMA_VERSION,
19
- runId: input.runId,
17
+ schemaVersion: SESSION_RECORD_MANIFEST_SCHEMA_VERSION,
18
+ sessionRecordSchemaVersion: SESSION_RECORD_SCHEMA_VERSION,
19
+ sessionId: input.sessionId,
20
20
  namespaces: Object.freeze([
21
- namespace("metadata", "Run metadata, submission snapshot, custody, and cost files."),
21
+ namespace("metadata", "SessionRecord metadata, submission snapshot, custody, and cost files."),
22
22
  namespace("events", "Typed event-channel exports."),
23
- namespace("outputs", "Captured deliverables produced by the run.")
23
+ namespace("files", "Captured files produced by the session.")
24
24
  ]),
25
25
  files: Object.freeze([
26
- file("metadata", "metadata/run.json", "run_metadata", "present"),
26
+ file("metadata", "metadata/session.json", "session_metadata", "present"),
27
27
  file("metadata", "metadata/submission.json", "submission_snapshot", input.submission?.status ?? "unavailable"),
28
28
  file("metadata", "metadata/cost.json", "cost", input.cost?.status ?? "pending"),
29
29
  file("metadata", "metadata/custody.json", "custody", input.custody?.status ?? "pending"),
@@ -31,9 +31,9 @@ export function buildRunRecordDownloadManifestV1(input) {
31
31
  recordCount: input.typedEventCount ?? 0
32
32
  }),
33
33
  file("events", "events/manifest.json", "coordinator_events_manifest", input.coordinatorEventsManifest?.status ?? "unavailable"),
34
- ...outputs.map((output) => artifactFile("outputs", "output", "outputs/", output))
34
+ ...sessionFiles.map((fileSummary) => artifactFile("files", "file", "files/", fileSummary))
35
35
  ]),
36
- outputs: Object.freeze(outputs),
36
+ sessionFiles: Object.freeze(sessionFiles),
37
37
  errors: Object.freeze(errors)
38
38
  });
39
39
  }
@@ -74,7 +74,7 @@ function normalizeArtifactSummary(input) {
74
74
  ...(input.contentType !== undefined ? { contentType: input.contentType } : {})
75
75
  });
76
76
  }
77
- export function scanRunRecordArchiveEntriesV1(entries) {
77
+ export function scanSessionRecordArchiveEntriesV1(entries) {
78
78
  const findings = [];
79
79
  for (const entry of entries) {
80
80
  if (entry.customerContent || !shouldScanArchiveEntry(entry)) {
@@ -86,14 +86,14 @@ export function scanRunRecordArchiveEntriesV1(entries) {
86
86
  }
87
87
  return Object.freeze(findings);
88
88
  }
89
- export function assertRunRecordArchivePublicSafeV1(entries) {
90
- const findings = scanRunRecordArchiveEntriesV1(entries);
89
+ export function assertSessionRecordArchivePublicSafeV1(entries) {
90
+ const findings = scanSessionRecordArchiveEntriesV1(entries);
91
91
  if (findings.length > 0) {
92
- throw new RunRecordArchiveRedactionError(findings);
92
+ throw new SessionRecordArchiveRedactionError(findings);
93
93
  }
94
94
  }
95
95
  function shouldScanArchiveEntry(entry) {
96
- if (entry.path.startsWith("outputs/")) {
96
+ if (entry.path.startsWith("files/")) {
97
97
  return false;
98
98
  }
99
99
  const contentType = entry.contentType?.toLowerCase() ?? "";
@@ -127,7 +127,7 @@ function isAllowedArchiveHighEntropyField(entryPath, finding) {
127
127
  if (finding.reason !== "high_entropy_token" || !entryPath.endsWith("manifest.json")) {
128
128
  return false;
129
129
  }
130
- return /^\$(?:\.files\[\d+\]|\.outputs\[\d+\])\.id$/.test(finding.path);
130
+ return /^\$(?:\.files\[\d+\]|\.sessionFiles\[\d+\])\.id$/.test(finding.path);
131
131
  }
132
132
  function parseArchiveTextValues(path, text) {
133
133
  if (/\.json$/i.test(path)) {
@@ -0,0 +1,209 @@
1
+ import type { SessionControlStatus } from "./status.js";
2
+ export declare const SESSION_RETENTION_SCHEMA_VERSION = 1;
3
+ export declare const SESSION_DELETION_MANIFEST_KIND = "aex.session_deletion_manifest.v1";
4
+ export declare const SESSION_DELETION_JOB_KIND = "aex.session_deletion_job.v1";
5
+ export declare const SESSION_DELETION_MANIFEST_CONTENT_TYPE = "application/json; charset=utf-8";
6
+ export declare const SESSION_RETENTION_REDACTION_SCANNER_VERSION = 1;
7
+ export declare const SESSION_DELETION_REASONS: readonly ["manual_delete", "retention_gc"];
8
+ export type SessionDeletionReason = (typeof SESSION_DELETION_REASONS)[number];
9
+ export declare const SESSION_DELETION_MANIFEST_MODES: readonly ["dry_run", "final"];
10
+ export type SessionDeletionManifestMode = (typeof SESSION_DELETION_MANIFEST_MODES)[number];
11
+ export declare const SESSION_DELETION_CANDIDATE_STATUSES: readonly ["selected", "blocked"];
12
+ export type SessionDeletionCandidateStatus = (typeof SESSION_DELETION_CANDIDATE_STATUSES)[number];
13
+ export declare const SESSION_DELETION_BLOCKERS: readonly ["non_terminal", "retention_policy_disabled", "unexpired", "held", "retention_exempt", "unresolved_cleanup", "unresolved_custody"];
14
+ export type SessionDeletionBlocker = (typeof SESSION_DELETION_BLOCKERS)[number];
15
+ export declare const SESSION_DELETION_COUNT_CLASSES: readonly ["object_store_objects", "files", "logs", "events", "assets", "db_event_rows", "db_file_rows", "capture_failures", "storage_samples", "custody_manifests"];
16
+ export type SessionDeletionCountClass = (typeof SESSION_DELETION_COUNT_CLASSES)[number];
17
+ export declare const SESSION_DELETION_COUNT_STATUSES: readonly ["counted", "not_counted", "partial", "failed"];
18
+ export type SessionDeletionCountStatus = (typeof SESSION_DELETION_COUNT_STATUSES)[number];
19
+ export declare const SESSION_DELETION_JOB_STATUSES: readonly ["queued", "planning", "blocked", "manifest_written", "deleting", "delete_failed", "completed", "failed"];
20
+ export type SessionDeletionJobStatus = (typeof SESSION_DELETION_JOB_STATUSES)[number];
21
+ export declare const SESSION_DELETION_PROOF_STATUSES: readonly ["not_started", "running", "completed", "failed"];
22
+ export type SessionDeletionProofStatus = (typeof SESSION_DELETION_PROOF_STATUSES)[number];
23
+ export declare const SESSION_DELETION_WRITE_STATUSES: readonly ["not_written", "written", "write_failed"];
24
+ export type SessionDeletionWriteStatus = (typeof SESSION_DELETION_WRITE_STATUSES)[number];
25
+ export declare const SESSION_RETENTION_EXCLUDED_VALUE_CLASSES: readonly ["raw_paths", "object_keys", "filenames", "object_sizes", "hashes", "provider_ids", "vault_ids", "resource_ids", "resource_handles", "signed_urls"];
26
+ export type SessionRetentionExcludedValueClass = (typeof SESSION_RETENTION_EXCLUDED_VALUE_CLASSES)[number];
27
+ export interface SessionRetentionPolicyV1 {
28
+ readonly mode: "retain_indefinitely" | "delete_after_days";
29
+ readonly manualDelete: "enabled";
30
+ readonly automaticDeletion: "disabled" | "enabled";
31
+ readonly retentionDays?: number;
32
+ }
33
+ export interface SessionRetentionPolicyInput {
34
+ readonly automaticDeletion?: boolean;
35
+ readonly retentionDays?: number;
36
+ }
37
+ export interface SessionDeletionCandidateSessionV1 {
38
+ readonly sessionId: string;
39
+ readonly workspaceId: string;
40
+ readonly status: SessionControlStatus | string;
41
+ readonly createdAt?: string;
42
+ readonly terminalAt?: string;
43
+ readonly held?: boolean;
44
+ readonly retentionExempt?: boolean;
45
+ readonly unresolvedCleanup?: boolean;
46
+ readonly unresolvedCustody?: boolean;
47
+ }
48
+ export interface SessionDeletionBlockerV1 {
49
+ readonly code: SessionDeletionBlocker;
50
+ readonly observedAt: string;
51
+ }
52
+ export interface SessionDeletionCandidateV1 {
53
+ readonly status: SessionDeletionCandidateStatus;
54
+ readonly reason: SessionDeletionReason;
55
+ readonly evaluatedAt: string;
56
+ readonly eligibleAt?: string;
57
+ readonly blockers: readonly SessionDeletionBlockerV1[];
58
+ }
59
+ export interface SessionDeletionCandidateInput {
60
+ readonly session: SessionDeletionCandidateSessionV1;
61
+ readonly reason: SessionDeletionReason;
62
+ readonly policy?: SessionRetentionPolicyV1 | SessionRetentionPolicyInput;
63
+ readonly now: string;
64
+ }
65
+ export interface SessionDeletionCountV1 {
66
+ readonly class: SessionDeletionCountClass | string;
67
+ readonly count: number;
68
+ readonly status: SessionDeletionCountStatus;
69
+ readonly countedAt?: string;
70
+ readonly errorClass?: string;
71
+ }
72
+ export interface SessionDeletionManifestSessionV1 {
73
+ readonly sessionId: string;
74
+ readonly workspaceId: string;
75
+ readonly status: SessionControlStatus | string;
76
+ readonly createdAt?: string;
77
+ readonly terminalAt?: string;
78
+ readonly eligibleAt?: string;
79
+ }
80
+ export interface SessionDeletionManifestRequestV1 {
81
+ readonly reason: SessionDeletionReason;
82
+ readonly actorClass: "user" | "api_key" | "system" | "operator";
83
+ }
84
+ export interface SessionDeletionManifestSummaryV1 {
85
+ readonly totalCount: number;
86
+ readonly failedCountClasses: number;
87
+ readonly partialCountClasses: number;
88
+ readonly blockerCount: number;
89
+ readonly counts: readonly SessionDeletionCountV1[];
90
+ }
91
+ export interface SessionDeletionManifestRedactionV1 {
92
+ readonly policy: "counts_status_timestamps_only";
93
+ readonly scannerVersion: typeof SESSION_RETENTION_REDACTION_SCANNER_VERSION;
94
+ readonly excludes: readonly SessionRetentionExcludedValueClass[];
95
+ }
96
+ export interface SessionDeletionManifestV1 {
97
+ readonly schemaVersion: typeof SESSION_RETENTION_SCHEMA_VERSION;
98
+ readonly kind: typeof SESSION_DELETION_MANIFEST_KIND;
99
+ readonly generatedAt: string;
100
+ readonly mode: SessionDeletionManifestMode;
101
+ readonly session: SessionDeletionManifestSessionV1;
102
+ readonly request: SessionDeletionManifestRequestV1;
103
+ readonly candidate: SessionDeletionCandidateV1;
104
+ readonly summary: SessionDeletionManifestSummaryV1;
105
+ readonly redaction: SessionDeletionManifestRedactionV1;
106
+ }
107
+ export interface SessionDeletionManifestInput {
108
+ readonly generatedAt: string;
109
+ readonly mode: SessionDeletionManifestMode;
110
+ readonly session: SessionDeletionCandidateSessionV1;
111
+ readonly request: SessionDeletionManifestRequestV1;
112
+ readonly candidate?: SessionDeletionCandidateV1;
113
+ readonly policy?: SessionRetentionPolicyV1 | SessionRetentionPolicyInput;
114
+ readonly counts?: readonly SessionDeletionCountV1[];
115
+ }
116
+ export interface SessionDeletionManifestProofV1 {
117
+ readonly status: SessionDeletionWriteStatus;
118
+ readonly mode?: SessionDeletionManifestMode;
119
+ readonly writtenAt?: string;
120
+ }
121
+ export interface SessionDeletionPurgeProofV1 {
122
+ readonly status: SessionDeletionProofStatus;
123
+ readonly startedAt?: string;
124
+ readonly completedAt?: string;
125
+ readonly deletedObjectCount?: number;
126
+ }
127
+ export interface SessionDeletionOrderProofV1 {
128
+ readonly manifest: SessionDeletionManifestProofV1;
129
+ readonly purge: SessionDeletionPurgeProofV1;
130
+ }
131
+ export interface SessionDeletionJobV1 {
132
+ readonly schemaVersion: typeof SESSION_RETENTION_SCHEMA_VERSION;
133
+ readonly kind: typeof SESSION_DELETION_JOB_KIND;
134
+ readonly jobId: string;
135
+ readonly sessionId: string;
136
+ readonly workspaceId: string;
137
+ readonly reason: SessionDeletionReason;
138
+ readonly mode: SessionDeletionManifestMode;
139
+ readonly status: SessionDeletionJobStatus;
140
+ readonly createdAt: string;
141
+ readonly updatedAt?: string;
142
+ readonly order: SessionDeletionOrderProofV1;
143
+ readonly candidate?: SessionDeletionCandidateV1;
144
+ readonly summary?: SessionDeletionManifestSummaryV1;
145
+ }
146
+ export interface SessionDeletionJobInput {
147
+ readonly jobId: string;
148
+ readonly sessionId: string;
149
+ readonly workspaceId: string;
150
+ readonly reason: SessionDeletionReason;
151
+ readonly mode: SessionDeletionManifestMode;
152
+ readonly status: SessionDeletionJobStatus;
153
+ readonly createdAt: string;
154
+ readonly updatedAt?: string;
155
+ readonly order: SessionDeletionOrderProofV1;
156
+ readonly candidate?: SessionDeletionCandidateV1;
157
+ readonly summary?: SessionDeletionManifestSummaryV1;
158
+ }
159
+ export interface SessionDeletionManifestWriteObject {
160
+ readonly sessionId: string;
161
+ readonly workspaceId: string;
162
+ readonly contentType: typeof SESSION_DELETION_MANIFEST_CONTENT_TYPE;
163
+ readonly manifest: SessionDeletionManifestV1;
164
+ }
165
+ export interface SessionDeletionManifestObjectStore {
166
+ putSessionDeletionManifestObject(object: SessionDeletionManifestWriteObject): Promise<void>;
167
+ }
168
+ export interface SessionDeletionManifestWriteResult {
169
+ readonly status: "written";
170
+ readonly schemaVersion: typeof SESSION_RETENTION_SCHEMA_VERSION;
171
+ readonly sessionId: string;
172
+ readonly workspaceId: string;
173
+ readonly writtenAt: string;
174
+ readonly mode: SessionDeletionManifestMode;
175
+ }
176
+ export interface SessionDeletionManifestWriter {
177
+ writeSessionDeletionManifest(input: SessionDeletionManifestInput): Promise<SessionDeletionManifestWriteResult>;
178
+ }
179
+ export type SessionRetentionRedactionReason = "forbidden_field_name" | "signed_url" | "object_store_key" | "vault_id" | "private_resource_handle" | "hash_like_value";
180
+ export interface SessionRetentionRedactionFinding {
181
+ readonly path: string;
182
+ readonly reason: SessionRetentionRedactionReason;
183
+ readonly valueLength?: number;
184
+ }
185
+ export declare class SessionRetentionValidationError extends Error {
186
+ readonly code = "session_retention_contract_invalid";
187
+ constructor(message: string);
188
+ }
189
+ export declare class SessionRetentionRedactionError extends Error {
190
+ readonly code = "session_retention_payload_not_public_safe";
191
+ readonly findings: readonly SessionRetentionRedactionFinding[];
192
+ constructor(findings: readonly SessionRetentionRedactionFinding[]);
193
+ }
194
+ export declare class FakeSessionDeletionManifestObjectStore implements SessionDeletionManifestObjectStore {
195
+ #private;
196
+ putSessionDeletionManifestObject(object: SessionDeletionManifestWriteObject): Promise<void>;
197
+ getBySessionId(sessionId: string): SessionDeletionManifestV1 | undefined;
198
+ get(sessionId: string): SessionDeletionManifestV1 | undefined;
199
+ listSessionIds(): readonly string[];
200
+ }
201
+ export declare function createSessionDeletionManifestWriter(store: SessionDeletionManifestObjectStore): SessionDeletionManifestWriter;
202
+ export declare function writeSessionDeletionManifest(store: SessionDeletionManifestObjectStore, input: SessionDeletionManifestInput): Promise<SessionDeletionManifestWriteResult>;
203
+ export declare function buildSessionRetentionPolicy(input?: SessionRetentionPolicyInput): SessionRetentionPolicyV1;
204
+ export declare function evaluateSessionDeletionCandidate(input: SessionDeletionCandidateInput): SessionDeletionCandidateV1;
205
+ export declare function buildSessionDeletionManifest(input: SessionDeletionManifestInput): SessionDeletionManifestV1;
206
+ export declare function assertSessionDeletionOrder(proof: SessionDeletionOrderProofV1): void;
207
+ export declare function buildSessionDeletionJob(input: SessionDeletionJobInput): SessionDeletionJobV1;
208
+ export declare function scanSessionRetentionPayloadForSensitiveValues(input: unknown): readonly SessionRetentionRedactionFinding[];
209
+ export declare function assertPublicSafeSessionRetentionPayload(input: unknown): void;