engineering-behavior-observatory 0.2.7 → 0.2.8

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.
@@ -19,7 +19,7 @@ const CURSOR_NATIVE_SCHEMA_VERSION = "ebo.cursor-native-record/v1";
19
19
  const MAX_NATIVE_RECORD_BYTES = 16 * 1024 * 1024;
20
20
  const STREAM_TYPES = ["assistant", "request", "status", "system", "task", "thinking", "tool_call", "usage", "user"];
21
21
  const NATIVE_TYPES = [
22
- "configuration", "agent-created", "run-created", "delta", "step", "terminal", "history", "billing", "error", "cleanup",
22
+ "configuration", "agent-created", "run-created", "delta", "step", "terminal", "history", "billing", "usage-snapshot", "error", "cleanup",
23
23
  ...STREAM_TYPES.map((type) => `stream:${type}`),
24
24
  "stream:unknown", "store:agent", "store:run", "store:run-event", "store:checkpoint", "store:unknown",
25
25
  ];
@@ -443,6 +443,21 @@ async function executeCursorSdk(options) {
443
443
  }
444
444
  finally {
445
445
  callbacksOpen = false;
446
+ if (agent !== undefined && run !== undefined) {
447
+ try {
448
+ const usage = run.usage;
449
+ await options.writer.record("usage-snapshot", {
450
+ source: "run.usage", resourceSemantics: "cumulative", phase: "finalization",
451
+ status: usage === undefined ? "unavailable" : "available",
452
+ ...(usage === undefined ? {} : { usage: snapshotJson(usage) }),
453
+ }, ids(agent, run));
454
+ }
455
+ catch (error) {
456
+ captureError ??= `usage-snapshot: ${errorMessage(error)}`;
457
+ options.errors.push(`usage-snapshot: ${errorMessage(error)}`);
458
+ await options.writer.record("error", { stage: "usage-snapshot", message: errorMessage(error) }, ids(agent, run)).catch(() => undefined);
459
+ }
460
+ }
446
461
  if (agent !== undefined) {
447
462
  try {
448
463
  await disposeAgent();
@@ -1015,6 +1030,8 @@ function unmappedCursorReason(record) {
1015
1030
  return "Durable native history remains authoritative evidence and is not counted as a second operation/message source.";
1016
1031
  if (type === "billing")
1017
1032
  return "Eventually consistent billing readback remains separate from per-turn token observations.";
1033
+ if (type === "usage-snapshot")
1034
+ return "Cumulative run.usage at finalization is retained separately, not added to per-turn token observations.";
1018
1035
  if (type === "stream:thinking")
1019
1036
  return "Hidden reasoning remains restricted native evidence and is never projected as semantic content.";
1020
1037
  return "Cursor native record is retained explicitly without a supported semantic mapping.";
@@ -123,11 +123,18 @@ cannot produce qualified-complete capture.
123
123
  | `run.stream()` | lifecycle, messages, tools, per-turn usage | authoritative message/tool/usage projection |
124
124
  | `onDelta` / `onStep` | lower-level deltas, nested updates, step snapshots | retained as overlap evidence; not counted again |
125
125
  | `run.wait()` | owned terminal status, duration, cumulative usage | authoritative outcome; cumulative usage is not re-added |
126
+ | `run.usage` | cumulative finalization snapshot, including failed/interrupted runs | retained separately; not added to per-turn totals |
126
127
  | `run.conversation()` | durable conversation readback before disposal | retained as history; not counted again |
127
128
  | `agent.getUsage()` | eventually consistent billing scope/read time | separate billing evidence; absence does not invalidate semantic capture |
128
129
  | `JsonlLocalAgentStore` | agents, runs, run events, checkpoints | authoritative native persistence; not counted again |
129
130
 
130
131
  Every callback value is JSON-snapshotted at receipt and writes are serialized.
132
+ Finalization reads `run.usage` without waiting for a successful terminal result
133
+ or making another provider request. The `usage-snapshot` record identifies its
134
+ source, cumulative semantics, and availability. An unavailable value is not
135
+ zero. A getter or recorder failure is recorded as a capture gap without
136
+ replacing the original terminal error or skipping cleanup. Abrupt process
137
+ termination cannot guarantee a final snapshot.
131
138
  Unknown tool payloads remain in restricted native evidence. Portable export
132
139
  recursively removes thinking/reasoning content and checkpoint blob bytes, then
133
140
  redacts secrets, local identifiers, paths, and source correlations. Restricted
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "engineering-behavior-observatory",
3
- "version": "0.2.7",
3
+ "version": "0.2.8",
4
4
  "description": "Capture engineering-agent trajectories, evaluate behavior, and inspect cited evidence across harnesses.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -51,6 +51,7 @@
51
51
  "release/0.2.5/",
52
52
  "release/0.2.6/",
53
53
  "release/0.2.7/",
54
+ "release/0.2.8/",
54
55
  "schemas/",
55
56
  "scripts/atlas-grafana.sh"
56
57
  ],
@@ -0,0 +1,12 @@
1
+ # v0.2.8 known limitations
2
+
3
+ The [v0.2.7 limitations](../0.2.7/KNOWN_LIMITATIONS.md) continue to apply.
4
+
5
+ - A snapshot cannot supply usage that the runtime did not report. Unavailable
6
+ counters remain unavailable, not zero.
7
+ - The snapshot remains native cumulative evidence; it is not added to
8
+ normalized per-turn totals or used to infer missing token categories.
9
+ - Abrupt process termination can prevent finalization. A thrown getter or
10
+ failed recorder is reported as a capture gap while cleanup continues.
11
+ - No live trial was run for this patch. Existing Cursor SDK dependency audit
12
+ findings are unchanged.
@@ -0,0 +1,13 @@
1
+ # v0.2.8: Preserve Cursor usage on failure
2
+
3
+ Finalization snapshots `run.usage` even when the terminal wait throws or is
4
+ interrupted. The retained `usage-snapshot` records cumulative counters and
5
+ availability separately from per-turn usage and billing. It does not overwrite
6
+ terminal errors, add token totals twice, or make another provider call.
7
+
8
+ Tests cover success, terminal error, thrown wait, interruption, unavailable
9
+ usage, and getter failure with cleanup preserved.
10
+
11
+ See the [Cursor guide](../../docs/harnesses/cursor-sdk.md),
12
+ [known limitations](KNOWN_LIMITATIONS.md), and
13
+ [reproducibility manifest](reproducibility.json).
@@ -0,0 +1,74 @@
1
+ {
2
+ "schemaVersion": "ebo.release-reproducibility/v1",
3
+ "release": {
4
+ "name": "engineering-behavior-observatory",
5
+ "version": "0.2.8"
6
+ },
7
+ "runtime": {
8
+ "node": "24.19.0",
9
+ "claudeAgentSdk": "0.3.258",
10
+ "openhandsAgentServer": "1.46.0",
11
+ "deepseekClient": "0.1.1-rc.2",
12
+ "deepseekProtocol": "0.1.1-rc.2",
13
+ "deepseekRuntime": "0.1.1-rc.2",
14
+ "codexAppServer": "0.153.4",
15
+ "grafana": "13.2.0",
16
+ "grafanaInfinity": "4.0.0",
17
+ "piSdk": "0.85.1",
18
+ "cursorSdk": "1.0.31"
19
+ },
20
+ "commands": [
21
+ "npm ci",
22
+ "npm run acceptance"
23
+ ],
24
+ "fixtureCoverage": {
25
+ "agent-sdk": "frozen queue entry through qualified capture, approved export, normalization, configurable judging, review, aggregation, and Atlas",
26
+ "openhands-agent-server": "pinned REST/WebSocket stream-final reconciliation, workspace/outcome evidence, partial capture, and retained evaluation",
27
+ "deepseek-harness": "official-client JSON-RPC composition, receipt-to-idle completion, stderr, interruption, shutdown, swaps, and retained evaluation",
28
+ "codex-app-server": "owned stdio lifecycle, full history, OTLP, interruption/failure, export, and retained evaluation; configurable workspace-write networking with explicit offline queue propagation",
29
+ "acceptance-cases": "seeded ordering, secret scanning, partial attempts, native references, abstention, disputes, denominators, and unsupported comparisons",
30
+ "pi-sdk": "frozen queue, passive hooks, durable session, partial cleanup, export, retained normalization and evaluation",
31
+ "cursor-sdk": "frozen queue, official store, callbacks/history, bounded cancellation, export, retained normalization and evaluation; HTTP/1.1 configuration ordering, native retry validation, terminal transport error retention without replacement; cumulative usage finalization on success, failure, interruption, unavailable counters and getter failure",
32
+ "workspace-capture": "Contained absolute links relocated in derived captures; workspace packaging gaps preserve native completion and allow semantic analysis independently"
33
+ },
34
+ "determinism": {
35
+ "stable": [
36
+ "task, run, attempt, event, assertion, aggregate, and Atlas case identities",
37
+ "fixture, native-reference, normalized-dataset, source/cohort, archive, and package digests",
38
+ "seeded queue and review-sample ordering"
39
+ ],
40
+ "excluded": [
41
+ "native and EBO observation timestamps",
42
+ "lifecycle start/finish timestamps",
43
+ "provider timing and usage",
44
+ "temporary workspace and output paths"
45
+ ]
46
+ },
47
+ "fixtures": {
48
+ "tests/fixtures/task-packet.valid.v1.json": "ac2ef1043c0cc16bf4c21d05c1dc880ca1b4b8cc2f9ea7653328e91f0b0e2681",
49
+ "test/fixtures/agent-sdk-normalizer/complete.input.json": "7285dee088517e5de38ceda84fc7c58d9303949c7448ab3b5e10a5a2d2ebdfe3",
50
+ "test/fixtures/agent-sdk-normalizer/complete.expected.jsonl": "d32fa3a013bc179f1673f7e1a89b8a721bb8ddaf63eba5bc8a3f14f1cc148ed8",
51
+ "contracts/openhands-agent-server-v1.44.1.json": "e7a07977688a0703b15751a8a1ab17f29be45f9fdf438017e0dbcbc49cca37b0",
52
+ "contracts/openhands-agent-server-v1.46.0.json": "455cdddd2c206cb2f20245c2189b92e773657ec14d651236baa532b2dbadeb28",
53
+ "test/fixtures/openhands/v1.44.1/streamed-events.json": "d751083ba2ef94c9865117db481cc2f4933772bbbbb6b9fcf60571563715c1ea",
54
+ "test/fixtures/openhands/v1.44.1/final-events.json": "551db9904e860004d604c923692b5c5d3aaee966220492214c60003d2df415b6",
55
+ "test/fixtures/deepseek/golden-success.json": "f3867d38169bf0e28f64aba1dd60553f21cf07f41f81b4bad48261e49fa3ca88",
56
+ "test/fixtures/deepseek/golden-interrupted.json": "79e1f8404df1ee3b562d0bdbc0b2ee712ffc6d5774992b92970814ea815677b7",
57
+ "test/fixtures/deepseek/compositions/minimal/composition.json": "72fe4368e105f1bad82b7fdf8380e92c9fa689d8985f6ab91f534f0baf3eda02",
58
+ "contracts/codex-app-server-0.153.4/manifest.json": "e62281ff5e5d1cc71d07763b85e997ccc9ddbad9aa82a469da4181ee4b1890a8",
59
+ "test/fixtures/codex/legacy-0.150.1.dataset.json": "f71906b009e546afbf3b4e79396f223181382f3b3d8795e9cfcd032398a9d6bf",
60
+ "test/fixtures/behavior-assertions/abstained.json": "7f1962864f664c794925a67d93074e7b150af0f57c58041a81e062990d641197",
61
+ "test/fixtures/behavior-assertions/disputed.review.json": "450d3d9efe7feefaf7500b3ad20ab2803b412c7e53b91763125e15a83be87981",
62
+ "test/fixtures/comparison/exact.json": "cafa68e94b8d50dc308ddcfc2e73aa139c828b4ecd1e1c762bbc51bf1b44501e",
63
+ "test/fixtures/structural-observations/golden.json": "bad71a3a93524b76c0a2fdbb58e98e1e65be46cae14acf18ac89d9ba76e03e8a",
64
+ "test/atlas-fixture.ts": "9f03ce9cbcd0e5d3e3a5916866554ceb1c21f1c8712e58529499c1ea499f048d",
65
+ "test/pi.test.ts": "a00997c5617ca178e19b25b0d483cbdce8ce7c306d4c871557945b31a2e657cf",
66
+ "test/cursor-sdk.test.ts": "5b4537b31a7b001b2498b3a00c8cbc89e2a4cea3c8758e80be3541f0de6e2226",
67
+ "examples/cursor-sdk/README.md": "a2cf481123e7f3deb1c5a682ba208a775c3f91c35e1a6c1a428c517c79692618",
68
+ "examples/cursor-sdk/capture-profile.json": "d1a5787875daf5523b3783f259b891c256a904cbb10279d5be214af846305a2d",
69
+ "examples/cursor-sdk/harness.json": "2f1da6f2b17258d0ee59431f687696901ce3692589175d182f3a4bbe8dd4d689",
70
+ "examples/cursor-sdk/model.json": "ad8f31ff5d2387c02d79226679022358afafc61ba5dda73040e3f754530a230a",
71
+ "examples/cursor-sdk/native-limits.json": "40fe451f56b0863e79b42f5c85defbce678e1dc90dd248d15c430db176d71511",
72
+ "examples/cursor-sdk/native-tool-policy.json": "8148b9ad57134d217a03e47cc11bcc85758e1115b64bb06b85564139aecd1cd9"
73
+ }
74
+ }
package/release/README.md CHANGED
@@ -5,6 +5,7 @@ For downloads and published artifacts, see
5
5
 
6
6
  | Version | Changes and verification | Support boundary |
7
7
  | :--- | :--- | :--- |
8
+ | [0.2.8](0.2.8/README.md) | Retain Cursor cumulative usage during failure and interruption | [Known limitations](0.2.8/KNOWN_LIMITATIONS.md) |
8
9
  | [0.2.7](0.2.7/README.md) | Cursor native transport/stall recovery and recorded HTTP/1.1 settings | [Known limitations](0.2.7/KNOWN_LIMITATIONS.md) |
9
10
  | [0.2.6](0.2.6/README.md) | Portable contained absolute links; isolate workspace packaging failures from native completion and semantic analysis | [Known limitations](0.2.6/KNOWN_LIMITATIONS.md) |
10
11
  | [0.2.5](0.2.5/README.md) | Preserve contained workspace symlinks and macOS AppleDouble files | [Known limitations](0.2.5/KNOWN_LIMITATIONS.md) |