engineering-behavior-observatory 0.2.6 → 0.2.7

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.
@@ -70,7 +70,7 @@ export async function runCursorSdkQueueEntry(options) {
70
70
  sandbox: { enabled: toolPolicy.sandbox.enabled },
71
71
  settingSources: [],
72
72
  autoReview: false,
73
- enableAgentRetries: false,
73
+ enableAgentRetries: toolPolicy.enableAgentRetries,
74
74
  },
75
75
  maxNativeRecordBytes: limits.maxNativeRecordBytes,
76
76
  };
@@ -215,8 +215,8 @@ function validateConfigurationRecord(record, kind, reference) {
215
215
  if (!Array.isArray(record.settingSources) || record.settingSources.length !== 0) {
216
216
  throw configurationError(reference, "settingSources must be [] so unrelated user/candidate settings are not loaded");
217
217
  }
218
- if (record.autoReview !== false || record.enableAgentRetries !== false) {
219
- throw configurationError(reference, "autoReview and enableAgentRetries must both be false for an observational attempt");
218
+ if (record.autoReview !== false || record.enableAgentRetries !== true) {
219
+ throw configurationError(reference, "autoReview must be false and enableAgentRetries must be true for native recovery");
220
220
  }
221
221
  return;
222
222
  case "capture-profile":
@@ -18,7 +18,7 @@ export type CursorSdkToolPolicy = {
18
18
  };
19
19
  settingSources: readonly [];
20
20
  autoReview: false;
21
- enableAgentRetries: false;
21
+ enableAgentRetries: true;
22
22
  };
23
23
  export type CursorSdkCaptureConfiguration = {
24
24
  model: ModelSelection;
@@ -2,7 +2,7 @@ import { createHash } from "node:crypto";
2
2
  import { existsSync } from "node:fs";
3
3
  import { lstat, mkdir, open, stat } from "node:fs/promises";
4
4
  import { dirname, join, parse, resolve } from "node:path";
5
- import { Agent, JSONL_LOCAL_AGENT_STORE_FILES, JsonlLocalAgentStore, } from "@cursor/sdk";
5
+ import { Agent, Cursor, JSONL_LOCAL_AGENT_STORE_FILES, JsonlLocalAgentStore, } from "@cursor/sdk";
6
6
  import { assertNoDuplicateJsonKeys, digestMetadata } from "./artifacts.js";
7
7
  import { createAttemptIdentity, createRunIdentity, executeRunAttempt, } from "./lifecycle.js";
8
8
  import { createCapturedNativeEvidenceResolver, describeNormalizedDataset, validateNormalizedDataset, } from "./normalization-integrity.js";
@@ -56,6 +56,9 @@ export const CURSOR_SDK_CAPABILITIES = {
56
56
  export async function captureCursorSdkRun(options) {
57
57
  requireText(options.apiKey, "Cursor API key");
58
58
  requireText(options.prompt, "Cursor prompt");
59
+ if (options.configuration.toolPolicy.enableAgentRetries !== true) {
60
+ throw new Error("Cursor capture requires enableAgentRetries: true for native recovery.");
61
+ }
59
62
  if (options.definition.run.model.id !== options.configuration.model.id) {
60
63
  throw new Error("The declared model must match the Cursor SDK model configuration.");
61
64
  }
@@ -283,11 +286,13 @@ async function executeCursorSdk(options) {
283
286
  });
284
287
  try {
285
288
  await assertCursorWorkspaceIsolation(options.workspacePath);
289
+ Cursor.configure({ local: { useHttp1ForAgent: true } });
286
290
  await options.writer.record("configuration", {
287
291
  sdkVersion: CURSOR_SDK_VERSION,
288
292
  runtimeIdentity: { status: "not-exposed", detail: "The public SDK does not expose a separately versioned local agent runtime." },
289
293
  model: options.configuration.model,
290
294
  toolPolicy: options.configuration.toolPolicy,
295
+ transport: { useHttp1ForAgent: true },
291
296
  workingDirectory: options.workspacePath,
292
297
  workingDirectoryPolicy: "isolated-local.cwd",
293
298
  environmentKeys: environment.keys,
@@ -306,7 +311,7 @@ async function executeCursorSdk(options) {
306
311
  settingSources: [],
307
312
  sandboxOptions: { enabled: options.configuration.toolPolicy.sandbox.enabled },
308
313
  autoReview: false,
309
- enableAgentRetries: false,
314
+ enableAgentRetries: options.configuration.toolPolicy.enableAgentRetries,
310
315
  },
311
316
  });
312
317
  agent = await abortable(agentPromise, options.signal, "Cursor agent creation", async (lateAgent) => {
@@ -38,7 +38,21 @@ the following digest-pinned settings for every Cursor queue entry:
38
38
  MDM, or plugin settings are not silently loaded;
39
39
  - `autoReview: false`, so instrumentation does not add a behavior-changing
40
40
  classifier; and
41
- - `enableAgentRetries: false`, so a retained attempt is not silently replaced.
41
+ - `enableAgentRetries: true`, enabling Cursor's native transport/stall recovery
42
+ within the owned run. EBO does not add a retry loop or replacement attempt.
43
+
44
+ Before agent creation, EBO calls
45
+ `Cursor.configure({ local: { useHttp1ForAgent: true } })` to select HTTP/1.1
46
+ for local backend streams. This mitigates the observed `NGHTTP2_INTERNAL_ERROR`;
47
+ it is not a proven root-cause fix. Both settings use the
48
+ [public SDK API](https://cursor.com/docs/sdk/typescript).
49
+ The native `configuration` record retains `transport.useHttp1ForAgent` and
50
+ `toolPolicy.enableAgentRetries`. Terminal errors and partial evidence remain
51
+ retained if native recovery fails; the attempt deadline still applies.
52
+
53
+ Existing frozen policies with retries disabled are rejected at launch, not
54
+ silently overridden. Prepare new configuration records and a new queue for
55
+ future runs; preserve earlier frozen experiments and captures unchanged.
42
56
 
43
57
  SDK `1.0.31` treats an ancestor Git checkout as the local project root. EBO
44
58
  therefore rejects a materialized workspace nested under another `.git` path
@@ -79,7 +93,7 @@ provider ID containing dots.
79
93
  ```
80
94
 
81
95
  ```json
82
- { "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 }
96
+ { "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": true }
83
97
  ```
84
98
 
85
99
  ```json
@@ -1 +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}
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":true}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "engineering-behavior-observatory",
3
- "version": "0.2.6",
3
+ "version": "0.2.7",
4
4
  "description": "Capture engineering-agent trajectories, evaluate behavior, and inspect cited evidence across harnesses.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -50,6 +50,7 @@
50
50
  "release/0.2.4/",
51
51
  "release/0.2.5/",
52
52
  "release/0.2.6/",
53
+ "release/0.2.7/",
53
54
  "schemas/",
54
55
  "scripts/atlas-grafana.sh"
55
56
  ],
@@ -0,0 +1,8 @@
1
+ # v0.2.7 known limitations
2
+
3
+ The [v0.2.6 limitations](../0.2.6/KNOWN_LIMITATIONS.md) continue to apply.
4
+
5
+ - HTTP/1.1 mitigates the observed HTTP/2 failure; it is not a proven root-cause fix.
6
+ - Native recovery can still fail or reach the attempt deadline.
7
+ - Deterministic tests verify configuration and evidence handling, not live
8
+ provider recovery. No new full trial was run for this patch.
@@ -0,0 +1,17 @@
1
+ # v0.2.7: Cursor native recovery
2
+
3
+ Cursor capture configures HTTP/1.1 before agent creation and enables the SDK's
4
+ native transport/stall retries. The configuration evidence records both settings.
5
+ EBO does not launch replacement attempts or add its own retry loop. Terminal
6
+ errors and partial evidence remain available when native recovery fails.
7
+
8
+ New queue policies must explicitly set `enableAgentRetries: true`. Earlier
9
+ frozen policies are rejected at launch rather than silently overridden; prior
10
+ experiments and retained captures remain unchanged.
11
+
12
+ Regression tests cover configuration ordering, effective evidence, policy
13
+ validation, and terminal-error retention with exactly one agent creation.
14
+
15
+ See the [Cursor guide](../../docs/harnesses/cursor-sdk.md),
16
+ [known limitations](KNOWN_LIMITATIONS.md), and
17
+ [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.7"
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",
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": "ceb8aeb719b9554d51bb3cfe78fd0bc796acdce8ddc5ef205a327fac4226f57e",
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.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) |
8
9
  | [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) |
9
10
  | [0.2.5](0.2.5/README.md) | Preserve contained workspace symlinks and macOS AppleDouble files | [Known limitations](0.2.5/KNOWN_LIMITATIONS.md) |
10
11
  | [0.2.4](0.2.4/README.md) | Stream workspace snapshots and integrity checks; support archives up to 1 GiB | [Known limitations](0.2.4/KNOWN_LIMITATIONS.md) |