Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
2f44e1e
test(e2e): isolate EXDEV live boundaries
rsliter Sep 11, 2026
8de279e
merge: integrate canonical main for issue 11547
rsliter Sep 11, 2026
f5d18ea
test(e2e): close EXDEV fixture cleanup gap
rsliter Sep 11, 2026
1792963
docs(e2e): correct EXDEV line budget
rsliter Sep 11, 2026
ad32608
merge: refresh canonical main for issue 11547
rsliter Sep 11, 2026
0448934
test(e2e): rebase EXDEV scope after fixture repair
rsliter Sep 11, 2026
5897545
merge: refresh canonical main for issue 11547
rsliter Sep 11, 2026
95f33aa
merge: refresh canonical main for issue 11547
rsliter Sep 11, 2026
adf42c9
merge: refresh canonical main for issue 11547
rsliter Sep 11, 2026
76a6713
merge: refresh canonical main for issue 11547
rsliter Sep 11, 2026
c7122ab
test(e2e): retain verified forward release
rsliter Sep 11, 2026
b937ac6
Merge remote-tracking branch 'origin/main' into codex/11547-exdev-liv…
rsliter Sep 11, 2026
ab38c79
Merge remote-tracking branch 'origin/main' into codex/11547-exdev-liv…
rsliter Sep 11, 2026
8f43510
Merge remote-tracking branch 'origin/main' into codex/11547-exdev-liv…
rsliter Sep 11, 2026
6d470ac
Merge remote-tracking branch 'origin/main' into codex/11547-exdev-liv…
rsliter Sep 11, 2026
bd5a032
test(e2e): remove stale gateway stop
rsliter Sep 11, 2026
a2a5ad6
docs(e2e): align EXDEV reduction metrics
rsliter Sep 11, 2026
aca9a8c
Merge remote-tracking branch 'origin/main' into codex/11547-exdev-liv…
rsliter Sep 11, 2026
85920ce
merge: refresh main into EXDEV test refactor
rsliter Sep 14, 2026
f501e2d
merge: refresh current main before EXDEV validation
rsliter Sep 14, 2026
f8b670b
merge: refresh current main for E2E publication
rsliter Sep 14, 2026
6f449a8
test(e2e): canonicalize EXDEV fixture roots
rsliter Sep 14, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions ci/e2e-assertion-budget.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,28 +15,28 @@
"testFileCount": 85,
"liveFileCount": 220,
"direct": {
"expectCalls": 1794,
"matcherAssertions": 1763,
"expectCalls": 1793,
"matcherAssertions": 1762,
"nodeAssertions": 105,
"namedAssertionHelpers": 602,
"failCalls": 8,
"throwGuards": 87,
"objectFieldAssertions": 243,
"assertionPoints": 2808,
"generatedProbeBlocks": 122,
"generatedProbeConditions": 322
"assertionPoints": 2807,
"generatedProbeBlocks": 121,
"generatedProbeConditions": 321
},
"unique": {
"expectCalls": 2286,
"matcherAssertions": 2250,
"nodeAssertions": 126,
"expectCalls": 2285,
"matcherAssertions": 2249,
"nodeAssertions": 124,
"namedAssertionHelpers": 906,
"failCalls": 38,
"throwGuards": 627,
"objectFieldAssertions": 342,
"assertionPoints": 4289,
"generatedProbeBlocks": 276,
"generatedProbeConditions": 943
"assertionPoints": 4286,
"generatedProbeBlocks": 274,
"generatedProbeConditions": 935
},
"fileMetricOrder": [
"directExpectCalls",
Expand Down Expand Up @@ -99,7 +99,7 @@
"test/e2e/live/onboard-resume.test.ts": [59,63,59,63,0],
"test/e2e/live/openclaw-discord-pairing.test.ts": [13,20,28,86,10],
"test/e2e/live/openclaw-inference-switch.test.ts": [50,56,50,57,2],
"test/e2e/live/openclaw-plugin-runtime-exdev.test.ts": [9,17,9,32,3],
"test/e2e/live/openclaw-plugin-runtime-exdev.test.ts": [8,16,8,25,0],
"test/e2e/live/openclaw-skill-cli.test.ts": [10,14,10,14,1],
"test/e2e/live/openclaw-slack-pairing.test.ts": [11,18,26,84,10],
"test/e2e/live/openclaw-tui-chat-correlation.test.ts": [40,46,40,52,4],
Expand Down
19 changes: 18 additions & 1 deletion test/automation/pull-requests/pr-risk-plan.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,7 @@ describe("deterministic PR risk plan", () => {
it.each([
"test/e2e/fixtures/openclaw-plugin-runtime-exdev-onboard.ts",
"test/e2e/live/openclaw-plugin-runtime-exdev-trusted-prebuild.ts",
])("maps %s changes to the EXDEV job (#10517)", (changedFile) => {
])("maps %s changes to the EXDEV job (#10517, #11547)", (changedFile) => {
expect(focusedE2eJobsForChangedFiles([changedFile])).toEqual([
{
id: "openclaw-plugin-runtime-exdev",
Expand All @@ -465,6 +465,23 @@ describe("deterministic PR risk plan", () => {
]);
});

it("maps shared canonical OpenShell components to every live consumer (#11547)", () => {
const changedFile = "test/helpers/openshell-components.ts";

expect(focusedE2eJobsForChangedFiles([changedFile])).toEqual([
{ id: "mcp-bridge", matchedFiles: [changedFile] },
{ id: "openclaw-plugin-runtime-exdev", matchedFiles: [changedFile] },
]);
});

it("maps the exact-main driver wrapper to its stable live consumer (#11547)", () => {
const changedFile = "test/e2e/live/openshell-driver-config-test-wrapper.ts";

expect(focusedE2eJobsForChangedFiles([changedFile])).toEqual([
{ id: "mcp-bridge", matchedFiles: [changedFile] },
]);
});

it.each([
"src/lib/acp/main.ts",
"src/lib/acp/command.ts",
Expand Down
60 changes: 43 additions & 17 deletions test/e2e/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -779,30 +779,56 @@ recreation each run once. If onboarding or recreation reports missing canonical
CLI device pairing or a bounded CLI scope warm-up failure, the test attempts to
record structured diagnostics, attempts to write bounded `failed-no-retry`
evidence, and then stops without automatically resuming the ambiguously mutated
session. An evidence
write failure propagates, so that retry artifact may be absent. `tools.invoke`
session. An evidence write failure propagates, so that retry artifact may be
absent. `tools.invoke`
assertions prove the plugin version after onboarding, restart, and recreation.
The job also keeps the test-only tmpfs mount and uses OpenClaw's plugin installer
across the proven filesystem boundary before restart. `e2e-support` tests own
sandbox-create interception and wrapper argument rewriting. Onboarding and
recreation load the test-only interceptor; all other OpenShell commands use the
canonical binary so dashboard forward ownership remains verifiable. Deterministic
tests own exact package versions and third-party replacement internals. Runtime inspection and catalog
permutations are outside this live contract. Workspace preservation and policy
selection retain their focused coverage instead of another assertion in this
target. The `rebuild-openclaw` job remains the canonical live rebuild coverage.
The job uses OpenClaw's real plugin installer from a read-only host mount whose
device differs from the extension target. This proves installation across the
filesystem boundary, not a particular internal `EXDEV` system call or fallback.

The live assertions stop at the boundary outcomes: v1 after onboarding,
distinct source and target devices, a successful real install, v1-exdev after a
real gateway restart, v2 after recreation, and registered cleanup. The target
does not inspect listener process IDs, kill a gateway listener, rewrite
OpenShell commands, or assert terminal wording. Production forward-service
unit and integration tests own listener authority and wrapper mismatch
rejection. `e2e-support` owns canonical component composition, immutable image
handoff, recreation command shape, fixture extraction safety, output parsing,
and cleanup ordering. Deterministic tests also own exact package versions and
third-party replacement internals. Runtime inspection and catalog permutations
remain outside this live contract. Workspace preservation and policy selection
retain their focused coverage. The `rebuild-openclaw` job remains the canonical
live rebuild coverage.

The current-checkout fixture locally prebuilds repository-controlled images
with BuildKit. It verifies each local tag, then passes the matching immutable
image ID to OpenShell. User-supplied `--from` Dockerfiles retain the
gateway-builder trust boundary and are never host-prebuilt by this fixture.
The current-checkout fixture enables local base-image resolution after the
workflow removes Docker Hub credentials.
with BuildKit. It verifies each local tag, extracts the cross-device payload
from the matching immutable image ID into a fresh canonical `/dev/shm`
directory, and mounts that directory read-only at the same target during
onboarding and recreation. A minimal custom Dockerfile pins the image ID while
preserving the tool-disclosure build arguments. Canonical OpenShell CLI,
gateway, and sandbox executables own every forward lifecycle command. User
`--from` Dockerfiles retain the gateway-builder trust boundary and are never
host-prebuilt by this fixture. The current-checkout fixture enables local
base-image resolution after the workflow removes Docker Hub credentials.

The release-baseline lane is retired. Historical package versions are not part
of this current runtime contract.

Push-run timing for the reduced lifecycle has not yet been measured.
At issue creation, the live target had 9 direct `expect` calls and 17 direct
assertion points across 654 lines. Its three companions raised the transitive
totals to 9 `expect` calls, 32 assertion points, and three generated probe
blocks across 1,178 lines. A passing seven-phase run took about 20 minutes even
though the core cross-device install took about seven seconds. After #11552
fixed canonical forward ownership, the current base kept those assertion totals
while growing to 658 target lines and 1,202 transitive live lines. Its first
automatic main run completed the live step in 7 minutes 26 seconds.

The #11547 reduction keeps all seven phases while lowering the target to 8
direct `expect` calls and 16 direct assertion points. Its two companions bring
the transitive totals to 8 `expect` calls, 25 assertion points, and no generated
probe blocks across 1,094 lines. Against the current base, the live target falls
from 658 to 580 lines and the transitive live surface falls from 1,202 to 1,094
lines. Push-run timing for this revision is recorded by the focused PR E2E run.

## OpenShell development artifact retention

Expand Down
Loading
Loading