Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
21 changes: 5 additions & 16 deletions .github/workflows/native.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,37 +76,26 @@ jobs:
run: ./deploy/test_install.ps1 -Binary "$env:RUNNER_TEMP/oac.exe"
- name: Verify native download bootstrap and recovery
run: go test ./services/core/internal/nativeinstaller -count=1 -timeout=3m
- name: Native filesystem, authentication and process lifecycle
- name: Native filesystem and process lifecycle
id: filesystem
run: >-
go test -race -count=1
./internal/runtimefs
./apps/daemon/internal/auth
./apps/daemon/internal/paths
./apps/daemon/internal/daemonize
./apps/daemon/internal/agent/clirunner
- name: Native Harness ownership and environment identity
- name: Native Harness process ownership
id: harness
run: >-
go test -race -count=1
./apps/daemon/internal/agent/codex
./apps/daemon/internal/agent/claudesdk
./apps/daemon/internal/agent/mcode
-run 'TestJSONRPCClientOwnsToolDescendants|TestSelfHostedToolEnvironment'
- name: Native capability snapshots, files and installation
-run 'TestJSONRPCClientOwnsToolDescendants'
- name: Native installation
id: files
run: >-
go test -race -count=1
./apps/daemon/internal/localworkspace
./apps/daemon/internal/cli
-run 'TestNative|TestRuntimeInit|TestRuntimePreparationRejects|TestPreparationFreezesLocalContentsAcrossReconnect|TestSnapshotMarker'
- name: Windows npm and npx stdio launchers without network
if: runner.os == 'Windows'
run: >-
go test -race -count=1 -timeout=2m
./apps/daemon/internal/localworkspace
./apps/daemon/internal/cli
-run 'TestWindowsPackageManager|TestWindowsRuntimeMCP'
-run 'TestNative'
- name: Build pinned native components
run: |
pnpm --dir packages/claude-sdk-adapter install --frozen-lockfile
Expand Down
1 change: 0 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ Do not multiply entities without necessity. The long-term goal is minimal code,
| Nodes and daemons–Core (`/api/v1` HTTP routes; the node and daemon wire protocols are separate rows) | Route annotations in `services/core/internal/api/`; `make openapi` generates `contracts/agents-api/runtime.openapi.yaml` | [Machine connection API](contracts/agents-api/machine-api.md) |
| Core–Sandbox Provider | `services/core/internal/sandbox/sandbox_provider.go` | [Sandbox Provider guide](docs/sandbox-provider.md) |
| Core–sandbox node | `services/core/internal/sandbox/node/wire.go` | [Sandbox node protocol](contracts/agents-api/node-generation-protocol.md) |
| Provider–Runtime startup | `internal/runtimebootstrap/bootstrap.go` | [Runtime bootstrap](docs/runtime-bootstrap.md) |
| Runtime and Sandbox I/O service–relay (Link) | `internal/sandboxlink/protocol.go` | [Sandbox link protocol](docs/sandbox-link-protocol.md) |
| Provider–Sandbox I/O startup | `internal/sandboxbootstrap/bootstrap.go` | [Sandbox bootstrap](docs/sandbox-bootstrap.md) |
| Runtime–file service | `internal/sandboxfs/protocol.go` | [File access protocol](docs/file-access-protocol.md) |
Expand Down
2 changes: 1 addition & 1 deletion apps/daemon/internal/agent/binpath/binpath.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
// control: e2b's base image, for instance, ships its own
// /usr/local/bin entries that can shadow the ones we install, and a
// bare-name lookup then resolves to the wrong (or no) binary. The
// symptom is the worst kind — `oac-daemon connect` reports
// symptom is the worst kind — the agent host reports
// "no supported agent CLI available" and the device never dials in,
// with no indication of which lookup failed.
//
Expand Down
162 changes: 0 additions & 162 deletions apps/daemon/internal/agent/claudesdk/cancellation_live_linux_test.go

This file was deleted.

13 changes: 5 additions & 8 deletions apps/daemon/internal/agent/claudesdk/cancellation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import (

func TestCancellationWaitsForDrainAndPublishesOutcome(t *testing.T) {
root := t.TempDir()
t.Setenv("OAC_RUNTIME_HOME", root)
config := cancellationConfig(root, "wait")
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
Expand All @@ -47,7 +46,7 @@ func TestCancellationWaitsForDrainAndPublishesOutcome(t *testing.T) {
if err := running.SteerWithReceipt(ctx, proto.PromptSteerPayload{InputID: "later", Input: proto.TextInput("later")}, func() {}); !errors.Is(err, agent.ErrSteeringInactive) {
t.Fatal("cancelled execution accepted steering", err)
}
if err := os.WriteFile(filepath.Join(config.StateDir, "release"), nil, 0o600); err != nil {
if err := os.WriteFile(filepath.Join(config.StateDir(), "release"), nil, 0o600); err != nil {
t.Fatal(err)
}
if err := running.Cancel(ctx); err != nil {
Expand Down Expand Up @@ -85,7 +84,6 @@ func TestFailureKeepsOnlyVerifiedNativeIdentity(t *testing.T) {
for _, mode := range []string{"failure", "wrong-identity", "before-identity"} {
t.Run(mode, func(t *testing.T) {
root := t.TempDir()
t.Setenv("OAC_RUNTIME_HOME", root)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
out := make(chan proto.Envelope, 8)
Expand Down Expand Up @@ -120,7 +118,6 @@ func TestFailureKeepsOnlyVerifiedNativeIdentity(t *testing.T) {

func TestCancellationDrainsIntoReadyConsumer(t *testing.T) {
root := t.TempDir()
t.Setenv("OAC_RUNTIME_HOME", root)
config := cancellationConfig(root, "wait")
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
Expand All @@ -133,7 +130,7 @@ func TestCancellationDrainsIntoReadyConsumer(t *testing.T) {
if event := <-out; event.Type != proto.TypeDelta {
t.Fatal("missing native readiness barrier")
}
if err := os.WriteFile(filepath.Join(config.StateDir, "release"), nil, 0o600); err != nil {
if err := os.WriteFile(filepath.Join(config.StateDir(), "release"), nil, 0o600); err != nil {
t.Fatal(err)
}
if err := running.Cancel(ctx); err != nil {
Expand All @@ -158,12 +155,12 @@ func TestCancellationDrainsIntoReadyConsumer(t *testing.T) {
}
}

func cancellationConfig(root, mode string) Config {
return Config{Node: os.Args[0], Entrypoint: filepath.Join(root, "worker"), StateDir: filepath.Join(root, "state"), Env: []string{"GO_CLAUDE_SDK_HELPER=1", "SDK_HELPER_MODE=cancellation-" + mode, "GORACE=atexit_sleep_ms=0"}}
func cancellationConfig(root, mode string) testBridge {
return testBridge{Config: Config{Node: os.Args[0], Entrypoint: filepath.Join(root, "worker"), Env: []string{"GO_CLAUDE_SDK_HELPER=1", "SDK_HELPER_MODE=cancellation-" + mode, "GORACE=atexit_sleep_ms=0"}}, Home: root}
}

func cancellationRequest() proto.PromptRequestPayload {
return proto.PromptRequestPayload{ModelProvider: fixtureProvider(), AgentSessionID: "native-session", Model: "fake-model", SystemPrompt: "instructions"}
return proto.PromptRequestPayload{ModelProvider: fixtureProvider(), DisableExecutionEnvironment: true, AgentSessionID: "native-session", Model: "fake-model", SystemPrompt: "instructions"}
}

func runCancellationHelper(request startRequest, mode string, scanner *bufio.Scanner, emit func(bridgeEvent)) {
Expand Down
8 changes: 4 additions & 4 deletions apps/daemon/internal/agent/claudesdk/commands_session_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,22 @@ import (

func TestWorkspaceCommandsRequirePackagedFeature(t *testing.T) {
config := preparationFixture(t, "old-command-runtime")
if _, err := NewExecutorFactory(config)(t.Context(), prepared(t, preparationRequest())); err == nil || !strings.Contains(err.Error(), "workspace preparation is unavailable") {
if _, err := config.factory()(t.Context(), prepared(t, preparationRequest())); err == nil || !strings.Contains(err.Error(), "workspace preparation is unavailable") {
t.Fatal("old bridge accepted command observations", err)
}
if _, err := os.Stat(filepath.Join(config.StateDir, "launched")); !os.IsNotExist(err) {
if _, err := os.Stat(filepath.Join(config.StateDir(), "launched")); !os.IsNotExist(err) {
t.Fatal("old bridge started execution before rejection")
}
}

func TestWorkspaceCommandFramesKeepStartIdentityAndObservedOutput(t *testing.T) {
config := preparationFixture(t, "commands-success")
resource, err := NewExecutorFactory(config)(t.Context(), prepared(t, preparationRequest()))
resource, err := config.factory()(t.Context(), prepared(t, preparationRequest()))
if err != nil {
t.Fatal(err)
}
defer resource.Close(context.Background())
if _, err := os.Stat(filepath.Join(config.StateDir, "start.json")); !os.IsNotExist(err) {
if _, err := os.Stat(filepath.Join(config.StateDir(), "start.json")); !os.IsNotExist(err) {
t.Fatal("preparation submitted a command")
}
out := make(chan proto.Envelope, 16)
Expand Down
Loading
Loading