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,153 @@
1
+ # OpenHands Agent Server adapter
2
+
3
+ The OpenHands adapter executes one EBO attempt through a pinned Agent Server
4
+ REST/WebSocket boundary. It preserves the source records before projecting any
5
+ uniform events. It does not import the OpenHands Python SDK or embed the agent
6
+ loop.
7
+
8
+ ## Pinned boundary
9
+
10
+ The runtime pin is Agent Server `1.46.0`. The matching release OpenAPI digest,
11
+ server commit, image, event discriminator list, WebSocket route, and
12
+ authentication mode are recorded in the
13
+ [contract manifest](../../contracts/openhands-agent-server-v1.46.0.json).
14
+
15
+ The 1.46.0 upgrade preserves the existing conversation endpoints and consumed
16
+ event schemas. The upstream schema changes concern ACP agents and skill requests,
17
+ which this adapter does not use. Historical 1.44.1 fixtures and the contract
18
+ manifest remain unchanged; retained evaluation keeps their original runtime and
19
+ adapter identity.
20
+
21
+ For a native macOS ARM64 installation, download the release's
22
+ `agent-server-1.46.0-macos-arm64` and verify it against `SHA256SUMS` (also pinned
23
+ in the contract manifest). Mark the binary executable and launch it with:
24
+
25
+ ```sh
26
+ agent-server-1.46.0-macos-arm64 --host 127.0.0.1 --port 18080
27
+ curl --fail http://127.0.0.1:18080/server_info
28
+ ```
29
+
30
+ The identity response must report `1.46.0`. Server readiness does not establish
31
+ a working model route; the opt-in conversation smoke below verifies that separately.
32
+
33
+ `@openhands/typescript-client` `1.39.0` was checked against that contract. Its
34
+ generated types target Agent Server `1.44.0`, and its WebSocket wrapper neither
35
+ exposes reconnect lifecycle evidence nor uses the current first-message
36
+ authentication path. EBO therefore uses Node's native `fetch` and `WebSocket`
37
+ APIs for this boundary and does not add the client as a runtime dependency.
38
+
39
+ ## Capture flow
40
+
41
+ `captureOpenHandsAgentServerRun` coordinates one caller-supplied run definition:
42
+
43
+ The run configuration must expose the actual model at `agent.llm.model` or
44
+ `agent_settings.llm.model`; EBO rejects a request whose executable model differs
45
+ from the run manifest identity.
46
+
47
+ 1. Verify `/server_info` reports exactly `1.46.0`.
48
+ 2. Create one conversation with the supplied agent configuration and the
49
+ workspace path visible to the server. Authenticated REST requests use the
50
+ pinned server's `X-Session-API-Key` header.
51
+ 3. Open `/sockets/events/{conversation_id}` with `resend_mode=all`, authenticate
52
+ in the first frame when required, and submit the message through REST.
53
+ 4. Poll the conversation until `finished`, `error`, or `stuck`.
54
+ 5. Read every final event page in timestamp order, reconcile by native event ID,
55
+ then clean up the conversation.
56
+ 6. Package native JSONL, exposed hook events, the workspace outcome, and the EBO
57
+ verifier result before finalizing the run bundle. If workspace packaging
58
+ fails, preserve and report the disposable workspace path for recovery.
59
+
60
+ Container callers can set `serverWorkspacePath` when the Agent Server sees a
61
+ different mount path from the local EBO coordinator.
62
+
63
+ ## Reconciliation and completeness
64
+
65
+ Unexpected socket closure reconnects with `resend_mode=since` from the last
66
+ native event timestamp. Inclusive replay can deliver duplicates. EBO retains
67
+ every receipt as native evidence, selects the final REST copy as the canonical
68
+ normalization source, and emits one uniform event per native event ID.
69
+
70
+ The result reports streamed-only and final-only IDs. A failed final REST read
71
+ keeps the streamed records and marks reconciliation partial. Unknown `kind`
72
+ values remain in native JSONL and are listed as unmapped; they never crash the
73
+ capture.
74
+
75
+ REST responses and WebSocket frames are bounded before parsing, event capture
76
+ has a fixed upper limit, and repeated pagination cursors fail into partial
77
+ evidence. A coordinator abort closes the socket, stops polling, attempts final
78
+ REST recovery and cleanup with a short independent bound, and retains the
79
+ records already received.
80
+
81
+ Matching REST and WebSocket IDs proves agreement between those two public API
82
+ views only. The boundary does not expose enough evidence to prove delivery of
83
+ the complete in-process `EventLog`, so every otherwise usable capture records
84
+ `EVENT_LOG_COMPLETENESS_UNPROVEN` as a qualification gap.
85
+
86
+ ## Uniform projection
87
+
88
+ The adapter maps only fields present in the pinned event contract:
89
+
90
+ | Native record | Uniform family | Preserved distinctions |
91
+ |---|---|---|
92
+ | `MessageEvent`, `SystemPromptEvent` | `message` | actor comes from native `source`, not LLM role |
93
+ | `ActionEvent` | `tool` / before | tool and call identities |
94
+ | `ObservationEvent` | `tool` / after | `action_id` causal relation |
95
+ | `AgentErrorEvent` | `tool` / after | `agent-tool` error scope |
96
+ | `ConversationErrorEvent` | `runtime` | conversation error scope |
97
+ | `ServerErrorEvent` | `runtime` | server error scope |
98
+ | condensation records | `context` | exposed forgotten-event IDs stay native attributes |
99
+ | `HookExecutionEvent` | `runtime` | hook type, result, and exposed action/message association |
100
+ | state, pause, and interrupt records | `runtime` | source status facts |
101
+ | final conversation record | `outcome` | terminal status and workspace identity |
102
+
103
+ Workspace and verifier evidence are packaged through the existing EBO outcome
104
+ contracts. Agent Server product telemetry is not treated as complete native
105
+ OpenTelemetry evidence.
106
+
107
+ The native run bundle is finalized and capture-qualified before uniform-event
108
+ projection. A projection error is returned separately and does not replace the
109
+ recorded terminal state or make the retained native/workspace evidence
110
+ inaccessible. Unqualified capture is not normalized.
111
+
112
+ ## Validation
113
+
114
+ The normal test suite uses pinned streamed/final fixtures for reconnect,
115
+ deduplication, errors, condensation, hooks, unknown variants, and partial REST
116
+ failure. The live smoke is opt-in because it requires a running pinned server
117
+ and a permitted model route:
118
+
119
+ ```sh
120
+ export EBO_LIVE_OPENHANDS_WORKSPACE_ROOT=/path-visible-to-host-and-server
121
+ # Set SESSION_API_KEY and EBO_OPENHANDS_SESSION_API_KEY to the same local
122
+ # smoke-only value in the invoking environment.
123
+ mkdir -p "$EBO_LIVE_OPENHANDS_WORKSPACE_ROOT"
124
+ docker run --rm --name ebo-openhands-smoke -p 127.0.0.1:8010:8000 \
125
+ -v "$EBO_LIVE_OPENHANDS_WORKSPACE_ROOT:$EBO_LIVE_OPENHANDS_WORKSPACE_ROOT" \
126
+ -e SESSION_API_KEY \
127
+ ghcr.io/openhands/agent-server:1.46.0-python --host 0.0.0.0
128
+
129
+ npm run build
130
+ EBO_LIVE_OPENHANDS_SMOKE=1 \
131
+ EBO_OPENHANDS_SERVER_URL=http://127.0.0.1:8010 \
132
+ node --test --test-name-pattern='approved live Agent Server smoke' \
133
+ dist/test/openhands.test.js
134
+ ```
135
+
136
+ The smoke asks the agent to modify one file, verifies the retained workspace,
137
+ and requires native stream/final records, hook evidence, a verifier result, a
138
+ run bundle, normalized events, and the explicit EventLog completeness gap.
139
+ `LLM_MODEL` and `LLM_API_KEY` must name an approved route before the test runs.
140
+
141
+ For an OpenAI-compatible endpoint, use its LiteLLM `openai/` model prefix and
142
+ set `LLM_BASE_URL`. For example, the Z.ai coding-plan smoke used
143
+ `LLM_MODEL=openai/glm-5.3-flash` and
144
+ `LLM_BASE_URL=https://api.z.ai/api/coding/paas/v4`, with `LLM_API_KEY` supplied
145
+ from the operator's `ZAI_API_KEY` environment variable.
146
+
147
+ Set `EBO_LIVE_OPENHANDS_KEEP_ARTIFACTS=1` to retain the smoke directory and print
148
+ its location, including on failure. These native artifacts remain restricted.
149
+ On the tested macOS installation, the default tmux pool failed during tool
150
+ initialization. `EBO_LIVE_OPENHANDS_TERMINAL_TYPE=subprocess` selects OpenHands'
151
+ supported subprocess terminal for this smoke. With that setting, the 1.46.0
152
+ server completed the Z.ai run, verified the workspace, and produced normalized
153
+ events with the declared EventLog completeness gap.
@@ -0,0 +1,66 @@
1
+ # Pi TypeScript SDK harness
2
+
3
+ EBO integrates `@earendil-works/pi-coding-agent` `0.85.1` directly through its public TypeScript SDK. `ebo pi run` executes one caller-selected frozen queue entry; it does not add RPC, ACP, a Pi fork, or another scheduler.
4
+
5
+ ## Operator command
6
+
7
+ ```sh
8
+ ebo pi run \
9
+ <bundle-root> <queue.json> <run-id> <output-root> \
10
+ [--workspace-root <path>]
11
+ ```
12
+
13
+ The queue uses the existing model, harness, native-limits, native-tool-policy, and capture-profile references. Each referenced record declares `schemaVersion: "ebo.pi-config/v1"`. The checked-in synthetic shapes are under `test/fixtures/pi/configs/`; their provider URL is intentionally non-routable.
14
+
15
+ The model record owns the queue model-condition ID, effective provider/model, API dialect, base URL, credential environment-variable name, thinking level, optional provider-specific thinking-level map, advertised input types, context/output limits, and the pricing inputs Pi requires. Pi's opt-in `xhigh` and `max` levels require an explicit non-null mapping in this digest-bound record so the SDK cannot silently clamp them. Credentials remain process environment only; the runtime uses an empty attempt-local credential store so the user's Pi home cannot override the selected route. The retained composition also records Pi's effective non-secret prompt-cache retention (`long` or `short`) so ambient `PI_CACHE_RETENTION` differences remain explicit. The harness record pins Pi and may explicitly reference digest-bound extensions, skills, prompt templates, context files, and a system prompt. Admitted extension modules must be self-contained; import, dynamic-import, re-export, and CommonJS dependency syntax is rejected so the entrypoint digest covers the complete executable extension. Candidate workspace resources and the user's Pi home are not auto-discovered. The capture profile can set `passiveObserver: false` for a controlled observer-disabled condition; it defaults to enabled.
16
+
17
+ The tool-policy record selects Pi's public built-in tools and a child-process environment allowlist. The provider credential variable is rejected if it appears in that allowlist. This is configuration containment, not an OS sandbox: Pi still runs in the local trusted environment and its file tools can access paths allowed by the host account.
18
+
19
+ ## Native evidence
20
+
21
+ One attempt owns one native Pi session. EBO retains three separately addressable restricted artifacts:
22
+
23
+ | Artifact | Authority | Contents |
24
+ |---|---|---|
25
+ | `pi-session.jsonl` | authoritative history | Pi session header and append-only entries with original IDs, parent links, messages, usage, compaction, model and thinking changes |
26
+ | `pi-events.jsonl` | transient lifecycle | subscription events such as agent/turn/message/tool/retry/compaction lifecycle plus adapter cleanup/error records |
27
+ | `pi-observer.jsonl` | passive metadata | ordered public extension hooks for context, provider request/response stages, tool calls/results, compaction and session lifecycle |
28
+
29
+ Callback values are snapshotted at receipt and writes are serialized and drained before finalization. Provider payload content is off by default; when explicitly enabled it stays restricted. Header values are never recorded. The observer returns no context, prompt, provider-payload, tool-call, or tool-result modifications.
30
+
31
+ Pi history owns final messages and usage. Streamed message updates retain only their incremental event fields; cumulative `message` and `partial` snapshots are omitted to avoid quadratic evidence growth, while final content remains authoritative in native history. Streamed message deltas and passive tool hooks remain reachable but are explicitly unmapped where projecting them would double-count history or tool operations. Adapter receipt time is labeled in attributes and is never promoted to a native timestamp. Errors from selected extension hooks are retained as observer diagnostics and prevent the capture from qualifying.
32
+
33
+ On timeout or cancellation EBO calls the public `session.abort()` API, waits for idle, copies the original persisted native session tree, emits shutdown, disposes the session, drains recorders, and then packages the workspace. The SDK branch-export helper is only a fallback when native persistence is unavailable. Creation, provider, export, recorder, and cleanup failures retain a partial attempt; recorder loss cannot qualify as success. The single configured retry bound applies to Pi's agent-level loop while provider-library retries remain disabled, preventing multiplicative requests.
34
+
35
+ ## Capability and gap matrix
36
+
37
+ | Surface | Status | Evidence/gap |
38
+ |---|---|---|
39
+ | messages and native session tree | available | persisted Pi JSONL plus subscription start/end records |
40
+ | model requests | available | passive `before_provider_request`; payload content opt-in restricted |
41
+ | tool operations | available | subscription start/update/end keyed by native tool-call ID |
42
+ | context and compaction | available | context/compaction hooks plus native history |
43
+ | retries | available | public session retry lifecycle events |
44
+ | provider usage | available | native assistant-message usage; treated as per-message increments |
45
+ | permissions | unsupported | no distinct selected public-SDK permission-decision record |
46
+ | delegation/child histories | unsupported | one owned Pi session per attempt; no branching/resume UI |
47
+ | native OTLP receipt | unsupported | no verified native Pi `0.85.1` OTLP receipt surface |
48
+ | isolation | limited | local SDK execution is not an OS sandbox |
49
+
50
+ ## Validation
51
+
52
+ The deterministic fixture exercises the real queue, workspace, bundle, qualification, export/readback, observation, comparison, judge-package, calibration, aggregation, and Atlas paths with an SDK-shaped session seam:
53
+
54
+ ```sh
55
+ npm run build
56
+ node --test dist/test/pi.test.js
57
+ ```
58
+
59
+ The approved live smoke performs one synthetic file edit through Z.ai's OpenAI-compatible Chat Completions route. It is opt-in and never prints the key:
60
+
61
+ ```sh
62
+ EBO_LIVE_PI_SDK_SMOKE=1 node --test \
63
+ --test-name-pattern='approved live Pi SDK smoke' dist/test/pi.test.js
64
+ ```
65
+
66
+ Set `ZAI_API_KEY` in the environment. The smoke selects `glm-5.3-flash` and `https://api.z.ai/api/coding/paas/v4` only in its generated test input; neither is a product default.
@@ -0,0 +1,19 @@
1
+ # Reference
2
+
3
+ Use guides to learn a workflow; use these pages when implementing or checking
4
+ an exact contract.
5
+
6
+ | Reference | Answers |
7
+ | :--- | :--- |
8
+ | [CLI](cli.md) | Commands grouped by preparation, capture, evidence, evaluation, and reports |
9
+ | [Task packets and experiments](contracts.md) | Archive rules, admission, freeze, configuration digests, run matrices |
10
+ | [Run bundles](run-bundle-contract.md) | Evidence descriptors, terminal states, qualification, workspace and export contracts |
11
+ | [Run lifecycle](run-lifecycle.md) | Attempt ownership, interruption, retries, process boundary |
12
+ | [Agent SDK configuration](agent-sdk-operational-runner.md) | Five source-specific queue records and runner behavior |
13
+ | [Uniform events](../evaluation/uniform-events.md) | Families, native references, coverage, explicit unknown/unsupported values |
14
+ | [Extension contracts](../development/extension-contracts.md) | How new adapters and evaluators fit existing interfaces |
15
+
16
+ Machine-readable contracts are shipped under `schemas/`, `contracts/`, and
17
+ `ontology/`. Paths in versioned records are interpreted by their contract,
18
+ not automatically relative to your current shell directory. CLI filesystem
19
+ arguments are operator paths; packet locators remain bundle-relative.
@@ -0,0 +1,118 @@
1
+ # Agent SDK queue configuration
2
+
3
+ This reference describes the implemented `ebo agent-sdk run` input contract.
4
+ For authentication and native evidence, start with
5
+ [the harness guide](../harnesses/claude-agent-sdk.md). For packet preparation,
6
+ see [the operator workflow](../guides/operator-guide.md).
7
+
8
+ ## Command
9
+
10
+ ```sh
11
+ ebo agent-sdk run <bundle-root> <queue.json> <run-id> <output-root> [--workspace-root <path>]
12
+ ```
13
+
14
+ The runner validates a persisted queue entry, rechecks its frozen packet and
15
+ configuration digests, materializes a disposable workspace, and calls the
16
+ capture API once. It retains a starting baseline until outcome capture finishes,
17
+ then reopens the manifest before returning a summary.
18
+
19
+ The summary contains `runId`, `attemptId`, `bundlePath`,
20
+ `assessmentMode`, `terminal`, `classification`, and
21
+ `captureQualification`, plus native session/trace IDs when available.
22
+ A captured failure or stop is a valid observation, not necessarily a nonzero
23
+ CLI exit. Preflight or final validation failures return nonzero.
24
+
25
+ ## Five configuration records
26
+
27
+ Each JSON block below is a **separate file**, referenced and SHA-256 pinned by
28
+ the experiment/queue. Bounds and model values are examples, not research
29
+ defaults. Authentication stays in the process environment.
30
+
31
+ ```json
32
+ { "schemaVersion": "ebo.agent-sdk-config/v1", "kind": "model", "model": "sonnet" }
33
+ ```
34
+
35
+ ```json
36
+ { "schemaVersion": "ebo.agent-sdk-config/v1", "kind": "harness", "adapter": "claude-agent-sdk" }
37
+ ```
38
+
39
+ ```json
40
+ {
41
+ "schemaVersion": "ebo.agent-sdk-config/v1",
42
+ "kind": "native-limits",
43
+ "maxTurns": 8,
44
+ "maxBudgetUsd": 1
45
+ }
46
+ ```
47
+
48
+ ```json
49
+ {
50
+ "schemaVersion": "ebo.agent-sdk-config/v1",
51
+ "kind": "native-tool-policy",
52
+ "tools": ["Read", "Edit", "Bash"],
53
+ "allowedTools": ["Read", "Edit", "Bash"],
54
+ "disallowedTools": [],
55
+ "permissionMode": "dontAsk"
56
+ }
57
+ ```
58
+
59
+ ```json
60
+ {
61
+ "schemaVersion": "ebo.agent-sdk-config/v1",
62
+ "kind": "capture-profile",
63
+ "telemetry": {
64
+ "endpoint": "http://127.0.0.1:4318",
65
+ "protocol": "http/json",
66
+ "exportIntervalMs": 1000,
67
+ "logUserPrompts": false,
68
+ "logToolDetails": false,
69
+ "logToolContent": false,
70
+ "logRawApiBodies": false
71
+ },
72
+ "workspaceOutcome": {
73
+ "excludeDirectoryNames": ["node_modules", "coverage"],
74
+ "respectGitignore": true,
75
+ "omitEmptyDirectories": true
76
+ }
77
+ }
78
+ ```
79
+
80
+ Rules:
81
+
82
+ - The queue entry's model, harness, native-limits, native-tool-policy, and queue-level capture-profile references must resolve to the corresponding `kind`.
83
+ - Duplicate JSON keys, unknown fields, unsafe numbers, wrong kinds, digest mismatches, malformed UTF-8, and malformed JSON are rejected before SDK launch.
84
+ - The model record's `model` must equal the queue entry's model ID, matching the existing capture invariant.
85
+ - The harness adapter must be `claude-agent-sdk`.
86
+ - `maxTurns` and `maxBudgetUsd` are optional positive limits. The queue's coordinator `maxWallClockMs` remains the outer wall-clock limit.
87
+ - Tool lists are arrays of unique nonempty strings. Preserve Agent SDK names; do not invent a common tool ontology.
88
+ - `bypassPermissions` is accepted only when `allowDangerouslySkipPermissions` is explicitly true, matching the existing executor safeguard.
89
+ - Telemetry content flags default to false. Credentials and environment overrides are never read from these JSON files; authentication stays in the process environment.
90
+ - A configured telemetry endpoint without a receipt checker remains explicit `not-checked` or missing receipt evidence. Do not claim collector receipt from a successful HTTP configuration alone.
91
+
92
+ ## Retention and recovery
93
+
94
+ The output bundle is written under `<output-root>/<run-id>/<attempt-id>`.
95
+ Each invocation has a fresh attempt identity. The command does not iterate,
96
+ resume, or silently retry; ordinary CLI reruns do not claim linked retry lineage.
97
+
98
+ Only the admitted `agentInput` prompt and materialized fixture enter execution.
99
+ Observational packets have no verifier. Verified packets run their admitted
100
+ verifier on the retained workspace snapshot and keep its result separate from
101
+ capture qualification.
102
+
103
+ The capture layer retains complete or partial native evidence after execution
104
+ starts. If workspace packaging fails, the summary may expose
105
+ `retainedWorkspacePath` for local recovery. Do not delete that directory until
106
+ the outcome has been recovered. Cleanup failure after successful packaging
107
+ also leaves the path visible; it does not erase the retained bundle.
108
+
109
+ ## Library use
110
+
111
+ `runAgentSdkQueueEntry` accepts the same paths and selected run ID, plus
112
+ an optional abort signal and in-process test/receipt callbacks.
113
+ `captureClaudeAgentSdkRun` accepts an already-resolved attempt and explicit
114
+ workspace composition. Neither is a general task generator or study scheduler.
115
+
116
+ See [lifecycle](run-lifecycle.md) and
117
+ [run-bundle contracts](run-bundle-contract.md) for ownership, interruption,
118
+ qualification, and artifact invariants.
@@ -0,0 +1,114 @@
1
+ # CLI reference
2
+
3
+ Install `ebo` with [the quickstart](../guides/quickstart.md). `ebo --help`
4
+ prints the current top-level syntax. For a source checkout without `npm link`,
5
+ use `npm run ebo -- <arguments>`.
6
+
7
+ For one-offs without a global install, use
8
+ `npm exec --package=engineering-behavior-observatory -- ebo --help`.
9
+ Avoid `npx ebo`, which targets a different package.
10
+
11
+ `<angle-bracket>` values are required placeholders; `[square-bracket]` items
12
+ are optional. Do not paste these templates unchanged. `packet.json` and freeze
13
+ locators are relative to the declared bundle root; other filesystem arguments
14
+ are operator paths. Record destinations must be outside immutable evidence.
15
+
16
+ ## Validate artifacts
17
+
18
+ ```sh
19
+ ebo validate <artifact.json>...
20
+ ebo task-packet <validate|admit|freeze|status> <bundle-root> <packet.json> [freeze-record.json]
21
+ ```
22
+
23
+ `validate` checks registered artifact schemas. The source-specific readers,
24
+ capture qualification, and export readback perform additional evidence checks.
25
+
26
+ ## Prepare inputs
27
+
28
+ Validate/admit/freeze a caller-authored packet, then compile a deterministic queue. These commands do not generate tasks or run models.
29
+
30
+ ```sh
31
+ ebo matrix compile <experiment.json> <bundle-root> <queue.json> [--freeze-locator <task-id>=<path>]
32
+ ebo queue inspect <queue.json>
33
+ ebo queue validate <queue.json> [experiment.json] [--bundle-root <bundle-root>]
34
+ ```
35
+
36
+ ## Capture one attempt
37
+
38
+ Execute one selected frozen entry. Use the matching harness configuration and authentication. OpenHands and DeepSeek expose library APIs, not CLI run commands.
39
+
40
+ ```sh
41
+ ebo agent-sdk run <bundle-root> <queue.json> <run-id> <output-root> [--workspace-root <path>]
42
+ ebo codex run <bundle-root> <queue.json> <run-id> <output-root> [--workspace-root <path>]
43
+ ebo cursor run <bundle-root> <queue.json> <run-id> <output-root> [--workspace-root <path>]
44
+ ebo pi run <bundle-root> <queue.json> <run-id> <output-root> [--workspace-root <path>]
45
+ ```
46
+
47
+ ## Inspect and share evidence
48
+
49
+ Index retained manifests, query exact metadata, or create and transport a policy-checked derivative. Export and packing do not publish.
50
+
51
+ ```sh
52
+ ebo export create <run-bundle-root> <policy.json> <export-root>
53
+ ebo corpus build <corpus-root> <index.jsonl>
54
+ ebo corpus query <index.jsonl> [--kind|--run|--attempt|--task|--model|--harness|--assessment-mode|--terminal|--failure-class|--verifier-status|--capture|--export-status|--sharing-class <value>]
55
+ ebo corpus validate <corpus-root> <index.jsonl>
56
+ ebo corpus pack <export-root> <policy.json> <archive.tar.gz>
57
+ ebo corpus unpack <archive.tar.gz> <destination-root>
58
+ ```
59
+
60
+ ## Derive facts and evaluate
61
+
62
+ Observations qualify and normalize retained evidence before extracting structural facts. Judging requires an explicit request and may call a live provider; assertions remain proposals until reviewed.
63
+
64
+ ```sh
65
+ ebo observations create <run-bundle-root> <output.json>
66
+ ebo observations corpus <corpus-root> <index.jsonl> <output-root> [corpus query flags]
67
+ ebo assertions validate <run-bundle-root> <assertion.json> [review.json]
68
+ ebo judge run <run-bundle-root> <observations.json> <request.json> <output-root>
69
+ ```
70
+
71
+ ## Record human review
72
+
73
+ Select evidence and build static review packets. Import human-authored decisions; these commands do not manufacture reviewer identities or judgments.
74
+
75
+ ```sh
76
+ ebo calibration sample <sources.json> <criteria.json> <selection.json>
77
+ ebo calibration packet <selection.json> <output-root>
78
+ ebo calibration inspect <packet.json> <assertion-id> [event-id]
79
+ ebo calibration binding <selection.json> <assertion-id> [history.json]
80
+ ebo calibration <import|adjudicate> <selection.json> <history.json> <decision.json>
81
+ ebo calibration summarize <selection.json> <history.json> <summary.json>
82
+ ```
83
+
84
+ ## Compare and present
85
+
86
+ Check comparison eligibility, aggregate declared populations, and build or serve a local Atlas. These commands consume existing judgments rather than invoking a judge.
87
+
88
+ ```sh
89
+ ebo comparison check <request.json>
90
+ ebo aggregate build <request.json> <output.json>
91
+ ebo atlas build <request.json> <output-root> [--share] [--filter <name=value>]
92
+ ebo atlas serve <request.json> [--port <port>]
93
+ ```
94
+
95
+ ## Operational behavior
96
+
97
+ - A queue-run command executes one entry and creates a new attempt. It does not
98
+ schedule the whole queue or silently retry.
99
+ - A successful exit can mean a valid **captured failure or stop**. Read the run
100
+ summary, manifest, and capture report before interpreting the result.
101
+ - `queue inspect` prints summary information. Read `queue.json` for run IDs.
102
+ - Corpus filters use exact matches. Indexes are rebuildable; native manifests
103
+ and records remain authoritative.
104
+ - There is no standalone `normalize` command: observations invoke the
105
+ qualified retained-source path.
106
+ - `comparison check` prints a report to stdout; redirect it to a file when an
107
+ aggregation request needs it. Unsupported comparisons return nonzero.
108
+ - New export, unpack, judgment, and report destinations must not already exist.
109
+ - Atlas defaults to a loopback-only service. Ordinary reports remain restricted;
110
+ `--share` requires policy-validated source exports and excludes unsupported
111
+ semantic/review fields.
112
+
113
+ For preparation and recovery, use the [operator guide](../guides/operator-guide.md).
114
+ For field definitions, use the [reference index](README.md).