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.
- package/LICENSE +202 -0
- package/README.md +151 -0
- package/contracts/codex-app-server-0.150.1/manifest.json +25 -0
- package/contracts/codex-app-server-0.150.1/schema/InitializeParams.json +84 -0
- package/contracts/codex-app-server-0.150.1/schema/JSONRPCMessage.json +137 -0
- package/contracts/codex-app-server-0.150.1/schema/v2/ThreadReadParams.json +17 -0
- package/contracts/codex-app-server-0.150.1/schema/v2/ThreadTokenUsageUpdatedNotification.json +82 -0
- package/contracts/codex-app-server-0.150.1/schema/v2/TurnInterruptParams.json +17 -0
- package/contracts/codex-app-server-0.150.1/types/AskForApproval.ts +5 -0
- package/contracts/codex-app-server-0.150.1/types/ClientNotification.ts +5 -0
- package/contracts/codex-app-server-0.150.1/types/SandboxMode.ts +5 -0
- package/contracts/codex-app-server-0.150.1/types/ThreadReadParams.ts +9 -0
- package/contracts/codex-app-server-0.150.1/types/TokenUsageBreakdown.ts +5 -0
- package/contracts/codex-app-server-0.150.1/types/TurnInterruptParams.ts +5 -0
- package/contracts/codex-app-server-0.153.4/manifest.json +27 -0
- package/contracts/codex-app-server-0.153.4/schema/JSONRPCMessage.json +137 -0
- package/contracts/codex-app-server-0.153.4/schema/v1/InitializeParams.json +84 -0
- package/contracts/codex-app-server-0.153.4/schema/v2/ThreadReadParams.json +17 -0
- package/contracts/codex-app-server-0.153.4/schema/v2/ThreadStartParams.json +515 -0
- package/contracts/codex-app-server-0.153.4/schema/v2/ThreadTokenUsageUpdatedNotification.json +82 -0
- package/contracts/codex-app-server-0.153.4/schema/v2/TurnInterruptParams.json +17 -0
- package/contracts/codex-app-server-0.153.4/schema/v2/TurnStartParams.json +921 -0
- package/contracts/codex-app-server-0.153.4/types/AskForApproval.ts +5 -0
- package/contracts/codex-app-server-0.153.4/types/ClientNotification.ts +5 -0
- package/contracts/codex-app-server-0.153.4/types/SandboxMode.ts +5 -0
- package/contracts/codex-app-server-0.153.4/types/ThreadReadParams.ts +12 -0
- package/contracts/codex-app-server-0.153.4/types/TokenUsageBreakdown.ts +5 -0
- package/contracts/codex-app-server-0.153.4/types/TurnInterruptParams.ts +5 -0
- package/contracts/openhands-agent-server-v1.44.1.json +65 -0
- package/contracts/openhands-agent-server-v1.46.0.json +46 -0
- package/dist/contracts/codex-app-server-0.153.4/types/AskForApproval.d.ts +9 -0
- package/dist/contracts/codex-app-server-0.153.4/types/AskForApproval.js +2 -0
- package/dist/contracts/codex-app-server-0.153.4/types/ClientNotification.d.ts +3 -0
- package/dist/contracts/codex-app-server-0.153.4/types/ClientNotification.js +2 -0
- package/dist/contracts/codex-app-server-0.153.4/types/SandboxMode.d.ts +1 -0
- package/dist/contracts/codex-app-server-0.153.4/types/SandboxMode.js +2 -0
- package/dist/contracts/codex-app-server-0.153.4/types/ThreadReadParams.d.ts +10 -0
- package/dist/contracts/codex-app-server-0.153.4/types/ThreadReadParams.js +2 -0
- package/dist/contracts/codex-app-server-0.153.4/types/TokenUsageBreakdown.d.ts +8 -0
- package/dist/contracts/codex-app-server-0.153.4/types/TokenUsageBreakdown.js +2 -0
- package/dist/contracts/codex-app-server-0.153.4/types/TurnInterruptParams.d.ts +4 -0
- package/dist/contracts/codex-app-server-0.153.4/types/TurnInterruptParams.js +2 -0
- package/dist/src/agent-sdk-normalizer.d.ts +22 -0
- package/dist/src/agent-sdk-normalizer.js +995 -0
- package/dist/src/agent-sdk-run.d.ts +31 -0
- package/dist/src/agent-sdk-run.js +242 -0
- package/dist/src/agent-sdk-runner.d.ts +96 -0
- package/dist/src/agent-sdk-runner.js +407 -0
- package/dist/src/agent-sdk.d.ts +294 -0
- package/dist/src/agent-sdk.js +644 -0
- package/dist/src/aggregation.d.ts +183 -0
- package/dist/src/aggregation.js +513 -0
- package/dist/src/artifacts.d.ts +36 -0
- package/dist/src/artifacts.js +1372 -0
- package/dist/src/atlas-grafana.d.ts +377 -0
- package/dist/src/atlas-grafana.js +47 -0
- package/dist/src/atlas-html.d.ts +2 -0
- package/dist/src/atlas-html.js +34 -0
- package/dist/src/atlas.d.ts +130 -0
- package/dist/src/atlas.js +235 -0
- package/dist/src/behavior-assertions.d.ts +95 -0
- package/dist/src/behavior-assertions.js +154 -0
- package/dist/src/cli.d.ts +5 -0
- package/dist/src/cli.js +957 -0
- package/dist/src/codex-judge.d.ts +44 -0
- package/dist/src/codex-judge.js +214 -0
- package/dist/src/codex-run.d.ts +114 -0
- package/dist/src/codex-run.js +519 -0
- package/dist/src/codex.d.ts +187 -0
- package/dist/src/codex.js +1028 -0
- package/dist/src/contracts.d.ts +155 -0
- package/dist/src/contracts.js +866 -0
- package/dist/src/corpus.d.ts +67 -0
- package/dist/src/corpus.js +540 -0
- package/dist/src/cursor-sdk-runner.d.ts +81 -0
- package/dist/src/cursor-sdk-runner.js +362 -0
- package/dist/src/cursor-sdk.d.ts +81 -0
- package/dist/src/cursor-sdk.js +1078 -0
- package/dist/src/deepseek-adapter.d.ts +152 -0
- package/dist/src/deepseek-adapter.js +777 -0
- package/dist/src/exports.d.ts +69 -0
- package/dist/src/exports.js +966 -0
- package/dist/src/human-calibration.d.ts +167 -0
- package/dist/src/human-calibration.js +618 -0
- package/dist/src/index.d.ts +71 -0
- package/dist/src/index.js +38 -0
- package/dist/src/lifecycle.d.ts +196 -0
- package/dist/src/lifecycle.js +1889 -0
- package/dist/src/normalization-integrity.d.ts +128 -0
- package/dist/src/normalization-integrity.js +429 -0
- package/dist/src/openhands-run.d.ts +36 -0
- package/dist/src/openhands-run.js +415 -0
- package/dist/src/openhands.d.ts +130 -0
- package/dist/src/openhands.js +859 -0
- package/dist/src/pi.d.ts +203 -0
- package/dist/src/pi.js +1345 -0
- package/dist/src/process-protocol.d.ts +245 -0
- package/dist/src/process-protocol.js +1261 -0
- package/dist/src/retained-evidence.d.ts +12 -0
- package/dist/src/retained-evidence.js +201 -0
- package/dist/src/run-bundles.d.ts +193 -0
- package/dist/src/run-bundles.js +993 -0
- package/dist/src/scheduler.d.ts +109 -0
- package/dist/src/scheduler.js +1080 -0
- package/dist/src/semantic-judge.d.ts +194 -0
- package/dist/src/semantic-judge.js +875 -0
- package/dist/src/structural-observations.d.ts +124 -0
- package/dist/src/structural-observations.js +671 -0
- package/dist/src/task-packets.d.ts +115 -0
- package/dist/src/task-packets.js +683 -0
- package/dist/src/uniform-events.d.ts +120 -0
- package/dist/src/uniform-events.js +158 -0
- package/dist/src/verifiers.d.ts +116 -0
- package/dist/src/verifiers.js +819 -0
- package/dist/src/workspaces.d.ts +56 -0
- package/dist/src/workspaces.js +1314 -0
- package/docs/README.md +60 -0
- package/docs/development/README.md +71 -0
- package/docs/development/documentation-sync.md +58 -0
- package/docs/development/extension-contracts.md +307 -0
- package/docs/evaluation/README.md +48 -0
- package/docs/evaluation/aggregation.md +112 -0
- package/docs/evaluation/behavior-assertions.md +45 -0
- package/docs/evaluation/human-calibration.md +170 -0
- package/docs/evaluation/normalization-integrity.md +80 -0
- package/docs/evaluation/semantic-judge.md +188 -0
- package/docs/evaluation/structural-observations.md +84 -0
- package/docs/evaluation/uniform-events.md +131 -0
- package/docs/guides/atlas.md +144 -0
- package/docs/guides/evidence-and-sharing.md +100 -0
- package/docs/guides/operator-guide.md +424 -0
- package/docs/guides/quickstart.md +152 -0
- package/docs/guides/telemetry.md +66 -0
- package/docs/harnesses/README.md +31 -0
- package/docs/harnesses/claude-agent-sdk.md +61 -0
- package/docs/harnesses/codex-harness.md +174 -0
- package/docs/harnesses/cursor-sdk.md +149 -0
- package/docs/harnesses/deepseek-harness.md +134 -0
- package/docs/harnesses/openhands-agent-server.md +153 -0
- package/docs/harnesses/pi-sdk.md +66 -0
- package/docs/reference/README.md +19 -0
- package/docs/reference/agent-sdk-operational-runner.md +118 -0
- package/docs/reference/cli.md +114 -0
- package/docs/reference/contracts.md +222 -0
- package/docs/reference/run-bundle-contract.md +354 -0
- package/docs/reference/run-lifecycle.md +54 -0
- package/examples/cursor-sdk/README.md +11 -0
- package/examples/cursor-sdk/capture-profile.json +1 -0
- package/examples/cursor-sdk/harness.json +1 -0
- package/examples/cursor-sdk/model.json +1 -0
- package/examples/cursor-sdk/native-limits.json +1 -0
- package/examples/cursor-sdk/native-tool-policy.json +1 -0
- package/ontology/behavior-categories.v1.json +46 -0
- package/package.json +66 -0
- package/release/0.1.0/KNOWN_LIMITATIONS.md +35 -0
- package/release/0.1.0/README.md +46 -0
- package/release/0.1.0/reproducibility.json +61 -0
- package/release/0.2.0/KNOWN_LIMITATIONS.md +40 -0
- package/release/0.2.0/README.md +42 -0
- package/release/0.2.0/reproducibility.json +73 -0
- package/release/0.2.1/KNOWN_LIMITATIONS.md +18 -0
- package/release/0.2.1/README.md +63 -0
- package/release/0.2.1/reproducibility.json +73 -0
- package/release/README.md +13 -0
- package/schemas/aggregation.v1.json +293 -0
- package/schemas/behavior-assertions.v1.json +220 -0
- package/schemas/deepseek-runtime-composition.v1.schema.json +122 -0
- package/schemas/experiment.v1.schema.json +188 -0
- package/schemas/human-calibration.v1.json +336 -0
- package/schemas/normalization-integrity.v1.json +302 -0
- package/schemas/run-bundles/v1.json +1040 -0
- package/schemas/run-queue.v1.schema.json +206 -0
- package/schemas/semantic-judge.v1.json +380 -0
- package/schemas/structural-observations.v1.json +131 -0
- package/schemas/task-packet-freeze.v1.schema.json +106 -0
- package/schemas/task-packet.v1.schema.json +234 -0
- package/schemas/uniform-events/v1.json +289 -0
- package/scripts/atlas-grafana.sh +18 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Claude Agent SDK
|
|
2
|
+
|
|
3
|
+
EBO calls the TypeScript Agent SDK directly. It captures the native message
|
|
4
|
+
stream, passive lifecycle hooks, exposed session identities, usage, telemetry
|
|
5
|
+
receipt state, and a retained workspace outcome.
|
|
6
|
+
|
|
7
|
+
## Run one task
|
|
8
|
+
|
|
9
|
+
After [preparing and freezing a queue](../guides/operator-guide.md):
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
ebo agent-sdk run <bundle-root> <queue.json> <run-id> <output-root>
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
The adapter uses `@anthropic-ai/claude-agent-sdk@0.3.258`. It probes the
|
|
16
|
+
installed SDK/CLI and records version-specific capabilities rather than
|
|
17
|
+
assuming every hook is available. Runtime pins are implementation conditions,
|
|
18
|
+
not assurances that a provider model route is accessible.
|
|
19
|
+
|
|
20
|
+
Supply an approved Agent SDK authentication route through the environment.
|
|
21
|
+
The opt-in OAuth proofs use `CLAUDE_CODE_OAUTH_TOKEN` with
|
|
22
|
+
`ANTHROPIC_API_KEY` and `ANTHROPIC_AUTH_TOKEN` unset. Do not put credentials
|
|
23
|
+
in packet or queue JSON. EBO does not establish entitlement to a model.
|
|
24
|
+
|
|
25
|
+
The queue references five records: model, harness, native limits, tool policy,
|
|
26
|
+
and capture profile. See the [configuration reference](../reference/agent-sdk-operational-runner.md)
|
|
27
|
+
for accepted fields and examples. Tool permission settings can prevent a
|
|
28
|
+
headless run from proceeding; review them before committing to a long task.
|
|
29
|
+
|
|
30
|
+
## Read the capture
|
|
31
|
+
|
|
32
|
+
| Evidence | What it establishes |
|
|
33
|
+
| :--- | :--- |
|
|
34
|
+
| Native SDK stream | Messages, tool-related content, result and session identities |
|
|
35
|
+
| Passive hooks | Exposed lifecycle callback occurrences, including failures and compaction |
|
|
36
|
+
| Telemetry | Received timing/resource signals, with gaps recorded independently |
|
|
37
|
+
| Workspace evidence | Retained changes against the frozen starting tree |
|
|
38
|
+
| Capture report | Structural validity, source capabilities, and missing evidence |
|
|
39
|
+
|
|
40
|
+
A hook's occurrence is authoritative in callback evidence; a hook span is
|
|
41
|
+
optional timing data. Hooks do not modify the agent's choices. Native reasoning
|
|
42
|
+
may be present in restricted source data and is removed from portable exports.
|
|
43
|
+
|
|
44
|
+
Tracing is beta; metrics/log events are separate capabilities. Content capture
|
|
45
|
+
is opt-in. Short export intervals **and** clean shutdown reduce buffering loss,
|
|
46
|
+
but collector receipt must still be checked. See [telemetry](../guides/telemetry.md).
|
|
47
|
+
|
|
48
|
+
## Completion and interruption
|
|
49
|
+
|
|
50
|
+
The command executes one queue entry, with a fresh attempt identity and output
|
|
51
|
+
directory. It does not loop through the queue or silently retry. A valid
|
|
52
|
+
captured stop or failure can return a successful CLI exit: inspect the summary
|
|
53
|
+
and manifest to interpret the result.
|
|
54
|
+
|
|
55
|
+
If workspace packaging fails, preserve the summary's
|
|
56
|
+
`retainedWorkspacePath` for recovery. Missing outcome evidence cannot be
|
|
57
|
+
called qualified completion. See [failure recovery](../guides/operator-guide.md#failure-recovery).
|
|
58
|
+
|
|
59
|
+
Library operators can call `runAgentSdkQueueEntry` for queue execution or
|
|
60
|
+
`captureClaudeAgentSdkRun` for an already-resolved attempt. The latter
|
|
61
|
+
requires explicit workspace/lifecycle composition; it is not a task preparer.
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# Codex app-server harness
|
|
2
|
+
|
|
3
|
+
EBO can execute one selected frozen queue entry through an owned
|
|
4
|
+
`codex app-server --listen stdio://` child. The adapter is optional; the Claude
|
|
5
|
+
Agent SDK remains EBO's primary Anthropic capture path. Codex native protocol
|
|
6
|
+
records remain authoritative, OTLP is separately retained timing/resource
|
|
7
|
+
evidence, and uniform events are a digest-checked projection after capture.
|
|
8
|
+
|
|
9
|
+
The baseline is `codex-cli 0.153.4`. EBO rejects a different executable
|
|
10
|
+
version, starts a new child for each attempt, and never connects to the desktop
|
|
11
|
+
daemon or changes `~/.codex/config.toml`.
|
|
12
|
+
|
|
13
|
+
Each child receives a temporary isolated `CODEX_HOME`, a controlled instruction
|
|
14
|
+
file, and no copied user configuration. When the standard local login file is
|
|
15
|
+
available, EBO references it with a temporary symlink so the supported login is
|
|
16
|
+
reused without reading, copying, or retaining credential bytes. The temporary
|
|
17
|
+
home and native Codex history are removed after `thread/read`; EBO retains only
|
|
18
|
+
the captured protocol evidence.
|
|
19
|
+
The child environment is an allowlist of basic process/locale keys with `HOME`
|
|
20
|
+
and `CODEX_HOME` redirected to that temporary directory; caller secrets and
|
|
21
|
+
Node preload settings are not inherited. Retained evidence records the key
|
|
22
|
+
names, never their values.
|
|
23
|
+
|
|
24
|
+
## Generated contract
|
|
25
|
+
|
|
26
|
+
[`contracts/codex-app-server-0.153.4/manifest.json`](../../contracts/codex-app-server-0.153.4/manifest.json)
|
|
27
|
+
pins the generated root digests and the small schema/type subset used by the
|
|
28
|
+
adapter and its fixtures. Regenerate the source contracts with the pinned CLI:
|
|
29
|
+
|
|
30
|
+
```sh
|
|
31
|
+
codex app-server generate-ts --experimental --out /tmp/codex-types
|
|
32
|
+
codex app-server generate-json-schema --experimental --out /tmp/codex-schema
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
The adapter uses the stable initialize/thread/turn lifecycle, plus generated
|
|
36
|
+
leaf contracts for initialized, `thread/read`, `turn/interrupt`, and token usage.
|
|
37
|
+
Unknown notifications are retained unchanged and listed as unmapped.
|
|
38
|
+
|
|
39
|
+
The 0.153.4 refresh preserves the unchanged RPC, approval, sandbox, interruption
|
|
40
|
+
and usage contracts. Initialization moved into the generated `v1` schema
|
|
41
|
+
directory. The retained subset also includes thread/turn start parameters.
|
|
42
|
+
New captures explicitly select legacy history; paginated or summary-only
|
|
43
|
+
readback is retained with a gap instead of being claimed as complete history.
|
|
44
|
+
The pinned runtime treats `writableRoots` as additional to the effective `cwd`
|
|
45
|
+
and removes a redundant cwd entry. EBO verifies that cwd matches the requested
|
|
46
|
+
workspace, rejects additional roots, and requires the requested network and
|
|
47
|
+
temporary-directory restrictions. Initial thread effort and sandbox overrides
|
|
48
|
+
match the explicit turn policy.
|
|
49
|
+
|
|
50
|
+
Existing 0.150.1 bundles remain readable through their original normalization
|
|
51
|
+
profile and dataset identity. The legacy contract snapshot stays checked in;
|
|
52
|
+
a captured synthetic 0.150.1 bundle and its pre-upgrade normalized dataset test
|
|
53
|
+
exact readback. New captures use the 0.153.4 profile. Frozen run configurations
|
|
54
|
+
for the older executable are not rewritten: new execution requires fresh
|
|
55
|
+
configuration references carrying the new runtime version and contract digest.
|
|
56
|
+
|
|
57
|
+
## Queue configuration
|
|
58
|
+
|
|
59
|
+
The queue keeps condition IDs path-safe; the digest-pinned model record carries
|
|
60
|
+
the actual provider model and effort. A minimal observational configuration is:
|
|
61
|
+
|
|
62
|
+
```json
|
|
63
|
+
{ "schemaVersion": "ebo.codex-config/v1", "kind": "model", "provider": "openai", "model": "gpt-5.6-sol", "effort": "high" }
|
|
64
|
+
{ "schemaVersion": "ebo.codex-config/v1", "kind": "harness", "adapter": "codex-app-server", "executable": "/opt/homebrew/bin/codex", "version": "0.153.4", "contractDigest": "sha256:e5f798fd1343c539f01fedea0e8a84a43c080fcca4615c80eb04a5edab4f7d0a" }
|
|
65
|
+
{ "schemaVersion": "ebo.codex-config/v1", "kind": "native-limits", "shutdownGraceMs": 2000 }
|
|
66
|
+
{ "schemaVersion": "ebo.codex-config/v1", "kind": "native-tool-policy", "approvalPolicy": "never", "sandbox": "workspace-write" }
|
|
67
|
+
{ "schemaVersion": "ebo.codex-config/v1", "kind": "capture-profile", "telemetrySignals": ["logs", "traces", "metrics"], "workspaceOutcome": { "excludeDirectoryNames": ["node_modules"] } }
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Each record is referenced by the existing experiment/queue contract. After task
|
|
71
|
+
admission, freeze, and matrix compilation, execute exactly one entry:
|
|
72
|
+
|
|
73
|
+
```sh
|
|
74
|
+
ebo codex run \
|
|
75
|
+
<bundle-root> <queue.json> <run-id> <output-root> \
|
|
76
|
+
--workspace-root <disposable-workspace-parent>
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
`runCodexQueueEntry` is the equivalent library API. It does not iterate, retry,
|
|
80
|
+
resume, or overwrite an existing attempt destination.
|
|
81
|
+
|
|
82
|
+
## Lifecycle and evidence
|
|
83
|
+
|
|
84
|
+
The client sends `initialize`, `initialized`, `thread/start`, and `turn/start`.
|
|
85
|
+
Only `turn/completed` for the returned thread and turn ends the native attempt.
|
|
86
|
+
After completion or interruption, `thread/read` with `includeTurns: true`
|
|
87
|
+
retains persisted history separately from streamed item records. A request
|
|
88
|
+
is considered full readback only when the thread reports `historyMode: legacy`
|
|
89
|
+
and the owned turn reports `itemsView: full` with an items array. A request
|
|
90
|
+
acknowledgement, final-looking message, idle state, or process exit is not
|
|
91
|
+
completion.
|
|
92
|
+
|
|
93
|
+
An approved synthetic smoke uses an already authenticated route:
|
|
94
|
+
|
|
95
|
+
```sh
|
|
96
|
+
EBO_LIVE_CODEX_CAPTURE_SMOKE=1 EBO_LIVE_CODEX_CAPTURE_MODEL='<existing-route>' \
|
|
97
|
+
node --test --test-name-pattern='approved existing-auth' dist/test/codex.test.js
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
The 0.153.4 validation created the exact synthetic file, retained full legacy
|
|
101
|
+
history, and reported no capture gaps. Logs and traces arrived; metrics did not
|
|
102
|
+
arrive within the bounded run and remained `missing`, not a fabricated receipt.
|
|
103
|
+
|
|
104
|
+
On interruption EBO sends `turn/interrupt`, records its acknowledgement, waits
|
|
105
|
+
briefly for matching terminal evidence, then tears down the owned child. There
|
|
106
|
+
is no invented shutdown RPC. Requests, responses, server requests,
|
|
107
|
+
notifications, unknown variants, completion evidence, stderr diagnostics, and
|
|
108
|
+
process state append to `session.jsonl` with one receive/write sequence.
|
|
109
|
+
Malformed frames, early exit, auth failure, and bounded teardown remain valid
|
|
110
|
+
partial evidence. Workspace outcome capture runs independently and leaves the
|
|
111
|
+
source workspace available when post-start packaging fails.
|
|
112
|
+
|
|
113
|
+
The `ebo codex run` command turns scoped `SIGINT` and `SIGTERM` handlers into
|
|
114
|
+
the run's abort signal, allowing interruption, history readback, process
|
|
115
|
+
teardown, and partial-bundle finalization to complete before the CLI exits.
|
|
116
|
+
Library callers receive the same two-second default shutdown grace at both the
|
|
117
|
+
lifecycle and app-server boundaries unless they provide an explicit value.
|
|
118
|
+
|
|
119
|
+
Unattended runs never fabricate human input or broaden permissions. Command and
|
|
120
|
+
file approvals receive `decline`; MCP elicitation receives `decline`; dynamic
|
|
121
|
+
tool calls fail without content; other unsupported server requests receive a
|
|
122
|
+
recorded JSON-RPC error. Effective model/provider/effort, sandbox, approval
|
|
123
|
+
policy, workspace, runtime identity, instruction sources, and material config
|
|
124
|
+
remain in restricted evidence.
|
|
125
|
+
|
|
126
|
+
## Native telemetry and usage
|
|
127
|
+
|
|
128
|
+
When requested, EBO starts a bounded loopback OTLP/HTTP JSON receiver and passes
|
|
129
|
+
the documented `otel.exporter`, `otel.trace_exporter`, and
|
|
130
|
+
`otel.metrics_exporter` overrides to the owned child. `otel.log_user_prompt` is
|
|
131
|
+
always false. Each signal is classified independently as `received`, `missing`,
|
|
132
|
+
or `disabled`; configured export is never treated as receipt. Exported batches
|
|
133
|
+
are retained without synthetic spans or time-based joins.
|
|
134
|
+
The receiver accepts at most 256 records, 4 MiB per request, and 16 MiB total;
|
|
135
|
+
rejected requests remain explicit receiver diagnostics.
|
|
136
|
+
|
|
137
|
+
`thread/tokenUsage/updated` retains cumulative `total` and per-turn `last`
|
|
138
|
+
values separately, including `totalTokens`, `inputTokens`,
|
|
139
|
+
`cachedInputTokens`, `cacheWriteInputTokens`, `outputTokens`, and
|
|
140
|
+
`reasoningOutputTokens` when emitted. EBO does not sum cumulative updates or
|
|
141
|
+
turn cache/reasoning subsets into additional cost. Account quota and billing
|
|
142
|
+
remain unavailable unless supplied by separate evidence.
|
|
143
|
+
|
|
144
|
+
Restricted native session evidence retains Codex reasoning records unchanged.
|
|
145
|
+
Partner and public derivatives remove `item/reasoning/textDelta` content,
|
|
146
|
+
reasoning-item summary/content fields, and matching duplicated raw frames;
|
|
147
|
+
portable readback fails closed if any of those content forms remain.
|
|
148
|
+
|
|
149
|
+
## Uniform mapping
|
|
150
|
+
|
|
151
|
+
| Native evidence | Uniform family | Rule |
|
|
152
|
+
|---|---|---|
|
|
153
|
+
| completed user/agent message item | `message` | completed item only |
|
|
154
|
+
| completed command/MCP/dynamic/web-search item | `tool` | completed item only; starts and deltas stay native |
|
|
155
|
+
| completed file-change item | `artifact` | content references the native item |
|
|
156
|
+
| completed exposed collaboration item | `delegation` | no inferred child history |
|
|
157
|
+
| turn plan or compaction notification | `context` | only when emitted |
|
|
158
|
+
| token usage, reroute, or completed hook | `runtime` | native values only |
|
|
159
|
+
| approval, permission, user-input, or elicitation request | `permission` | request and decision remain separate native records; other server requests stay unmapped |
|
|
160
|
+
| matching `turn/completed` | `outcome` | terminal status is native |
|
|
161
|
+
|
|
162
|
+
Model requests are deliberately unsupported: EBO does not infer an inference
|
|
163
|
+
request from a turn, reroute, or model switch. Item starts, deltas, history
|
|
164
|
+
readback, raw frames, and unknown methods remain unmapped rather than becoming
|
|
165
|
+
duplicate tool/message counts. `describeAndValidateCodexDataset` runs the
|
|
166
|
+
native-reference, digest, content-reference, capability, and coverage checks.
|
|
167
|
+
|
|
168
|
+
Portable export uses the existing fail-closed sanitizer and readback. Native
|
|
169
|
+
source bundles stay restricted; authentication/account material, local paths,
|
|
170
|
+
environment values, and hidden reasoning are not approved portable fields.
|
|
171
|
+
|
|
172
|
+
Protocol details follow the official [Codex app-server documentation](https://learn.chatgpt.com/docs/app-server).
|
|
173
|
+
Exporter fields follow the official [advanced telemetry guidance](https://learn.chatgpt.com/docs/config-file/config-advanced#observability-and-telemetry)
|
|
174
|
+
and [configuration reference](https://learn.chatgpt.com/docs/config-file/config-reference).
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# Cursor TypeScript SDK harness
|
|
2
|
+
|
|
3
|
+
EBO can execute one selected frozen queue entry through the first-party
|
|
4
|
+
`@cursor/sdk` local-agent API. The integration pins SDK `1.0.31`, creates an
|
|
5
|
+
attempt-owned `JsonlLocalAgentStore`, and retains stream messages, detailed
|
|
6
|
+
callbacks, terminal `wait()` evidence, conversation history, billing readback,
|
|
7
|
+
the official native store, and the final workspace before normalization.
|
|
8
|
+
|
|
9
|
+
The SDK package version does not freeze Cursor's service, selected model, or
|
|
10
|
+
separately deployed local runtime. The selected model must be an exact result
|
|
11
|
+
from `Cursor.models.list()` at launch. SDK `1.0.31` does not expose a separate
|
|
12
|
+
local-runtime version or SDK-local per-run OTLP configuration/receipt surface,
|
|
13
|
+
so EBO records those capabilities as `not-exposed` and `unsupported` instead of
|
|
14
|
+
inventing identities or spans.
|
|
15
|
+
|
|
16
|
+
Cursor also offers a distinct [Enterprise OpenTelemetry Export](https://prod.cursor.com/docs/enterprise/opentelemetry-export)
|
|
17
|
+
configured by a team admin. It runs server-side and pushes OTLP/HTTP protobuf
|
|
18
|
+
metrics and logs to one public HTTPS collector; the [wire reference](https://prod.cursor.com/docs/enterprise/opentelemetry-export/wire)
|
|
19
|
+
includes `sdk_ts` as an entrypoint. This adapter does not configure or receive that
|
|
20
|
+
team export. Its metrics are aggregate deltas without conversation/request IDs,
|
|
21
|
+
and although logs have dedupe IDs plus optional conversation/request/usage-event
|
|
22
|
+
IDs, the public docs do not establish an exact join from those fields to this
|
|
23
|
+
SDK's agent/run IDs. It provides no traces, prompt content, or historical
|
|
24
|
+
backfill. EBO therefore records Enterprise export as `not-checked`, separately
|
|
25
|
+
from the SDK-local `unsupported` result; future ingestion would require an
|
|
26
|
+
approved admin destination and observed identity correlation evidence.
|
|
27
|
+
|
|
28
|
+
## Safety policy
|
|
29
|
+
|
|
30
|
+
Local tool execution is not an OS or container sandbox. EBO requires all of
|
|
31
|
+
the following digest-pinned settings for every Cursor queue entry:
|
|
32
|
+
|
|
33
|
+
- an explicit `sandbox.enabled` boolean; `true` can reject writes that require
|
|
34
|
+
interactive approval in a headless run, while `false` executes with the
|
|
35
|
+
invoking user's OS permissions and is not containment;
|
|
36
|
+
- an explicit built-in tool allowlist and optional deny list;
|
|
37
|
+
- `settingSources: []`, so candidate project files and unrelated user, team,
|
|
38
|
+
MDM, or plugin settings are not silently loaded;
|
|
39
|
+
- `autoReview: false`, so instrumentation does not add a behavior-changing
|
|
40
|
+
classifier; and
|
|
41
|
+
- `enableAgentRetries: false`, so a retained attempt is not silently replaced.
|
|
42
|
+
|
|
43
|
+
SDK `1.0.31` treats an ancestor Git checkout as the local project root. EBO
|
|
44
|
+
therefore rejects a materialized workspace nested under another `.git` path
|
|
45
|
+
before starting the SDK. Use the default system temporary parent or pass a
|
|
46
|
+
`--workspace-root` outside the invoking checkout; this prevents accidental
|
|
47
|
+
ancestor-project routing but is not OS containment.
|
|
48
|
+
|
|
49
|
+
No MCP servers, custom callback tools, subagents, cloud repositories, remote PR
|
|
50
|
+
automation, or environment values are loaded from configuration. Supply
|
|
51
|
+
`CURSOR_API_KEY` only in the process environment through the approved secret
|
|
52
|
+
path; it is passed directly to the SDK and never written to an artifact. The
|
|
53
|
+
SDK owns its child processes and does not expose a per-agent environment
|
|
54
|
+
allowlist in this pin. During the deliberately single-entry SDK run, EBO keeps
|
|
55
|
+
only platform/network variables and `CURSOR_API_KEY` in the process environment,
|
|
56
|
+
records the allowed key names (never values), and restores the original
|
|
57
|
+
environment after agent disposal. Concurrent in-process Cursor captures are
|
|
58
|
+
rejected while that boundary is active.
|
|
59
|
+
|
|
60
|
+
## Configuration records
|
|
61
|
+
|
|
62
|
+
The queue points to five digest-pinned `ebo.cursor-sdk-config/v1` records. The
|
|
63
|
+
minimal examples under [`examples/cursor-sdk`](../../examples/cursor-sdk/README.md) are
|
|
64
|
+
caller inputs, not defaults. Replace the model placeholder with one exact
|
|
65
|
+
catalog ID before computing digests and compiling a queue. The experiment's
|
|
66
|
+
model-set key remains a path-safe condition ID; it need not duplicate a
|
|
67
|
+
provider ID containing dots.
|
|
68
|
+
|
|
69
|
+
```json
|
|
70
|
+
{ "schemaVersion": "ebo.cursor-sdk-config/v1", "kind": "model", "provider": "cursor", "model": { "id": "<exact-catalog-model-id>" } }
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
```json
|
|
74
|
+
{ "schemaVersion": "ebo.cursor-sdk-config/v1", "kind": "harness", "adapter": "cursor-sdk", "sdkVersion": "1.0.31" }
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
```json
|
|
78
|
+
{ "schemaVersion": "ebo.cursor-sdk-config/v1", "kind": "native-limits", "shutdownGraceMs": 2000, "maxNativeRecordBytes": 16777216 }
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
```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 }
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
```json
|
|
86
|
+
{ "schemaVersion": "ebo.cursor-sdk-config/v1", "kind": "capture-profile", "nativeOtlp": "unsupported", "workspaceOutcome": { "excludeDirectoryNames": ["node_modules"] } }
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Use the existing packet admission, freeze, matrix compilation, and queue
|
|
90
|
+
validation commands from the [operator guide](../guides/operator-guide.md). Then run one
|
|
91
|
+
persisted entry:
|
|
92
|
+
|
|
93
|
+
```sh
|
|
94
|
+
# After injecting CURSOR_API_KEY through the approved secret environment:
|
|
95
|
+
ebo cursor run \
|
|
96
|
+
<bundle-root> <queue.json> <run-id> <output-root> \
|
|
97
|
+
--workspace-root <workspace-parent>
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
The output destination is never replaced. Interrupting the command cancels the
|
|
101
|
+
owned run within the configured shutdown grace. Provider, stream, history,
|
|
102
|
+
recorder, store, workspace, and cleanup failures retain a partial attempt and
|
|
103
|
+
cannot produce qualified-complete capture.
|
|
104
|
+
|
|
105
|
+
## Evidence and overlap policy
|
|
106
|
+
|
|
107
|
+
| Channel | Retained role | Normalized role |
|
|
108
|
+
|---|---|---|
|
|
109
|
+
| `run.stream()` | lifecycle, messages, tools, per-turn usage | authoritative message/tool/usage projection |
|
|
110
|
+
| `onDelta` / `onStep` | lower-level deltas, nested updates, step snapshots | retained as overlap evidence; not counted again |
|
|
111
|
+
| `run.wait()` | owned terminal status, duration, cumulative usage | authoritative outcome; cumulative usage is not re-added |
|
|
112
|
+
| `run.conversation()` | durable conversation readback before disposal | retained as history; not counted again |
|
|
113
|
+
| `agent.getUsage()` | eventually consistent billing scope/read time | separate billing evidence; absence does not invalidate semantic capture |
|
|
114
|
+
| `JsonlLocalAgentStore` | agents, runs, run events, checkpoints | authoritative native persistence; not counted again |
|
|
115
|
+
|
|
116
|
+
Every callback value is JSON-snapshotted at receipt and writes are serialized.
|
|
117
|
+
Unknown tool payloads remain in restricted native evidence. Portable export
|
|
118
|
+
recursively removes thinking/reasoning content and checkpoint blob bytes, then
|
|
119
|
+
redacts secrets, local identifiers, paths, and source correlations. Restricted
|
|
120
|
+
source artifacts are unchanged.
|
|
121
|
+
|
|
122
|
+
## Capability matrix
|
|
123
|
+
|
|
124
|
+
| Capability | Status | Basis |
|
|
125
|
+
|---|---|---|
|
|
126
|
+
| messages | available | SDK stream user/assistant records |
|
|
127
|
+
| tools | available | SDK stream `tool_call` identity/status/args/result |
|
|
128
|
+
| context | partial | detailed summaries/nested updates retained, not reconstructed |
|
|
129
|
+
| delegation | partial | task tool retained without invented subagent lifecycle |
|
|
130
|
+
| artifacts | unsupported | tool names retain intent only; verified workspace outcome remains separate and authoritative |
|
|
131
|
+
| usage | available | per-turn stream increments; cumulative/billing channels remain separate |
|
|
132
|
+
| terminal outcome | available | exact owned `run.wait()` result |
|
|
133
|
+
| parentage/native time | partial | exposed identities and adapter receipt order only |
|
|
134
|
+
| SDK-local OTLP configuration/receipt | unsupported | no public SDK `1.0.31` per-run API |
|
|
135
|
+
| Enterprise team OTLP export | not checked | server-side metrics/logs exist, but no destination or exact SDK run correlation was verified |
|
|
136
|
+
| OS containment | unsupported | SDK sandbox policy is not an OS/container boundary |
|
|
137
|
+
|
|
138
|
+
Run the deterministic contract proof with:
|
|
139
|
+
|
|
140
|
+
```sh
|
|
141
|
+
npm run build
|
|
142
|
+
node --test dist/test/cursor-sdk.test.js
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
That fixture covers frozen queue execution through workspace retention,
|
|
146
|
+
qualification, export/readback, observations, existing judge evidence,
|
|
147
|
+
comparison/aggregation, and Atlas drilldown. It is not proof of live provider
|
|
148
|
+
authentication. A live smoke must use an exact currently available catalog
|
|
149
|
+
model and one bounded synthetic local workspace edit through the same command.
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# DeepSeek Harness adapter
|
|
2
|
+
|
|
3
|
+
EBO drives DeepSeek Harness out of process through the pinned public package
|
|
4
|
+
roots `@deepseek-ai/dsh-sdk-client@0.1.1-rc.2` and
|
|
5
|
+
`@deepseek-ai/dsh-sdk-protocol@0.1.1-rc.2`. It does not import source modules,
|
|
6
|
+
embed the agent loop, or implement JSON-RPC framing, correlation,
|
|
7
|
+
subscriptions, or process teardown.
|
|
8
|
+
|
|
9
|
+
The upstream contracts are the official
|
|
10
|
+
[TypeScript client](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/sdk/client/README.md),
|
|
11
|
+
[wire protocol](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/sdk/protocol/README.md),
|
|
12
|
+
[server plugin](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/sdk/server/README.md),
|
|
13
|
+
[session log](https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/subsystems/session.md),
|
|
14
|
+
and [session telemetry](https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/subsystems/session-telemetry.md).
|
|
15
|
+
|
|
16
|
+
## Live verification
|
|
17
|
+
|
|
18
|
+
The September 9 release audit ran the installed `@deepseek-ai/dsh@0.1.1-rc.2`
|
|
19
|
+
runtime with matching `dsh-sdk-jsonrpc-server` and `dsh-llm-pi-ai` packages.
|
|
20
|
+
The npm CLI at that version has no shipped `sdk` profile. A custom profile's
|
|
21
|
+
`package.json` selected `dsh.profile.bundles: ["@deepseek-ai/dsh-base"]`;
|
|
22
|
+
its patch mounted the official JSON-RPC server and configured the existing
|
|
23
|
+
`llm-pi-ai` plugin. No agent loop or protocol implementation was added to EBO.
|
|
24
|
+
|
|
25
|
+
The provider configuration used `api: openai-completions`,
|
|
26
|
+
`baseURL: https://api.z.ai/api/coding/paas/v4`, `apiKeyEnv: ZAI_API_KEY`,
|
|
27
|
+
and model `glm-5.3-flash`. The key was supplied only through the recorded child
|
|
28
|
+
environment allowlist. The permission preset explicitly paired workspace-write
|
|
29
|
+
sandboxing with unattended approval; module reload, generated session titles,
|
|
30
|
+
and native telemetry were disabled for this smoke.
|
|
31
|
+
|
|
32
|
+
The run wrote `done` to the requested file in 12 seconds and retained 206
|
|
33
|
+
client observations, including 196 native session notifications. All 35
|
|
34
|
+
sequenced events in the persisted session log matched delivered native events;
|
|
35
|
+
the stream also carries chunk events stored compactly by the runtime.
|
|
36
|
+
Receipt-to-idle completion and client-owned process teardown passed.
|
|
37
|
+
Capture qualification and validation of 202 projected events passed after
|
|
38
|
+
expanding the uniform relation bound to preserve large native source sets.
|
|
39
|
+
|
|
40
|
+
This proves the tested Z.ai composition, not every provider or plugin choice.
|
|
41
|
+
The runtime reported server version `0.0.1`; installed npm package versions
|
|
42
|
+
and the runtime/configuration digests identify the actual software. Native
|
|
43
|
+
telemetry was disabled and is not live-verified by this smoke. Capture/judge
|
|
44
|
+
and release checks do not turn a successful file-write smoke into a quality score.
|
|
45
|
+
|
|
46
|
+
## Runtime composition
|
|
47
|
+
|
|
48
|
+
`ebo.deepseek-runtime-composition/v1` records the exact Node command and
|
|
49
|
+
arguments, process and workspace directories, named profile, ordered Cordis
|
|
50
|
+
patches, provider/model route, pinned client/protocol versions, plugin names,
|
|
51
|
+
an ordered digest-bearing reference for every Cordis patch and plugin
|
|
52
|
+
configuration, the launched runtime artifact, environment policy, and telemetry
|
|
53
|
+
selection. Every referenced configuration and runtime digest is rechecked
|
|
54
|
+
before the process starts.
|
|
55
|
+
Environment values are not recorded. The adapter passes a replacement child
|
|
56
|
+
environment to the official client and rejects keys outside the recorded
|
|
57
|
+
allowlist; configured secret values are redacted from retained error and stderr
|
|
58
|
+
tails. When a Harness home is selected, the child `DSH_HOME` is set from that
|
|
59
|
+
retained path and any caller-supplied value must match it.
|
|
60
|
+
|
|
61
|
+
Two fixtures demonstrate configuration-only swaps:
|
|
62
|
+
|
|
63
|
+
- `test/fixtures/deepseek/compositions/minimal` disables native telemetry.
|
|
64
|
+
- `test/fixtures/deepseek/compositions/telemetry` composes the telemetry plugin
|
|
65
|
+
and records its separate artifact reference.
|
|
66
|
+
|
|
67
|
+
The adapter code is identical for both compositions. Runtime and plugin choices
|
|
68
|
+
remain configuration, not EBO runner branches.
|
|
69
|
+
|
|
70
|
+
## Native evidence
|
|
71
|
+
|
|
72
|
+
`HarnessClient` owns the child and JSON-RPC transport. EBO calls only its public
|
|
73
|
+
`start`, `initialize`, `prompt`, `subscribeSessionTree`, and `close` methods.
|
|
74
|
+
The native JSONL evidence records:
|
|
75
|
+
|
|
76
|
+
- the selected composition and capability report;
|
|
77
|
+
- typed initialize, prompt receipt, notification, error, and shutdown
|
|
78
|
+
observations in observed order;
|
|
79
|
+
- every delivered `session.event` envelope verbatim, including its native
|
|
80
|
+
`seq`, `time`, surface metadata, and source-specific fields;
|
|
81
|
+
- root and child session identities from each native notification, with the
|
|
82
|
+
declared session tree used during bundle qualification;
|
|
83
|
+
- whole-agent `session.status` and available subagent notifications; and
|
|
84
|
+
- bounded, redacted diagnostics only when the official client attributes them
|
|
85
|
+
to the child stderr tail.
|
|
86
|
+
|
|
87
|
+
Stdout remains exclusively owned by the official JSON-RPC transport. EBO does
|
|
88
|
+
not attach a console exporter or stdout logger. The controlled-runtime test
|
|
89
|
+
parses every emitted evidence line and forces a contaminated runtime to fail
|
|
90
|
+
while retaining its stderr diagnostic and partial observations.
|
|
91
|
+
|
|
92
|
+
## Completion and limitations
|
|
93
|
+
|
|
94
|
+
`session/prompt` returns only the durable queued message ID. Completion requires
|
|
95
|
+
the matching native `agent/inbox/spliced` event followed by the root session
|
|
96
|
+
whole-agent `session.status: idle`. Those two observation sequences are retained
|
|
97
|
+
as the activity boundary. They do not claim that an assistant message was
|
|
98
|
+
caused by the prompt, and `finalResponse` is not treated as a prompt result.
|
|
99
|
+
|
|
100
|
+
The capability report keeps these current protocol limitations explicit:
|
|
101
|
+
|
|
102
|
+
- protocol-version negotiation: unsupported;
|
|
103
|
+
- prompt cancellation: unsupported;
|
|
104
|
+
- per-session close: unsupported;
|
|
105
|
+
- true per-prompt result: unsupported; and
|
|
106
|
+
- native spans: available, unsupported, or not checked according to the named
|
|
107
|
+
telemetry composition.
|
|
108
|
+
|
|
109
|
+
The official client owns graceful `shutdown`, stdin EOF, SIGTERM, and SIGKILL
|
|
110
|
+
escalation. An interruption, activity timeout, transport exit, or protocol
|
|
111
|
+
failure closes through that same ladder. Delivered notifications and stderr
|
|
112
|
+
remain valid partial evidence.
|
|
113
|
+
|
|
114
|
+
## Normalization
|
|
115
|
+
|
|
116
|
+
Normalization begins only when the capture retains the selected composition,
|
|
117
|
+
capabilities, successful initialize and prompt receipts, and at least one
|
|
118
|
+
durable session event. A completed capture additionally requires the exact
|
|
119
|
+
receipt-to-idle boundary and successful official-client close/reap evidence.
|
|
120
|
+
The client does not expose whether its best-effort protocol shutdown request or
|
|
121
|
+
a later EOF/signal step ended the process, so EBO does not invent a shutdown
|
|
122
|
+
response.
|
|
123
|
+
|
|
124
|
+
The capture report persists the required semantic-evidence kinds and related
|
|
125
|
+
session IDs. Later qualification treats that declaration as authoritative and
|
|
126
|
+
rejects caller overrides that would weaken or replace it.
|
|
127
|
+
|
|
128
|
+
Mapped events retain a `line:N` native reference into the authoritative DeepSeek
|
|
129
|
+
JSONL. Session events use their native session-local sequence/time; EBO client
|
|
130
|
+
observations use a separate observation-order domain. Large message, tool,
|
|
131
|
+
compaction, request, validation, and artifact bodies remain behind content
|
|
132
|
+
references. Unknown source events remain explicitly unmapped rather than being
|
|
133
|
+
dropped or forced into a convenience family. Optional telemetry stays a
|
|
134
|
+
separate timing/resource artifact and never replaces semantic session events.
|