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,131 @@
1
+ # Uniform events and adapter contract
2
+
3
+ EBO normalizes only capture-qualified native evidence. The native session,
4
+ hook, protocol, telemetry, workspace, verifier, and manifest records remain the
5
+ authority; an `ebo.uniform-event/v1` record is a bounded projection with an
6
+ audit link back to those bytes.
7
+
8
+ ## Event projection
9
+
10
+ [`schemas/uniform-events/v1.json`](../../schemas/uniform-events/v1.json) defines the
11
+ event and `ebo.adapter-capability-profile/v1` schemas. Every event carries its
12
+ event, run, and attempt identities; source harness and native type; native
13
+ evidence reference; native order and time; actor; family; phase; scope;
14
+ relations; bounded attributes; and content references.
15
+
16
+ An event may retain up to 4,096 known relations. Native model-request and
17
+ assembled-message events can reference many source chunks; the live DeepSeek
18
+ smoke required 119 relations on one event. Relations are preserved rather than
19
+ silently truncated, and larger sets fail validation explicitly.
20
+
21
+ The initial families are `message`, `model-request`, `tool`, `context`,
22
+ `permission`, `delegation`, `artifact`, `validation`, `runtime`, and `outcome`.
23
+ They are observation categories, not a shared transport or lifecycle protocol.
24
+ The four phases (`before`, `during`, `after`, and `instant`) locate an
25
+ observation around its native operation. They do not claim common completion
26
+ semantics across harnesses.
27
+
28
+ Native order, native time, parentage, and content are explicit evidence values:
29
+
30
+ - `known` carries a native value, an empty list for known-empty content, or
31
+ content references.
32
+ - `unknown` records that the run did not establish the value and gives a reason.
33
+ - `unsupported` records that the source capability cannot provide it and gives
34
+ a reason.
35
+
36
+ Adapters must not substitute a local clock, array position, empty content, or a
37
+ false parent for missing native evidence. Attributes accept at most 32 shallow
38
+ scalar fields, strings are bounded, and nested or large content is represented
39
+ only through a native evidence reference.
40
+
41
+ A known native order includes its source-local `domain`. Sequence values from
42
+ independent session, hook, protocol, or telemetry streams are never compared or
43
+ combined unless retained native evidence establishes that ordering.
44
+
45
+ ## Native references
46
+
47
+ A native reference contains the retained `artifactId` and a source-owned
48
+ `recordLocator`, such as a JSONL line, JSON pointer, or workspace path. EBO does
49
+ not interpret the locator as a universal protocol address. The
50
+ `NativeEvidenceResolver` verifies that each source and content reference
51
+ resolves in the retained bundle before normalized events are accepted.
52
+
53
+ DeepSeek JSON-RPC method names remain native types and record locators.
54
+ OpenHands REST resources, operations, and WebSocket events remain native types
55
+ and record locators. None of them become uniform event families. The same rule
56
+ applies to Agent SDK message and hook names.
57
+
58
+ ## Adapter boundary
59
+
60
+ `NativeCaptureAdapter<Request, NativeRecord>` owns a typed, source-specific
61
+ request and returns one `QualifiedNativeCapture`: the run and attempt identity,
62
+ qualification status, and the native records qualified under that identity. It
63
+ does not impose shared methods, tool names, limits, or completion states.
64
+ `UniformEventNormalizationAdapter<NativeRecord>` consumes that same envelope
65
+ and produces uniform events plus an explicit list of unmapped native references.
66
+
67
+ `assertAdapterContract` checks that:
68
+
69
+ 1. capture, normalizer, and capability-profile identities agree;
70
+ 2. every event and content reference resolves;
71
+ 3. every captured native record is either mapped or retained as unmapped; and
72
+ 4. a normalizer does not invent source references.
73
+
74
+ `AdapterRegistry` receives a fixed list and rejects duplicate harnesses. This is
75
+ explicit registration, not dynamic discovery or a plugin lifecycle. Adding an
76
+ adapter supplies its own native types and capability profile; it does not add
77
+ convenience fields to the event schema.
78
+
79
+ The golden examples in
80
+ `test/fixtures/uniform-events/all-families.v1.json`
81
+ cover all initial families using representative retained harness, verifier,
82
+ telemetry, workspace, and terminal evidence shapes. They deliberately preserve unknown
83
+ time, parentage, and content where the qualified fixtures do not establish
84
+ those facts.
85
+
86
+ ## Agent SDK mapping
87
+
88
+ `normalizeClaudeAgentSdkRunBundle` applies the concrete Agent SDK adapter to a
89
+ retained bundle. It runs structural capture qualification first, verifies every
90
+ artifact digest, normalizes the qualified native records, and resolves every
91
+ emitted source/content reference. An unqualified bundle is rejected before
92
+ normalization.
93
+
94
+ | Native evidence | Uniform families |
95
+ | --- | --- |
96
+ | SDK assistant/user/result and structural system records | `message`, `tool`, `context`, `delegation`, `permission`, `runtime`, `outcome` |
97
+ | Agent SDK callback records | `message`, `tool`, `context`, `permission`, `delegation`, `artifact`, `runtime` |
98
+ | Agent SDK telemetry summary | `runtime` |
99
+ | Workspace manifest descriptor and verifier artifact | `artifact`, `validation` |
100
+ | Run-manifest assessment mode and terminal records | `outcome` |
101
+
102
+ Session and callback sequence numbers keep separate
103
+ `session:<artifact-id>` and `hooks:<artifact-id>` order domains. An originating
104
+ SDK message timestamp is retained when present and valid RFC 3339;
105
+ the adapter never promotes the stream capture clock or hook callback clock to a
106
+ native occurrence time. Tool call/result and hook relations are added only when
107
+ one unique emitted call is supported by the same `tool_use_id`; the same rule
108
+ applies to stable subagent/task and workspace artifact identities.
109
+
110
+ Workspace metadata is sourced from its exact run-manifest evidence-descriptor
111
+ pointer; the qualified workspace bytes remain a content reference. Raw prompts,
112
+ messages, tool inputs/results, compact summaries, and verifier
113
+ assertions stay in their native artifacts. Events contain bounded structural
114
+ attributes and pointers to those bytes. Unknown message/hook records and
115
+ qualification metadata remain reachable through the returned `unmapped`
116
+ report.
117
+
118
+ The returned per-run capability profile records whether detailed-beta hook
119
+ spans were configured. This never changes semantic hook events because
120
+ `hooks.jsonl` is the occurrence authority. That separation follows the Agent
121
+ SDK's documented [callback correlation](https://code.claude.com/docs/en/agent-sdk/hooks)
122
+ and [beta tracing](https://code.claude.com/docs/en/agent-sdk/observability)
123
+ boundaries.
124
+
125
+ Model-switch callbacks remain `runtime` evidence. The retained Agent SDK
126
+ capability record does not expose inference-request lifecycle events, so the
127
+ `model-request` family is reported as unsupported rather than as an observed
128
+ zero.
129
+
130
+ Dataset-wide native-reference, ordering, coverage, and comparison gates are
131
+ documented in [Normalization integrity and comparison gates](normalization-integrity.md).
@@ -0,0 +1,144 @@
1
+ # Behavior Atlas
2
+
3
+ The Atlas combines native Grafana dashboards, a local evidence workbench and a
4
+ standalone HTML research report. It consumes the [aggregation request](../evaluation/aggregation.md)
5
+ and revalidates corpus, structural observations, assertion citations, human
6
+ review lineage and comparison gates. It never runs a judge or edits reviews.
7
+
8
+ ## Rebuild and explore
9
+
10
+ Use Node 24.19.0 and `npm ci && npm run build`. Put this request beside the
11
+ aggregation request. Paths are relative to their containing request.
12
+
13
+ ```json
14
+ {
15
+ "schemaVersion": "ebo.atlas-request/v1",
16
+ "aggregationRequest": "aggregation.json",
17
+ "title": "Behavior study",
18
+ "operatorNarrative": "Optional operator-authored research notes.",
19
+ "atlasUrl": "http://127.0.0.1:13011",
20
+ "grafanaUrl": "http://127.0.0.1:13010",
21
+ "reviewPackets": ["review-packet/index.html"]
22
+ }
23
+ ```
24
+
25
+ ```sh
26
+ ebo atlas build atlas.json atlas-output
27
+ ebo atlas serve atlas.json
28
+ ```
29
+
30
+ Open `http://127.0.0.1:13011`. Model, harness, task, trial, capture, outcome,
31
+ review, category, assessment and text filters select a reproducible cohort.
32
+ Apply with the button or Enter; controls and evidence disclosures use native
33
+ keyboard behavior. Expand a case for rationale, alternative explanation,
34
+ normalized events, cited native records and human decision lineage.
35
+
36
+ Filters select attempts through matching cases. Aggregation keeps **every
37
+ judgment on those attempts**, including conflicting assessments. Filtering for
38
+ constructive cases cannot erase an adverse rerun from the aggregate. Matching
39
+ case and aggregate attempt populations are named separately. Rates expose both
40
+ counts and exclusion reasons; structural means retain their units and are not
41
+ percentages. Observational completion is not task success.
42
+
43
+ The server binds only to `127.0.0.1`, accepts read-only named routes and known
44
+ filter keys, rejects foreign hosts/origins and never maps URLs to arbitrary
45
+ files. It reloads explicitly configured sources for each query. Stale or
46
+ incompatible input fails rather than returning an old aggregate. `--port <port>`
47
+ changes the listener; set `atlasUrl` to the same port before rebuilding dashboards.
48
+ This is a local research workbench, not a hosted multi-user service.
49
+
50
+ ## Grafana
51
+
52
+ Install official **Grafana OSS 13.2.0** for your operating system, then start a
53
+ fresh profile using the generated provisioning:
54
+
55
+ ```sh
56
+ sh scripts/atlas-grafana.sh /path/to/grafana-13.2.0 atlas-output
57
+ ```
58
+
59
+ The script installs **Infinity 4.0.0** from Grafana's official registry in this
60
+ output's private plugin directory. Grafana binds `127.0.0.1:13010` with local
61
+ anonymous Viewer access. Its data, logs, plugins and provisioning stay under
62
+ this output; no existing dashboard, Docker container or volume changes.
63
+ Rebuild into a new output to preserve previous outputs and local changes.
64
+
65
+ Open `/d/ebo-atlas-overview` or `/d/ebo-atlas-behavior` on that Grafana instance.
66
+ Native tables, cohort variables and data links query EBO-derived JSON and open
67
+ the evidence workbench at a selected case. There is no custom plugin code or
68
+ study-specific TestData snapshot. Grafana's time picker affects Tempo only; it
69
+ does not filter the retained EBO cohort.
70
+
71
+ For existing captured traces, point `grafanaUrl` and `tempoDatasourceUid` to a
72
+ profile containing the relevant Tempo data source. Optional `traces` entries
73
+ name `runId`, `attemptId`, a 32-character hexadecimal `traceId`, `originalStart`
74
+ and optional `replayStart` (ISO timestamps). These are operator-configured
75
+ references. Atlas labels both timestamps and neither replays nor invents trace
76
+ data. Without a configured backend and reference it shows trace viewing as
77
+ unavailable. A fresh profile needs its own Tempo data source before trace links
78
+ can resolve.
79
+
80
+ ## Reports and sharing
81
+
82
+ “Open cohort report” freezes the selected filters, exact aggregates, evidence
83
+ cases, operator narrative, method, limitations and source/cohort digests in
84
+ standalone HTML. Save it and use “Print / save PDF.” The JSON link retains
85
+ supporting data. No server or frontend build is needed to open the saved report.
86
+
87
+ ```sh
88
+ ebo atlas build atlas.json selected-report \
89
+ --filter model=model-a --filter review=confirmed
90
+ ```
91
+
92
+ Output must be a new directory outside immutable sources. The offline report
93
+ declares its frozen population and never recalculates semantic populations in
94
+ browser JavaScript. Cited records use the existing export sanitizer to omit
95
+ secrets, hidden fields and local paths; original evidence remains authoritative.
96
+ Assertion/source digests identify the original. Existing human packet links are
97
+ local file URLs; browsers may block them from HTTP, so open them from the saved
98
+ local report.
99
+
100
+ This does not require paid Grafana reporting: Grafana's scheduled reports and
101
+ dashboard PDF exports are Enterprise features. EBO uses standalone HTML and
102
+ browser printing. See [Grafana's official sharing documentation](https://grafana.com/docs/grafana/latest/visualizations/dashboards/share-dashboards-panels/).
103
+
104
+ Ordinary reports are **restricted-local-only**, even when cited displays are
105
+ sanitized. A shareable summary requires existing portable exports covering every
106
+ selected source manifest. Add `sharing` to the request using the exact policy
107
+ used to create those exports:
108
+
109
+ ```json
110
+ {
111
+ "sharing": {
112
+ "policy": { "sharingClass": "partner", "maxArtifactBytes": 16777216, "maxStringBytes": 8192 },
113
+ "approvedExports": ["approved/run-a", "approved/run-b"],
114
+ "fields": ["cohort", "aggregate-metrics", "source-digests"]
115
+ }
116
+ }
117
+ ```
118
+
119
+ `ebo atlas build atlas.json shareable-summary --share` reuses portable export
120
+ readback, policy/digest validation, sanitization and final secret scanning.
121
+ Source correlations are rewritten. Unsupported fields fail closed. Semantic
122
+ assertions/distributions, human prose, native records, raw prompts, trace/review
123
+ links and operator narrative lack portable field classifications and are
124
+ excluded. Local review access never grants sharing approval. Nothing uploads,
125
+ emails or publishes the report.
126
+
127
+ Shared summaries accept model, harness, task, trial, capture and outcome
128
+ filters. Review, category, assessment and free-text evidence filters are
129
+ rejected: even without case details, their selected-cohort counts would disclose
130
+ semantic or human-review findings that have no export approval.
131
+
132
+ ## Synthetic verification
133
+
134
+ ```sh
135
+ node dist/test/atlas-fixture.js .ebo/atlas-fixture
136
+ ebo atlas build .ebo/atlas-fixture/atlas.json .ebo/atlas-report
137
+ ebo atlas serve .ebo/atlas-fixture/atlas.json
138
+ node --test dist/test/atlas.test.js
139
+ ```
140
+
141
+ The generator injects synthetic capture streams and fixture review decisions;
142
+ it never calls a model or labels real research. It covers opposite assessments,
143
+ confirmed/disputed/rejected/proposed/abstained/unavailable states, a retry,
144
+ missing observations, an unsupported comparison and hostile text.
@@ -0,0 +1,100 @@
1
+ # Inspect and share evidence
2
+
3
+ A run bundle is the retained record of one attempt. Begin with its manifest,
4
+ not a filename guessed from another harness.
5
+
6
+ ## Read a run
7
+
8
+ | Read | Question |
9
+ | :--- | :--- |
10
+ | CLI summary | Where is the bundle? Did cleanup leave a workspace to recover? |
11
+ | `manifest.json` | Which run/attempt, runtime, configuration, terminal and evidence descriptors belong together? |
12
+ | Capture report referenced by the manifest | Which evidence qualified? What is missing or unsupported? |
13
+ | Native session/store/hooks | What did the agent and harness actually emit? |
14
+ | Workspace descriptor and patch/snapshot | What changed from the frozen starting tree? |
15
+ | Derived observations | Which mechanical facts are supported, and by which native records? |
16
+
17
+ Each evidence descriptor gives the retained path, media type, size, digest, and
18
+ authority. Names differ by harness. A Pi session tree and a Cursor JSONL store
19
+ are not interchangeable with an Agent SDK stream.
20
+
21
+ ```sh
22
+ ebo validate <bundle-root>/manifest.json
23
+ ebo observations create <bundle-root> study/observations.json
24
+ ebo corpus build study/runs study/index.jsonl
25
+ ebo corpus validate study/runs study/index.jsonl
26
+ ebo corpus query study/index.jsonl --capture qualified
27
+ ```
28
+
29
+ `validate` checks supported artifact schemas; it is not a claim that every
30
+ referenced byte or capability was verified. Observation creation and corpus
31
+ validation perform their documented retained-evidence checks. Review
32
+ `qualified-with-gaps` separately, using the gaps relevant to your question.
33
+
34
+ The corpus index is a rebuildable JSONL view, not the source of truth. It
35
+ indexes identities and capture/outcome facts rather than prompt and tool bodies.
36
+
37
+ ## Preserve partial attempts
38
+
39
+ Do not discard an interrupted run because it lacks a final answer. Its native
40
+ events can still explain a stop. Keep terminal state, infrastructure failure,
41
+ and capture quality separate. Preserve `retainedWorkspacePath` when outcome
42
+ packaging failed; that path is a recovery location, not qualified evidence.
43
+
44
+ Use a new output destination for derived records and reruns. Do not edit a
45
+ native bundle to make a validator accept it.
46
+
47
+ ## Create a portable export
48
+
49
+ Review the sharing authorization and source material first. Sanitization reduces
50
+ disclosure risk; it does not grant permission to distribute someone else's code.
51
+
52
+ Save a caller-owned policy as `study/export-policy.json`:
53
+
54
+ ```json
55
+ {
56
+ "sharingClass": "partner",
57
+ "maxArtifactBytes": 16777216,
58
+ "maxStringBytes": 8192,
59
+ "sensitiveValues": []
60
+ }
61
+ ```
62
+
63
+ Add known confidential strings to `sensitiveValues` when necessary. Keep
64
+ that policy restricted if it contains them. Bounds are examples: choose values
65
+ appropriate to the evidence, not a reason to silently truncate it.
66
+
67
+ ```sh
68
+ ebo export create <bundle-root> study/export-policy.json study/exports/run-a
69
+ ebo corpus pack study/exports/run-a study/export-policy.json study/run-a.tar.gz
70
+ ```
71
+
72
+ Export creates a separate derivative, removes hidden reasoning and detected
73
+ secrets/local identifiers, rewrites correlations, and validates the output.
74
+ Unknown classifications, unsupported content, or failed integrity/secret checks
75
+ stop creation. Native source bytes remain unchanged. Inspect the export manifest
76
+ for transformations and exclusions: opaque workspace snapshots, for example,
77
+ are not made shareable by passing through a text sanitizer.
78
+
79
+ Packing revalidates the derivative with the same policy, follows the export
80
+ manifest allowlist, and records only approved members. It does not publish.
81
+
82
+ To inspect a received archive:
83
+
84
+ ```sh
85
+ ebo corpus unpack study/run-a.tar.gz study/received-run-a
86
+ ```
87
+
88
+ The destination must not exist. Unpacking validates archive bounds, membership,
89
+ paths, and digests. Do not replace this with manual extraction of an untrusted
90
+ archive into your checkout.
91
+
92
+ ## Reports are a separate sharing surface
93
+
94
+ An ordinary Atlas report is **restricted-local-only**, even if displayed
95
+ citations are sanitized. Shareable summaries require approved exports for every
96
+ selected source and an explicit Atlas sharing policy. See
97
+ [reports and sharing](atlas.md#reports-and-sharing) for supported fields and
98
+ exclusions.
99
+
100
+ For field-level details, see the [run-bundle contract](../reference/run-bundle-contract.md).