engineering-behavior-observatory 0.2.1

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 (178) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +151 -0
  3. package/contracts/codex-app-server-0.150.1/manifest.json +25 -0
  4. package/contracts/codex-app-server-0.150.1/schema/InitializeParams.json +84 -0
  5. package/contracts/codex-app-server-0.150.1/schema/JSONRPCMessage.json +137 -0
  6. package/contracts/codex-app-server-0.150.1/schema/v2/ThreadReadParams.json +17 -0
  7. package/contracts/codex-app-server-0.150.1/schema/v2/ThreadTokenUsageUpdatedNotification.json +82 -0
  8. package/contracts/codex-app-server-0.150.1/schema/v2/TurnInterruptParams.json +17 -0
  9. package/contracts/codex-app-server-0.150.1/types/AskForApproval.ts +5 -0
  10. package/contracts/codex-app-server-0.150.1/types/ClientNotification.ts +5 -0
  11. package/contracts/codex-app-server-0.150.1/types/SandboxMode.ts +5 -0
  12. package/contracts/codex-app-server-0.150.1/types/ThreadReadParams.ts +9 -0
  13. package/contracts/codex-app-server-0.150.1/types/TokenUsageBreakdown.ts +5 -0
  14. package/contracts/codex-app-server-0.150.1/types/TurnInterruptParams.ts +5 -0
  15. package/contracts/codex-app-server-0.153.4/manifest.json +27 -0
  16. package/contracts/codex-app-server-0.153.4/schema/JSONRPCMessage.json +137 -0
  17. package/contracts/codex-app-server-0.153.4/schema/v1/InitializeParams.json +84 -0
  18. package/contracts/codex-app-server-0.153.4/schema/v2/ThreadReadParams.json +17 -0
  19. package/contracts/codex-app-server-0.153.4/schema/v2/ThreadStartParams.json +515 -0
  20. package/contracts/codex-app-server-0.153.4/schema/v2/ThreadTokenUsageUpdatedNotification.json +82 -0
  21. package/contracts/codex-app-server-0.153.4/schema/v2/TurnInterruptParams.json +17 -0
  22. package/contracts/codex-app-server-0.153.4/schema/v2/TurnStartParams.json +921 -0
  23. package/contracts/codex-app-server-0.153.4/types/AskForApproval.ts +5 -0
  24. package/contracts/codex-app-server-0.153.4/types/ClientNotification.ts +5 -0
  25. package/contracts/codex-app-server-0.153.4/types/SandboxMode.ts +5 -0
  26. package/contracts/codex-app-server-0.153.4/types/ThreadReadParams.ts +12 -0
  27. package/contracts/codex-app-server-0.153.4/types/TokenUsageBreakdown.ts +5 -0
  28. package/contracts/codex-app-server-0.153.4/types/TurnInterruptParams.ts +5 -0
  29. package/contracts/openhands-agent-server-v1.44.1.json +65 -0
  30. package/contracts/openhands-agent-server-v1.46.0.json +46 -0
  31. package/dist/contracts/codex-app-server-0.153.4/types/AskForApproval.d.ts +9 -0
  32. package/dist/contracts/codex-app-server-0.153.4/types/AskForApproval.js +2 -0
  33. package/dist/contracts/codex-app-server-0.153.4/types/ClientNotification.d.ts +3 -0
  34. package/dist/contracts/codex-app-server-0.153.4/types/ClientNotification.js +2 -0
  35. package/dist/contracts/codex-app-server-0.153.4/types/SandboxMode.d.ts +1 -0
  36. package/dist/contracts/codex-app-server-0.153.4/types/SandboxMode.js +2 -0
  37. package/dist/contracts/codex-app-server-0.153.4/types/ThreadReadParams.d.ts +10 -0
  38. package/dist/contracts/codex-app-server-0.153.4/types/ThreadReadParams.js +2 -0
  39. package/dist/contracts/codex-app-server-0.153.4/types/TokenUsageBreakdown.d.ts +8 -0
  40. package/dist/contracts/codex-app-server-0.153.4/types/TokenUsageBreakdown.js +2 -0
  41. package/dist/contracts/codex-app-server-0.153.4/types/TurnInterruptParams.d.ts +4 -0
  42. package/dist/contracts/codex-app-server-0.153.4/types/TurnInterruptParams.js +2 -0
  43. package/dist/src/agent-sdk-normalizer.d.ts +22 -0
  44. package/dist/src/agent-sdk-normalizer.js +995 -0
  45. package/dist/src/agent-sdk-run.d.ts +31 -0
  46. package/dist/src/agent-sdk-run.js +242 -0
  47. package/dist/src/agent-sdk-runner.d.ts +96 -0
  48. package/dist/src/agent-sdk-runner.js +407 -0
  49. package/dist/src/agent-sdk.d.ts +294 -0
  50. package/dist/src/agent-sdk.js +644 -0
  51. package/dist/src/aggregation.d.ts +183 -0
  52. package/dist/src/aggregation.js +513 -0
  53. package/dist/src/artifacts.d.ts +36 -0
  54. package/dist/src/artifacts.js +1372 -0
  55. package/dist/src/atlas-grafana.d.ts +377 -0
  56. package/dist/src/atlas-grafana.js +47 -0
  57. package/dist/src/atlas-html.d.ts +2 -0
  58. package/dist/src/atlas-html.js +34 -0
  59. package/dist/src/atlas.d.ts +130 -0
  60. package/dist/src/atlas.js +235 -0
  61. package/dist/src/behavior-assertions.d.ts +95 -0
  62. package/dist/src/behavior-assertions.js +154 -0
  63. package/dist/src/cli.d.ts +5 -0
  64. package/dist/src/cli.js +957 -0
  65. package/dist/src/codex-judge.d.ts +44 -0
  66. package/dist/src/codex-judge.js +214 -0
  67. package/dist/src/codex-run.d.ts +114 -0
  68. package/dist/src/codex-run.js +519 -0
  69. package/dist/src/codex.d.ts +187 -0
  70. package/dist/src/codex.js +1028 -0
  71. package/dist/src/contracts.d.ts +155 -0
  72. package/dist/src/contracts.js +866 -0
  73. package/dist/src/corpus.d.ts +67 -0
  74. package/dist/src/corpus.js +540 -0
  75. package/dist/src/cursor-sdk-runner.d.ts +81 -0
  76. package/dist/src/cursor-sdk-runner.js +362 -0
  77. package/dist/src/cursor-sdk.d.ts +81 -0
  78. package/dist/src/cursor-sdk.js +1078 -0
  79. package/dist/src/deepseek-adapter.d.ts +152 -0
  80. package/dist/src/deepseek-adapter.js +777 -0
  81. package/dist/src/exports.d.ts +69 -0
  82. package/dist/src/exports.js +966 -0
  83. package/dist/src/human-calibration.d.ts +167 -0
  84. package/dist/src/human-calibration.js +618 -0
  85. package/dist/src/index.d.ts +71 -0
  86. package/dist/src/index.js +38 -0
  87. package/dist/src/lifecycle.d.ts +196 -0
  88. package/dist/src/lifecycle.js +1889 -0
  89. package/dist/src/normalization-integrity.d.ts +128 -0
  90. package/dist/src/normalization-integrity.js +429 -0
  91. package/dist/src/openhands-run.d.ts +36 -0
  92. package/dist/src/openhands-run.js +415 -0
  93. package/dist/src/openhands.d.ts +130 -0
  94. package/dist/src/openhands.js +859 -0
  95. package/dist/src/pi.d.ts +203 -0
  96. package/dist/src/pi.js +1345 -0
  97. package/dist/src/process-protocol.d.ts +245 -0
  98. package/dist/src/process-protocol.js +1261 -0
  99. package/dist/src/retained-evidence.d.ts +12 -0
  100. package/dist/src/retained-evidence.js +201 -0
  101. package/dist/src/run-bundles.d.ts +193 -0
  102. package/dist/src/run-bundles.js +993 -0
  103. package/dist/src/scheduler.d.ts +109 -0
  104. package/dist/src/scheduler.js +1080 -0
  105. package/dist/src/semantic-judge.d.ts +194 -0
  106. package/dist/src/semantic-judge.js +875 -0
  107. package/dist/src/structural-observations.d.ts +124 -0
  108. package/dist/src/structural-observations.js +671 -0
  109. package/dist/src/task-packets.d.ts +115 -0
  110. package/dist/src/task-packets.js +683 -0
  111. package/dist/src/uniform-events.d.ts +120 -0
  112. package/dist/src/uniform-events.js +158 -0
  113. package/dist/src/verifiers.d.ts +116 -0
  114. package/dist/src/verifiers.js +819 -0
  115. package/dist/src/workspaces.d.ts +56 -0
  116. package/dist/src/workspaces.js +1314 -0
  117. package/docs/README.md +60 -0
  118. package/docs/development/README.md +71 -0
  119. package/docs/development/documentation-sync.md +58 -0
  120. package/docs/development/extension-contracts.md +307 -0
  121. package/docs/evaluation/README.md +48 -0
  122. package/docs/evaluation/aggregation.md +112 -0
  123. package/docs/evaluation/behavior-assertions.md +45 -0
  124. package/docs/evaluation/human-calibration.md +170 -0
  125. package/docs/evaluation/normalization-integrity.md +80 -0
  126. package/docs/evaluation/semantic-judge.md +188 -0
  127. package/docs/evaluation/structural-observations.md +84 -0
  128. package/docs/evaluation/uniform-events.md +131 -0
  129. package/docs/guides/atlas.md +144 -0
  130. package/docs/guides/evidence-and-sharing.md +100 -0
  131. package/docs/guides/operator-guide.md +424 -0
  132. package/docs/guides/quickstart.md +152 -0
  133. package/docs/guides/telemetry.md +66 -0
  134. package/docs/harnesses/README.md +31 -0
  135. package/docs/harnesses/claude-agent-sdk.md +61 -0
  136. package/docs/harnesses/codex-harness.md +174 -0
  137. package/docs/harnesses/cursor-sdk.md +149 -0
  138. package/docs/harnesses/deepseek-harness.md +134 -0
  139. package/docs/harnesses/openhands-agent-server.md +153 -0
  140. package/docs/harnesses/pi-sdk.md +66 -0
  141. package/docs/reference/README.md +19 -0
  142. package/docs/reference/agent-sdk-operational-runner.md +118 -0
  143. package/docs/reference/cli.md +114 -0
  144. package/docs/reference/contracts.md +222 -0
  145. package/docs/reference/run-bundle-contract.md +354 -0
  146. package/docs/reference/run-lifecycle.md +54 -0
  147. package/examples/cursor-sdk/README.md +11 -0
  148. package/examples/cursor-sdk/capture-profile.json +1 -0
  149. package/examples/cursor-sdk/harness.json +1 -0
  150. package/examples/cursor-sdk/model.json +1 -0
  151. package/examples/cursor-sdk/native-limits.json +1 -0
  152. package/examples/cursor-sdk/native-tool-policy.json +1 -0
  153. package/ontology/behavior-categories.v1.json +46 -0
  154. package/package.json +66 -0
  155. package/release/0.1.0/KNOWN_LIMITATIONS.md +35 -0
  156. package/release/0.1.0/README.md +46 -0
  157. package/release/0.1.0/reproducibility.json +61 -0
  158. package/release/0.2.0/KNOWN_LIMITATIONS.md +40 -0
  159. package/release/0.2.0/README.md +42 -0
  160. package/release/0.2.0/reproducibility.json +73 -0
  161. package/release/0.2.1/KNOWN_LIMITATIONS.md +18 -0
  162. package/release/0.2.1/README.md +63 -0
  163. package/release/0.2.1/reproducibility.json +73 -0
  164. package/release/README.md +13 -0
  165. package/schemas/aggregation.v1.json +293 -0
  166. package/schemas/behavior-assertions.v1.json +220 -0
  167. package/schemas/deepseek-runtime-composition.v1.schema.json +122 -0
  168. package/schemas/experiment.v1.schema.json +188 -0
  169. package/schemas/human-calibration.v1.json +336 -0
  170. package/schemas/normalization-integrity.v1.json +302 -0
  171. package/schemas/run-bundles/v1.json +1040 -0
  172. package/schemas/run-queue.v1.schema.json +206 -0
  173. package/schemas/semantic-judge.v1.json +380 -0
  174. package/schemas/structural-observations.v1.json +131 -0
  175. package/schemas/task-packet-freeze.v1.schema.json +106 -0
  176. package/schemas/task-packet.v1.schema.json +234 -0
  177. package/schemas/uniform-events/v1.json +289 -0
  178. package/scripts/atlas-grafana.sh +18 -0
@@ -0,0 +1,222 @@
1
+ # Task-packet and experiment contracts
2
+
3
+ The post-capture uniform event and adapter boundary is documented separately in
4
+ [uniform-events.md](../evaluation/uniform-events.md). Its schemas consume capture-qualified
5
+ native evidence; they are not task-authorship or experiment inputs.
6
+
7
+ EBO accepts externally authored task packets and experiment configurations as
8
+ versioned JSON documents. The schemas are the contract; this repository does
9
+ not contain an evaluation corpus or a fixed operating matrix.
10
+
11
+ ## Task packets
12
+
13
+ `schemas/task-packet.v1.schema.json` divides a packet into two surfaces:
14
+
15
+ - `agentInput` is the only surface a workspace materializer may use. It holds
16
+ the public prompt, a digest-verified sanitized TAR+gzip v1 archive with
17
+ compressed-byte, expanded-byte, and member-count limits, and an explicit
18
+ workspace-relative allowlist. A materializer verifies the archive digest and
19
+ copies only entries selected by `includePaths`; it must not materialize a raw
20
+ repository checkout or an entry outside that allowlist.
21
+ - Its archive locator is a secret-free, bundle-relative logical path. URLs,
22
+ absolute local paths, credentials, and path traversal are invalid there. Its
23
+ resolver rejects links and paths that leave the real task-bundle root.
24
+ Include paths are canonical POSIX logical paths only; leading slashes, trailing
25
+ slashes, backslashes,
26
+ drive letters, UNC paths, and traversal forms are invalid.
27
+ Common framework filenames may use brackets, parentheses, `+`, and `@`;
28
+ spaces, colons, wildcard characters, and shell metacharacters remain invalid.
29
+ - `verified-archive-literal-paths-v1` resolves each literal from the sanitized
30
+ archive root. A file includes that file; a directory includes its complete
31
+ descendant tree. Wildcards are intentionally unsupported.
32
+ - `verified-archive-literal-paths-no-links-v1` adds the required v1 link rule:
33
+ enumerate every selected entry and selected directory descendant before copy,
34
+ then reject every non-file/non-directory entry. Links are never copied or dereferenced. Every
35
+ selected member name must be a canonical root-relative logical path before
36
+ joining either archive or workspace roots.
37
+ - Archive membership and allowlist selection use exact canonical POSIX names.
38
+ Case folding is used only to reject destination collisions across filesystems.
39
+ - `assessmentMode` is explicit. `observational` packets are the primary
40
+ open-ended task form and omit `restricted` entirely. `verified` packets use
41
+ `restricted` only for digest-addressed reference-solution and verifier
42
+ references; the packet cannot embed their contents.
43
+
44
+ The packet records repository provenance, a controlled perturbation, admission
45
+ review status, sharing classification, and SHA-256 digests for every frozen
46
+ component. Every digest has one authority: the safe fixture source, controlled
47
+ perturbation artifact, and restricted component references carry their own. The schema
48
+ does not claim a separate agent-input digest without defining its canonical
49
+ bytes; admission-freeze tooling owns the whole-packet identity.
50
+
51
+ `proposed` packets explicitly set `admission.review` to `null`. `admitted` and
52
+ `rejected` packets require a reviewer, RFC 3339 `date-time` evidence, and the
53
+ restricted review-record reference. Repository provenance is a credential-free
54
+ HTTPS repository URI, optionally on an explicit port, plus a full immutable Git
55
+ object ID. Branches and tags are not accepted. A verifier is required only for `verified`
56
+ packets; `referenceSolution.status` may be `not-provided` or `unsupported` for
57
+ verifier-only work. Controlled perturbation
58
+ content is either an external, digest-addressed artifact or an explicit
59
+ `not-applied`/`unsupported` state; EBO does not prescribe a task-authoring
60
+ taxonomy.
61
+
62
+ Before scheduling, EBO requires an admitted packet's review time to be a valid
63
+ RFC 3339 calendar timestamp and its review record. Verified packets additionally
64
+ require provided reference-solution and verifier bytes to match their pinned digests. The review record binds the
65
+ canonical pre-admission packet digest; the admitted packet can then hash its
66
+ review-record reference without requiring a circular digest. Each declared
67
+ materialization literal must select at least one verified archive file or
68
+ directory tree. A referenced controlled perturbation also hashes to its pinned
69
+ digest before scheduling; explicit unavailable states remain distinct from a
70
+ referenced artifact that fails to resolve.
71
+
72
+ ### Admission and freeze
73
+
74
+ Task-packet tooling consumes an externally authored packet; it does not create
75
+ tasks or make a human review decision. `validate` checks the packet schema,
76
+ parses each declared TAR+gzip fixture, verifies its declared size/member/link
77
+ limits and literal allowlist, and resolves every declared perturbation,
78
+ mode-appropriate reference/verifier, and review-record digest. `admit` additionally
79
+ requires the recorded admission status to be `admitted` and a complete human
80
+ review.
81
+
82
+ `freeze` writes a sibling
83
+ [`ebo.task-packet-freeze/v1`](../../schemas/task-packet-freeze.v1.schema.json)
84
+ record. It records the assessment mode and stable SHA-256 digests for the
85
+ prompt, fixture, optional reference solution/verifier, review record,
86
+ controlled perturbation, and canonical packet. The review record binds the canonical packet content with its
87
+ `admission` field omitted, using its `preAdmissionDigest` field and avoiding a
88
+ circular reference. The aggregate digest is derived from those identities, the
89
+ packet locator, and the recorded `frozenAt` timestamp. Repeating a freeze for
90
+ unchanged content retains the first published record and its timestamp.
91
+ An existing freeze is never silently replaced after a component changes.
92
+
93
+ `status` compares the current packet and resolved bytes with the freeze record
94
+ and reports the named mismatching component before a later materializer or
95
+ scheduler can consume it. The model-visible projection is only `agentInput`;
96
+ verified-task reference solutions/verifier bytes and all review records remain restricted.
97
+
98
+ ## Workspace materialization
99
+
100
+ `materializeWorkspace` accepts an admitted packet with a `frozen` status and
101
+ creates an attempt-identified directory outside the task bundle. It verifies
102
+ the digest-pinned TAR+gzip source, copies only the declared literal allowlist,
103
+ rejects links, special entries, traversal, and a selected `restricted/`
104
+ subtree, then normalizes private modes and timestamps before calculating the
105
+ `workspaceFingerprint` used for outcome binding and, when present, verification. The result's `startingDigest` is
106
+ the declared fixture digest; `workspaceDigest` is the normalized tree
107
+ fingerprint. Attempt roots and non-executable files use `0700` and `0600`;
108
+ executable archive or setup files retain the owner execute bit.
109
+
110
+ Setup callbacks receive the disposable workspace path and an invocation-owned
111
+ `{ spawn }` context. Child processes that setup needs to create must use that
112
+ context: each child is placed in a private process group and its group is
113
+ terminated before the fingerprint is calculated. This prevents cleanup from
114
+ mistaking unrelated coordinator processes for setup descendants. A setup step
115
+ must settle all in-process writes (including timers and promises) and must not
116
+ leave ambient child processes behind before returning; arbitrary filesystem
117
+ closures cannot be revoked without a sandbox. Stronger process isolation can
118
+ still be supplied by the evaluation environment. Call
119
+ `cleanupWorkspace(result, "success")` (or `result.cleanup("success")`) after a
120
+ successful attempt. A failed setup returns a failed lifecycle result;
121
+ `retainOnFailure: true` keeps its attempt path for inspection after normalizing
122
+ an owned tree to private modes, while the default removes it. Identity changes,
123
+ links, special entries, and paths that cannot be safely normalized are never
124
+ retained. Failure retention never changes the model-visible input surface or
125
+ the frozen packet.
126
+
127
+ ## Experiments
128
+
129
+ `schemas/experiment.v1.schema.json` treats task, model, and harness sets;
130
+ trial count; ordering seed; coordinator wall-clock budget; and capture profile
131
+ as data. Each condition set is an ID-keyed map, so one identity can expand to
132
+ only one matrix condition. Every referenced configuration has a SHA-256 digest.
133
+ Each harness condition separately names source-specific native-limits and
134
+ native-tool-policy configurations; EBO does not define a shared turn count or
135
+ tool namespace.
136
+
137
+ Every experiment configuration reference is a portable bundle-relative logical
138
+ path, resolved from the experiment bundle root rather than the current working
139
+ directory. The resolver checks each component without following symbolic links
140
+ and rejects a path that leaves the real bundle root. URLs, absolute paths,
141
+ traversal, aliases such as `./`, and backslashes are invalid. A
142
+ `permuted` order also names a digest-pinned permutation-algorithm reference;
143
+ that versioned artifact defines how the supplied seed orders matrix cells. Each
144
+ resolved model, harness, native-limit, native-tool-policy, capture-profile, and
145
+ permutation artifact must hash to its pinned digest before scheduling.
146
+
147
+ `declared` ordering carries explicit task, model, and harness ID lists. Matrix
148
+ compilers use those lists, never object-property enumeration, and reject a list
149
+ unless it is an exact permutation of its condition-set IDs. Before expansion, a
150
+ compiler resolves every task packet, checks the reference digest, and requires
151
+ `admission.status` to be `admitted`. Capture profiles use the same digest-pinned
152
+ configuration-reference shape as other immutable experiment inputs.
153
+
154
+ For declared matrices, traversal is task outermost, then model, then harness,
155
+ with one-based trial replicas innermost. The compiler rejects duplicate task
156
+ packet digests across task IDs before expansion. The declared cell iterator is
157
+ lazy, so externally supplied trial counts do not allocate a full matrix.
158
+
159
+ The fixtures include a generic 18-cell matrix and a differently shaped matrix
160
+ to show that no study dimensions are built into the contract. Parsed numeric
161
+ controls are limited to JavaScript safe integers.
162
+
163
+ ## Run queues
164
+
165
+ `compileRunQueue` expands an experiment into a persisted
166
+ `ebo.run-queue/v1` document. Every entry contains the task-packet freeze
167
+ identity, digest-pinned model and harness configuration references, and a
168
+ one-based trial identity; the queue also retains the selected capture-profile
169
+ reference and coordinator budget. A scheduling digest covers those controls,
170
+ the matrix, seed, and ordering policy; run IDs include that digest so
171
+ standalone consumers reject mutations to any persisted scheduling input. When
172
+ the API is used without a bundle root, each admitted task resolution must carry
173
+ the complete schema-valid freeze record that supplied task identities are
174
+ checked against. Freeze locators are distinct from every packet/configuration
175
+ artifact path and from each other; persisted custom locators are reused when
176
+ queues are revalidated without a bundle root.
177
+
178
+ The compiler supports sequential (`declared` is retained as its legacy name),
179
+ seeded-shuffle (`permuted` is retained as its legacy name), and balanced
180
+ interleaving. Interleaving round-robins the selected dimension (model by
181
+ default) and preserves every cell exactly once, including matrices whose
182
+ groups have different sizes. Configuration references are resolved before
183
+ compilation, and every task packet must have a matching, admitted freeze
184
+ record. A seeded-shuffle with a permutation reference reads that verified
185
+ artifact and currently accepts the declared `fisher-yates-v1` algorithm;
186
+ unknown algorithm definitions fail closed. The normalized queue records the
187
+ resolved algorithm name, so experiment-only validation remains reproducible;
188
+ passing a bundle root additionally rechecks the pinned artifact. Queue writes
189
+ use the existing atomic artifact writer and do not execute work or coordinate
190
+ across machines.
191
+
192
+ The CLI exposes `ebo matrix compile <experiment.json> <bundle-root>
193
+ <queue.json> [--freeze-locator <task-id>=<path>]`, `ebo queue inspect
194
+ <queue.json>`, and `ebo queue validate
195
+ <queue.json> [experiment.json] [--bundle-root <bundle-root>]`. Supplying the
196
+ bundle root lets queue validation recheck each freeze and pinned algorithm
197
+ artifact. The 18-cell fixture is only a generality test;
198
+ the compiler has no fixed task, model, harness, or trial count, subject to the
199
+ bounded 100,000-entry local queue limit; larger matrices require a future
200
+ streaming queue implementation.
201
+
202
+ ## Agent SDK run configuration
203
+
204
+ `ebo.agent-sdk-config/v1` is the single discriminated contract behind the five
205
+ digest-pinned configuration artifacts a queue entry already references. The
206
+ `kind` values are `model`, `harness`, `native-limits`, `native-tool-policy`,
207
+ and `capture-profile`; `ebo agent-sdk run` resolves each reference through the
208
+ bundle resolver and validates the record before launching the Agent SDK. The
209
+ model record's `model` must equal the queue entry's model ID, the harness
210
+ adapter must be `claude-agent-sdk`, tool lists are arrays of unique nonempty
211
+ Agent SDK tool names, and `bypassPermissions` is accepted only with an explicit
212
+ `allowDangerouslySkipPermissions: true`. Duplicate JSON keys, unknown fields,
213
+ unsafe numbers, wrong kinds, digest mismatches, and malformed UTF-8 or JSON
214
+ fail before an attempt starts. Credentials and environment overrides are never
215
+ read from these files; authentication stays in the process environment, and
216
+ telemetry content flags default to false. A configured telemetry endpoint
217
+ without a receipt checker remains explicit `not-checked` receipt evidence. The
218
+ full runner specification is
219
+ [agent-sdk-operational-runner.md](agent-sdk-operational-runner.md).
220
+
221
+ Unknown schema versions and sharing classifications are invalid. Consumers must
222
+ validate a document before materializing a workspace or scheduling a run.
@@ -0,0 +1,354 @@
1
+ # Run-bundle contract
2
+
3
+ Run bundles retain the evidence needed to inspect one attempt without copying
4
+ native harness payloads into a common event model. This contract is versioned
5
+ as [`schemas/run-bundles/v1.json`](../../schemas/run-bundles/v1.json).
6
+
7
+ ## Bundle layout
8
+
9
+ ```text
10
+ run-bundle/
11
+ manifest.json
12
+ session.jsonl
13
+ hooks.jsonl
14
+ telemetry/
15
+ workspace.patch
16
+ verifier.json # verified tasks only
17
+ capture-report.json
18
+ export/manifest.json
19
+ ```
20
+
21
+ `manifest.json` is the run-manifest schema root. Its evidence descriptors are
22
+ the portable index: each gives an artifact ID, source, authority, media type,
23
+ SHA-256 digest, byte size, sharing class, bundle-relative path, and native type
24
+ and identity when the source provides them. Native content stays in the
25
+ referenced file. Artifact IDs are unique within a bundle, and every bundle
26
+ retains exactly one capture-report descriptor.
27
+
28
+ For TypeScript Agent SDK runs, `openClaudeAgentSdkHookCapture` creates the
29
+ no-clobber `hooks.jsonl` sink. Each source-specific record retains the complete
30
+ typed callback input, callback time, empty neutral callback output, abort-signal
31
+ state, and only the session, prompt, tool-use, agent, transcript, and working
32
+ directory identities the callback exposed. Because the native payload can
33
+ contain prompts, tool inputs, and local paths, the resulting artifact is
34
+ restricted evidence; later export policy must not treat the source file as a
35
+ sanitized derivative.
36
+
37
+ `hooks.jsonl` is authoritative for callback occurrence. Optional detailed-beta
38
+ hook spans are a separate timing capability and are not required to infer or
39
+ confirm an occurrence. If a hook append fails, the executor returns the neutral
40
+ empty hook output, keeps the agent operation running, and retains a bounded
41
+ capture warning in the attempt evidence.
42
+
43
+ All paths are bundle-relative. The schema rejects absolute and parent-traversal
44
+ paths; the shared artifact utilities will also resolve symlinks and verify
45
+ digests before use. Each retained path appears exactly once under a
46
+ case-folded portable identity. A sanitized
47
+ partner or public artifact therefore has its own retained path, and source bytes
48
+ cannot masquerade as another evidence class.
49
+
50
+ ## Evidence authority
51
+
52
+ | Authority | Source of record | It can answer |
53
+ | --- | --- | --- |
54
+ | `semantic` | Native session and hook artifacts | What the agent and harness exchanged or observed |
55
+ | `timing-resource` | Native telemetry | Timing, tokens, cost, and resource observations |
56
+ | `outcome` | Workspace and optional verified-task artifacts | What changed and, only for verified tasks, whether executable assertions passed |
57
+ | `capture` | Capture report | Which evidence is available, missing, or unsupported |
58
+ | `export` | Export manifest | Which approved artifacts were prepared for sharing |
59
+
60
+ The contract does not describe a uniform event ontology or attach semantic
61
+ quality labels. Source-specific records remain authoritative until a later,
62
+ capture-qualified normalization step.
63
+
64
+ Evidence kind and authority are fixed pairs: sessions and hooks are semantic;
65
+ telemetry is timing-resource; workspace and verifier records are outcome; the
66
+ capture report is capture; and the export manifest is export.
67
+
68
+ ## Attempt and terminal semantics
69
+
70
+ A run identifies the declared task/model/harness condition. An attempt is one
71
+ execution of that run; retries get a new attempt ID and must point at `retryOf`.
72
+ `retryOf` cannot name the attempt itself. No attempt replaces prior evidence.
73
+ When a run declares a native session ID, it retains at least one session
74
+ reference naming that same native session, with at least one parsed native
75
+ record.
76
+ The same rule applies to a declared native trace ID and retained telemetry
77
+ evidence. Runtime components are unique by source, name, and version.
78
+
79
+ `runtime` is a non-empty list of source-specific components, each with source,
80
+ name, and version. One component's source or name and version represents the
81
+ declared harness. An Agent SDK run can record SDK and CLI components; an Agent
82
+ Server run can record only its server component. No integration invents an
83
+ absent SDK or CLI identity.
84
+
85
+ `terminal` separates these conditions:
86
+
87
+ | Terminal state | Failure class | Stop reason |
88
+ | --- | --- | --- |
89
+ | `completed` | `none` | `none` |
90
+ | `failed` | `infrastructure` or `task` | `none` |
91
+ | `stopped` | `none` | `budget` or `policy` |
92
+ | `interrupted` | `infrastructure` | `none` |
93
+
94
+ Every run declares `assessmentMode`. `observational` is the primary mode for
95
+ open-ended engineering work: a `completed` terminal means execution ended
96
+ normally with retained workspace evidence, not that the task was correct or
97
+ stakeholder-approved. It has no verifier artifact. `verified` preserves the
98
+ existing verifier-backed completion and task-failure semantics.
99
+
100
+ Capture incompleteness is not a task or infrastructure failure class. It is a
101
+ capture-report qualification with an explicit missing-evidence reason.
102
+
103
+ ## Qualification
104
+
105
+ `capture-report/v1` records `semantic`, `timingResource`, and `outcome`
106
+ capabilities separately. A `qualified` report requires available semantic and
107
+ outcome evidence and checked timing-resource evidence. For observational runs,
108
+ workspace evidence satisfies the outcome capability; verified runs also require
109
+ their verifier evidence. Missing optional beta spans are recorded as
110
+ `optional-beta-unavailable` affecting `timing-resource`; they never assert that
111
+ semantic evidence is missing. Every unavailable capability has an explicit
112
+ missing-evidence entry; optional-beta-unavailable affects timing-resource only.
113
+ An available capability requires an indexed artifact with that authority. The
114
+ embedded capture report must also name the containing bundle. An `incomplete`
115
+ report remains a valid retained partial bundle but is not capture-qualified.
116
+ Missing-evidence effects cannot contradict a capability reported as available.
117
+ `unsupported` and `not-checked` reasons each match their corresponding
118
+ capability status.
119
+
120
+ An artifact may retain `sharingClass: unknown` when capture cannot classify it.
121
+ Exports fail closed: unknown artifacts and unknown export classes are never
122
+ ready or exported.
123
+
124
+ The final capture report for a direct Agent SDK attempt also retains the exact
125
+ SDK/CLI capability profile, effective model/tool/permission/budget
126
+ configuration, and expected hook set used for qualification. Its
127
+ `structuralQualification` field preserves the resulting dimension statuses and
128
+ reason codes. These are capture facts, not behavioral judgments, and remain
129
+ internal until the export policy produces an approved derivative.
130
+
131
+ Real package-manager workspaces may declare a bounded outcome projection:
132
+ directory names such as `node_modules` and `coverage`, source `.gitignore`
133
+ rules, and empty-directory omission. EBO copies the final workspace, applies
134
+ that policy without mutating the live attempt, records the policy in the
135
+ capture report, and then verifies the resulting patch or snapshot. Link and
136
+ hard-link rejection remains unchanged. Hook serialization warnings are retained
137
+ in the Agent SDK capture report and qualify the hook dimension as a gap rather
138
+ than erasing an otherwise complete native session and hook stream.
139
+
140
+ `captureClaudeAgentSdkRun` is the single-run production composition boundary.
141
+ It reuses the existing lifecycle, caller-supplied workspace coordinator,
142
+ passive Agent SDK sinks, optional verified-task result, assembler, and qualifier. It neither
143
+ reads a run queue nor retries an attempt; an operational runner may call it once
144
+ for each already-resolved queue entry.
145
+
146
+ `qualifyRunBundle` performs the post-capture structural check without adding a
147
+ new artifact dialect. Its report evaluates attempt identity, session evidence,
148
+ pinned hook capability versus observed callbacks, telemetry receipt and
149
+ optional timing, workspace outcome, assessment mode, any required verified-task result, terminal classification,
150
+ and sharing classification independently. The overall result is `qualified`,
151
+ `qualified-with-gaps`, or `unqualified`, with stable reason codes and the named
152
+ evidence ID. Optional detailed-beta timing and a missing collector receipt are
153
+ timing gaps; missing or malformed semantic/outcome evidence, an unusable patch,
154
+ or contradictory capture-report facts are unqualified. The report contains no
155
+ behavioral or semantic-quality judgment.
156
+
157
+ An explicit `unsupported` capture-report capability remains qualified and is
158
+ reported as `unsupported`, not rewritten as missing evidence. Qualification
159
+ caps every retained artifact read at 64 MiB; larger evidence is rejected with
160
+ `ARTIFACT_TOO_LARGE` before whole-file parsing. Parsed session records and raw
161
+ telemetry payloads are not retained in the qualification report.
162
+
163
+ Session qualification requires the descriptor, manifest, and every observed
164
+ native session identity to agree. Hook JSONL must contain at least one pinned
165
+ callback in `hook`, `hook_event_name`, or a source-specific `type`; unrelated
166
+ nonempty JSON does not count as hook evidence. A telemetry artifact without a
167
+ collector receipt is a `TELEMETRY_RECEIPT_MISSING` gap, including the supported
168
+ usage-only path.
169
+
170
+ Qualification reuses manifest schema checks, descriptor digest/path readback,
171
+ mode-appropriate outcome binding, and export-manifest validation. When a
172
+ workspace patch is present, callers supply the admitted starting fixture so the
173
+ patch can be checked with `git apply --check`; omission leaves an explicit
174
+ `WORKSPACE_PATCH_NOT_CHECKED` gap.
175
+
176
+ ## Portable export
177
+
178
+ `createPortableRunBundleExport` reads a qualified run bundle without changing
179
+ it and creates a separate partner or public derivative tree. Its policy fixes
180
+ the artifact and string byte limits plus caller-supplied sensitive values. The
181
+ exporter also removes credential-bearing environment values, local paths and
182
+ usernames, hidden-reasoning fields, and disallowed raw API bodies. Run,
183
+ attempt, bundle, session, and trace identities are replaced consistently so
184
+ cross-artifact correlation survives without exposing native identifiers.
185
+
186
+ The export allowlist covers JSONL session/hooks, JSON telemetry,
187
+ text workspace patches, JSON verifier/capture reports, and text verifier
188
+ diagnostics. Unknown classifications and unrecognized kind/media pairs stop
189
+ the export. Restricted workspace snapshots may be retained up to 128 MiB for
190
+ qualification, but portable exports explicitly exclude them as
191
+ `unsupported-workspace-snapshot`; opaque archive bytes never pass through the
192
+ text sanitizer. Existing source export manifests are likewise excluded and
193
+ recorded rather than recursively exported.
194
+
195
+ The derivative `export-manifest/v1` records each portable artifact's source
196
+ digest, every applied transformation, each exclusion, the effective policy
197
+ digest, and rewritten correlations. Creation reports success only after
198
+ `readPortableRunBundleExport` rechecks schema, paths, digests, sizes,
199
+ references, policy, JSON/JSONL structure, and a final secret scan. A failed
200
+ creation removes its newly-created destination tree; an existing destination
201
+ is never replaced.
202
+
203
+ The remainder of this verifier section applies only to `verified` tasks.
204
+ Verifier results cannot contradict their assertions: passed results have no
205
+ failed assertion, while failed results retain at least one failed assertion.
206
+ Assertion IDs are unique, and a retained verifier result names the containing
207
+ bundle. Completed runs retain passed verifier results; task-failed runs retain
208
+ at least one failed verifier result and may retain independent passed results.
209
+ Both verified outcomes require retained verifier and workspace evidence; workspace
210
+ evidence alone cannot establish task pass or task failure. A passed verifier
211
+ result contains only passed assertions and, when retained, an exit code of zero.
212
+ Every passed or failed verifier also names the retained workspace artifact and
213
+ digest it evaluated.
214
+
215
+ The executor receives both the retained workspace artifact reference and a
216
+ separate live-workspace fingerprint; the executor options require the retained
217
+ workspace reference to carry that same fingerprint. The v1 live-workspace fingerprint hashes
218
+ the root and sorted descendant relative paths, entry kinds, permission mode
219
+ bits, reproducible modification times, and file bytes; hard-linked files,
220
+ symbolic links, and unsupported entry kinds are rejected. POSIX snapshots use
221
+ the metadata-preserving system copy path with nanosecond modification times;
222
+ the Windows fallback uses Node's reproducible millisecond precision. The
223
+ fingerprint must
224
+ match the live workspace before and after its private snapshot is created. The
225
+ executor then evaluates that detached snapshot, while the artifact digest
226
+ remains the digest of the retained workspace evidence. The complete executor
227
+ result records the snapshot fingerprint alongside the workspace reference, and
228
+ manifest workspace descriptors may carry it for later terminal binding checks.
229
+
230
+ Verifier execution uses a small subprocess boundary. The executor resolves the
231
+ digest-pinned restricted verifier from its task-bundle root, stages it in a
232
+ private trusted subdirectory separate from the snapshot, and invokes the pinned
233
+ Node runtime with the staged verifier path followed by the snapshot workspace
234
+ path. Launcher options cannot replace the staged entry point, and the child
235
+ environment contains only fixed coordinator variables; `PATH` points to a
236
+ dedicated empty trusted-stage directory, while Node preload, POSIX dynamic-loader,
237
+ shell-startup, and interpreter module-path injection are unavailable. Verifier
238
+ tools must be invoked by absolute pinned paths. Normal completion is reported
239
+ over a parent-owned extra stdio channel rather than a marker file or inherited
240
+ environment variable, so ordinary workspace descendants cannot recreate it. The
241
+ restricted implementation and any
242
+ reference solution remain outside that workspace. `.mjs`/`.cjs` locators retain
243
+ their module semantics; ambiguous `.js` or extensionless artifacts default to
244
+ CommonJS unless the caller supplies `moduleFormat: "module"`, and explicit
245
+ formats cannot contradict an unambiguous suffix. The verifier writes one JSON
246
+ object to stdout:
247
+
248
+ ```json
249
+ {
250
+ "assertions": [
251
+ { "id": "unit-tests", "status": "passed" },
252
+ { "id": "lint", "status": "failed" }
253
+ ]
254
+ }
255
+ ```
256
+
257
+ Each assertion object contains exactly `id` and `status`; undeclared fields,
258
+ non-string statuses, duplicate IDs, and IDs longer than 256 characters are
259
+ verifier errors rather than silently normalized away.
260
+
261
+ The executor records the selected verifier's locator, digest, and module format, the assertion
262
+ list, `durationMs`, observed `exitCode` when the process exits normally, and a
263
+ `status` of `passed`, `failed`, or `error`. A run manifest may declare the
264
+ task-bound verifier reference under `run.verifier`; manifest validation then
265
+ requires each retained unsanitized verifier result to identify that same
266
+ reference. A valid assertion failure is a task failure; timeout, crash, invalid
267
+ UTF-8/JSON, duplicate or invalid assertion, and an exit/assertion contradiction
268
+ are verifier errors. A failed assertion therefore requires a nonzero verifier
269
+ exit; a zero exit paired with a failure is not a task result. `not-run` remains
270
+ available for a caller that records a verifier which was never started, and its
271
+ assertions must all be `not-run`. Stdout
272
+ and stderr are drained without an unbounded buffer and persisted to private
273
+ files while the process runs, so a partial attempt retains output even when
274
+ execution ends abnormally. A timeout terminates the verifier process group (or
275
+ process tree on Windows). Each retained stream is represented by an
276
+ execution-specific diagnostic reference with a `stream` (`stdout` or `stderr`),
277
+ bundle-relative `locator`, SHA-256 `digest`, retained `sizeBytes`, and a
278
+ `truncated` flag. Sanitized verifier results may retain diagnostics only when
279
+ each one carries a source diagnostic origin and points to a separately
280
+ classified `diagnostic` evidence sidecar. The sidecar's path, digest, and size
281
+ must match exactly, and it must be included in the export. The result remains
282
+ valid even when diagnostics are truncated.
283
+ The `durationMs` and `diagnostics` fields are optional for older v1 records;
284
+ new executor results include both. An `error` result requires a nonempty
285
+ explanation and may omit `workspace` when the verifier failed before a
286
+ workspace was available; it must not invent a workspace binding. Coordinator
287
+ failures such as timeout, launch, parse, or
288
+ cleanup errors are recorded in the result's `error` field; the native stderr
289
+ diagnostic remains byte-for-byte separate. `error` is not valid on passed or
290
+ failed results. Sanitized verifier derivatives preserve `durationMs` and
291
+ `error`; sensitive error text may use `errorRedacted: true` with the literal
292
+ `[redacted]`, but cannot be replaced by an unmarked claim. The process-group boundary cannot
293
+ contain a verifier that deliberately creates a new POSIX session; callers that
294
+ run untrusted verifiers need an OS sandbox or equivalent isolation boundary.
295
+
296
+ The result serializer validates `verifier-result/v1` before writing it. The
297
+ diagnostic references are read back and digest-checked before the result is
298
+ saved, so a result cannot point at missing or changed diagnostic bytes. Result
299
+ paths use no-clobber persistence: an existing result, manifest, or other
300
+ retained evidence file is never replaced by a later verifier write, and a
301
+ crash between the no-clobber link and temporary-name cleanup is recovered on
302
+ the next verified read. Manifest
303
+ validation also cross-checks each retained verifier's `bundleId` and workspace
304
+ artifact ID/digest against the containing bundle's retained evidence. The
305
+ `manifest.json` path and its descendants are reserved for the containing
306
+ manifest and cannot be used for verifier results or diagnostic directories.
307
+ The CLI applies duplicate-key detection to standalone verifier JSON before
308
+ parsing, just as manifest-nested verifier artifacts and subprocess output are
309
+ checked before interpretation. Manifest validation requires a retained passed
310
+ verifier for a completed verified run and a retained failed verifier for a
311
+ task-failed run, and checks each verifier's status against that terminal
312
+ outcome before the bundle is accepted. Observational completion instead
313
+ requires retained workspace evidence and rejects verifier evidence.
314
+
315
+ ## Sharing boundary
316
+
317
+ A partner export that lists restricted native artifacts is `blocked`. A `ready`
318
+ or `exported` package resolves every artifact ID and requires every descriptor
319
+ to have the export's exact sharing class. A public package therefore cannot
320
+ bypass lookup or classification, and both partner and public packages need
321
+ separately sanitized artifacts. Each such descriptor records `sanitizedFrom`
322
+ with the retained source artifact ID and digest, and has a distinct bundle path;
323
+ changing a native artifact's sharing class is not sanitization. The export pipeline performs the actual
324
+ sanitization and readback; the v1 contract fixture makes the unsafe direct
325
+ reference visibly blocked. A ready or exported manifest also names its
326
+ containing bundle before its artifact list is approved. Ready and exported
327
+ manifests contain at least one non-export evidence artifact; blocked and
328
+ unrequested records may be empty but still name their containing bundle.
329
+
330
+ The contract is intentionally only a declaration. Schema loading, safe path
331
+ resolution, atomic persistence, and byte-level digest verification are shared
332
+ artifact primitives delivered separately; no runner, adapter, exporter, or
333
+ evaluation behavior is defined here.
334
+
335
+ ## Fixtures
336
+
337
+ The four small fixtures under `test/fixtures/run-bundles/` establish the
338
+ contract boundary:
339
+
340
+ - `complete`: all five evidence authorities are referenced.
341
+ - `task-failed`: a verifier-backed task failure is distinct from infrastructure
342
+ failure.
343
+ - `interrupted`: retained semantic evidence plus an incomplete capture report;
344
+ no outcome evidence is invented.
345
+ - `telemetry-incomplete`: semantic and outcome evidence remain available while
346
+ optional beta telemetry is explicitly absent.
347
+
348
+ The checked-in Node contract test runs the schema, cross-descriptor uniqueness,
349
+ sharing-path and export boundaries, capture-report correlation, capability
350
+ evidence, artifact references/digests, retry identity, and representative
351
+ rejected records. The later shared artifact validator reuses these fixtures; it
352
+ owns filesystem hardening and persistence rather than a second contract.
353
+ The build script clears compiled output first, and its regression test proves a
354
+ stale compiled test cannot survive into test discovery.
@@ -0,0 +1,54 @@
1
+ # Run lifecycle and process protocol
2
+
3
+ `src/lifecycle.ts` owns one declared run cell and one attempt. A run is
4
+ identified by task, model, and harness IDs; an attempt gets a fresh ID and
5
+ number. `retryAttempt` links a later attempt with `retryOf`, so callers must
6
+ choose a distinct record/evidence path. Attempt paths are reserved before any
7
+ callback runs; an existing record path is never reopened by a new execution,
8
+ and the runner never retries implicitly.
9
+
10
+ The guarded attempt phases are:
11
+
12
+ ```text
13
+ created -> setup -> running -> verifying -> cleaning -> terminal
14
+ ```
15
+
16
+ Setup, harness execution, optional verifier execution, cleanup, and evidence flushing
17
+ are injected callbacks. Setup and harness drivers can register independent
18
+ shutdown handles for in-flight processes. `executeRunAttempt` passes an
19
+ `AbortSignal`, enforces the coordinator and harness budgets, and records phase
20
+ timestamps in an
21
+ `ebo.attempt/v1` record. Each record declares `observational` or `verified`
22
+ assessment. An observational attempt skips the verifying phase; normal harness
23
+ termination plus retained workspace evidence is execution completion, not task
24
+ success. Only a failed verifier on a verified task with retained workspace
25
+ evidence is a task failure; a harness-declared task result without verifier
26
+ evidence remains an infrastructure failure. A verifier execution error, setup
27
+ error, harness error, or cleanup error after an otherwise successful run is
28
+ also infrastructure evidence. A verified completed attempt needs both a passed
29
+ verifier and a retained workspace artifact; an observational completed attempt
30
+ needs the workspace artifact and carries no verifier evidence. Missing capture flush support is
31
+ explicit as `capture-incomplete` and does not become a task failure.
32
+
33
+ `src/process-protocol.ts` is a narrow process boundary, not a JSON-RPC
34
+ implementation. `ProtocolProcess` parses newline-delimited JSON only to reject
35
+ malformed stdout, keeps stdout machine-only, and drains bounded stderr into a
36
+ diagnostic result (and optional `stderrPath`). `ProtocolEvidenceRecorder`
37
+ retains raw frames plus caller-supplied request, response, notification,
38
+ completion, and capability observations. Drivers provide method names,
39
+ correlation IDs, native identities, and completion evidence; the runner does
40
+ not infer prompt completion or map records into EBO event families.
41
+
42
+ JSONL records are flushed and fsynced as they arrive. Valid frames retain their
43
+ original line text alongside parsed data, so duplicate keys or large numeric
44
+ IDs cannot be silently rewritten by a JavaScript round trip. The stdout line
45
+ limit is enforced while bytes are consumed. When a caller supplies a JSONL
46
+ writer, the process derives a conservative effective stdout limit from that
47
+ writer's per-record envelope capacity so retaining both raw and parsed frame
48
+ evidence cannot turn a valid frame into an append failure. In-memory
49
+ observations use a bounded tail; the JSONL file remains the complete source
50
+ record. Interruption and malformed output therefore leave a readable partial
51
+ evidence file and a process result with launch identity, exit/signal state, and
52
+ termination reason.
53
+ `shutdown()` and `interrupt()` are explicit operations; no process retry is
54
+ performed.
@@ -0,0 +1,11 @@
1
+ # Cursor SDK input example
2
+
3
+ These five records are the minimal Cursor-specific inputs referenced by an EBO
4
+ experiment. Copy them into the caller-owned bundle, replace the model
5
+ placeholder with an exact ID returned by `Cursor.models.list()`, compute the
6
+ normal EBO artifact digests, and reference them from the experiment's model,
7
+ harness, native-limits, native-tool-policy, and capture-profile fields.
8
+
9
+ Use the standard `task-packet admit`, `task-packet freeze`, `matrix compile`,
10
+ `queue validate`, and `cursor run` commands. No Cursor-specific preparation
11
+ script or cloud agent is required.
@@ -0,0 +1 @@
1
+ {"schemaVersion":"ebo.cursor-sdk-config/v1","kind":"capture-profile","nativeOtlp":"unsupported","workspaceOutcome":{"excludeDirectoryNames":["node_modules"]}}
@@ -0,0 +1 @@
1
+ {"schemaVersion":"ebo.cursor-sdk-config/v1","kind":"harness","adapter":"cursor-sdk","sdkVersion":"1.0.31"}
@@ -0,0 +1 @@
1
+ {"schemaVersion":"ebo.cursor-sdk-config/v1","kind":"model","provider":"cursor","model":{"id":"REPLACE_WITH_EXACT_CATALOG_MODEL"}}
@@ -0,0 +1 @@
1
+ {"schemaVersion":"ebo.cursor-sdk-config/v1","kind":"native-limits","shutdownGraceMs":2000,"maxNativeRecordBytes":16777216}
@@ -0,0 +1 @@
1
+ {"schemaVersion":"ebo.cursor-sdk-config/v1","kind":"native-tool-policy","tools":["read","edit","grep","glob","ls"],"disallowedTools":["shell","task","mcp","webSearch","webFetch"],"sandbox":{"enabled":false},"settingSources":[],"autoReview":false,"enableAgentRetries":false}