Qualify the installed repository response and dispatch custody
Human verified
A human reviewed this page, but it may be out of date. Later edits may not have been reviewed.
Check useful Git work and conversation continuity
From the repository root, use Node.js 24 or newer, Git, OpenSSL, matching installed
workspace dependencies, and an owned disposable PostgreSQL fixture. Follow the
prepared PostgreSQL setup. Inside its
cleanup-trapped subshell, replace the run-tests command with these commands.
Each case copies the migrated template and runs as the limited application role.
Clearing stale overrides ensures it uses this run's prepared database:
node scripts/ci/prepare.mjs --lane postgres-application \ --file tests/integration/postgres-external-protected-git.test.ts \ --state "$PG_RUN_DIR/state.json" --github-env "$PG_RUN_DIR/test.env"env -u OCC_TEST_DATABASE_URL -u OPENCLAW_ENTERPRISE_CI_STATE \ -u OPENCLAW_ENTERPRISE_CI_PREFIX node --env-file="$PG_RUN_DIR/test.env" --test \ tests/integration/postgres-external-protected-git.test.tsRequire every selected case to pass without skips. The installation journeys fetch a previously absent object, push a new commit, create and update a PR, then push a second distinct commit to the same branch. They read the same PR through the authorized API route and compare its head ref with the exact commit in the real bare origin. They also require rejection of a provider-protected ref and fresh Git denial after withdrawal, with no issuance or workload traffic, while the same token still works directly at the controlled provider. Git and PostgreSQL are real; the installed external Driver, workload, placement and GitHub API are fixtures.
The default file-based GitHub policy case signs in a persisted account through Fastify, creates and deploys an Agent without a public Repo Driver, and refuses the same repository in an otherwise authorized foreign Namespace before issuance or Git traffic. It restarts the Worker and custody owner, fetches a new commit through the original revision, then proves a due renewal issues and installs new material while approved. After withdrawal, the same due custody pass must issue nothing; fresh fetch and push fail before issuer or workload-provider ingress. Intentional token retirement is counted separately from workload traffic. The provider holds retirement of the current token through the denied Git requests and a direct validity probe, then releases it before custody and Worker checks. The two direct probe requests are accounted for separately; issuer and workload baselines remain continuous. This is local protocol and persistence proof, not an installed OpenShell or live GitHub qualification.
Run the external Driver conversation rehearsal with the same prepared PostgreSQL
test environment and OCC_TEST_STANDING_GIT_CODEX set to the absolute path of
the Codex executable pinned by the runtime Dockerfile:
env -u OCC_TEST_DATABASE_URL -u OPENCLAW_ENTERPRISE_CI_STATE \ -u OPENCLAW_ENTERPRISE_CI_PREFIX OCC_TEST_REQUIRE_EXTERNAL_GIT_CONVERSATION=1 \ node --env-file="$PG_RUN_DIR/test.env" --test \ --test-name-pattern="a capable external Driver reduces Git" \ tests/integration/postgres-external-protected-git.test.tsRequire the four check receipts model-before, git-fetched, git-refused,
and model-after, a passing selected case, and successful fixture cleanup.
This runs the shipped Codex process and real Git, with a controlled inference
origin and the external Driver fixture. It uses synthetic credentials and
requires no OpenShell installation.
The OpenShell-specific conversation case still runs with
pnpm test:standing-git-conversation and its corresponding prepared database.
On the deployed build, use disposable repositories and an approved GitHub credential source. The Agent must never receive the token. In one Agent conversation, repeat the fetch, two commits, PR creation and update; independently read back the PR and its Git head. Withdraw Git while its token is still valid, require a fresh Git request to fail without provider traffic, and continue that conversation through its retained model access. Record build IDs, commit SHAs, PR number, withdrawal time and both turns; exclude credentials. Reconcile an uncertain write by reading its state, never by replaying it. The local proofs do not replace this installed qualification.
Reuse the rehearsal with another runtime
Use the scenario helper from a
Node test. Run all four observations inside the runAgentGrantRehearsal callback.
The test fails if the callback returns before modelAfter succeeds.
Register cleanup as each resource is acquired with t.after, including
the Agent process, origin servers, and disposable repository. Keep the operator
control endpoints and origin repository outside the workload's reach.
- Start one Agent and one conversation. Serve two distinct answers from a
controlled model origin. Require the first answer and its origin request,
then call
modelBeforewith the observed Agent, revision, runtime, session, and turn IDs. - Read the expected commit SHA at the bare origin. Use real Git in a
workload-owned repository and check that it lacks that commit before fetch.
Give
gitFetchedthe observedFETCH_HEADand the change in origin request count. Use a separate origin-side control to publish commits. - Remove the Git grant through its owning control plane while the Agent stays
up. Publish a different commit at the origin. Fetch the same ref through the
workload's original Git path. Require the adapter's specific policy refusal
and pass Git's exit status, the before and after object lookups, and origin
request delta to
gitRefused. - Ask a second question on the original conversation. Verify the controlled
model reply, read back the same runtime identity, and pass the new turn ID
to
modelAfter. Stop and join the workload before closing the origins.
For a Strands Agents SDK workload, start with the Strands Box SDK example and the Git tool policy from its Git workload test. Replace the example's Bedrock provider with an SDK model pointed at the controlled origin and keep the SDK Agent alive for both turns. Give its Git tool access to one disposable checkout and one fixture HTTPS repository. Use a test CA and a synthetic origin credential if required. Keep both origin control channels outside the Box.
Use the hosted Box library from the
reload integration test.
Start one strands_box::run and have the host call strands_box::reload with
the complete policy minus the Git destination permit. Keep Git tool execution
and the model destination permitted so the refusal occurs at the Git egress
boundary. Read the denial in the Box journal and measure Git origin traffic
outside the Box. Use the Box execution identity as runtimeId. This path needs
no OpenShell or workload identity service. To qualify an installed integration,
withdraw through that integration's actual grant owner and verify the same
observations through its selected sender.
Qualify installed custody
Run the dedicated egress-custody-installed lane on a newly prepared, disposable
controller and OpenShell pair before landing whole-execution repository authority.
The lane manifest
requires every named observation. An ordinary CI pass or the static inference lane
does not run this qualification. Preserve exact build, image selection, installed
configuration and independent network-enforcement evidence with the result.
Use the version 2 connected inputs, with authorityProfile set to
fresh-whole-execution and no credentialConnector. Omit controllerUpgrade: this
lane qualifies one deployed release. In gateway discovery, the supplier must list
each of these capabilities exactly once in both its required and supported lists, in any order:
credential access, installation exchange, response custody, execution authority and protected
no-material support. Installed enforcement evidence must report them in the order shown.
Configure its fixture bridge and valid TLS trust for both
ordinary workload clients. Select the fixture HTTPS origin (without /v1) in
drivers.credential_proxy.configuration.preparedGitHub.apiOrigin in the Installation.
Supply issuerCaPath: /etc/openclaw/prepared-github-issuer/ca.crt and
custodyKeyPath: /etc/openclaw/prepared-github/custody.key. In the chart select
preparedGitHub.custodySecretName, issuerCaConfigMapName, exact issuerCidrs
IPv4 /32 and issuerPort. The API and worker need working DNS and verified
TLS to that origin. The test checks the selected private origin in both Pods
before enrollment; a credential source cannot redirect it. The test also checks
the workload's effective authorization cannot retrieve or project the Compute signer.
The test generates an App key, separately consented dedicated Agents and metadata-only installation credentials. It contacts neither GitHub nor a model provider.
The qualification operator needs the supplier's workspace User role and
sandbox:write access for ExecSandbox. The test rechecks the enrolled Sandbox
name and immutable ID, records a fresh launch request ID, then asks the authenticated
gateway to start ordinary curl or Node on the supplier's workload launcher. The
children inherit its connection mediation and installed TLS trust. Operator credentials
stay on the gateway control channel. A Kubernetes exec in the same Pod would not
inherit the launcher's mediation. If the terminal Exit is missing or the supplier
reports an execution timeout, reconcile that launch ID without resubmitting the client.
The supervisor's later egress request ID identifies a separate operation.
Observe custody while the enrolled Sandbox still exists. The supervisor pushes structured
INFO events in batches. Its console output omits the request ID and transition fields.
The test reads the full supplier log with GetSandboxLogs (workspace User, sandbox:read),
checks the Sandbox ID, supervisor Pod UID, container and log continuity, then joins the
reported request ID to the dispatch receipt and the independently observed origin request.
A refusal requires an explicit no_permit event. If delivery is incomplete, ambiguous or
late, report custody as unobservable and preserve the other evidence without repeating the
workload request. The log supplies evidence about that request, never permission to send it.
Before installing the disposable API controller, start the following observer on
its owner host. Use the same limited disposable database selected for the test.
The directory must not already exist. Keep the Unix socket on this host. Route
only that API controller's database connection through the observer's loopback
data port using the disposable network's supported forwarding. This observer
needs an explicitly non-TLS local PostgreSQL wire; never turn off an existing
transport security requirement to run it. Permit the deliberate restart only
on this API Pod template with the annotation
openclaw.dev/egress-custody-qualification-restart: permitted. Keep the owner
forward to the API service alive across Pod replacement. Include setup, test,
fresh API readiness, evidence and cleanup in the actual slot and outer deadline.
node tests/fixtures/egress-custody-postgres-observer.mjs "$new_observer_dir" "$data_port"In the qualification shell, set the four connected inputs from the lane manifest, then select the actual lane. The state and results paths must belong to this attempt.
export OCC_TEST_EGRESS_DISPATCH_OBSERVER_SOCKET="$new_observer_dir/control.sock"CI_RUNNER_DEADLINE_MS=$(node -p 'Date.now() + 95 * 60000') \CI_RUNNER_TEST_TIMEOUT_MS=5100000 node scripts/ci/run-tests.mjs run egress-custody-installed \ --state "$attempt/state.json" --results "$attempt/results.json"Reserve 90 minutes for the lane after setup, plus time for collection and disposal.
The installed test has a 74-minute execution budget. The 85-minute file timeout above
also covers owned-resource cleanup. If set, the runner's absolute CI_RUNNER_DEADLINE_MS
must leave at least 90 minutes when the lane starts.
Require both files in the manifest to pass. At the real TLS gRPC authority, a synthetic enrolled peer presents the copied opening first on the wrong sink, crosses two signed openings and two live dispatch handles, and attempts to splice an actual pending reply. The installed test cannot extract a supervisor's possession key to repeat that injection. Instead it holds two separately authorized executions' actual replies, makes B finish first with only the final forbidden trailer, checks B's exact refusal and A's exact approved identity through TLS FIN (curl at A, an independent Node client at B), then checks B's own fresh authorized read. The separate trailer control has identical chunk framing and no trailers. For replacement, B remains authorized with its own accepted read pending while A's late valid response is released. It must receive only its expected refusal through FIN, then its own fresh successful read. The subsequent IAM denial is a withdrawal control.
The final case selects a protected read that explicitly requires no provider credential. It joins the no-material access and send decisions to the acknowledged dispatch, the credential-free request at the origin and the repository identity returned to the Agent. It then withdraws authority while the recipient is live and verifies final route retirement.
Require the ordinary curl and Node workload reads, observed direct TCP attempt, and
specific dispatch acknowledgment loss and API restart as well. The diagnostic
names the private .build/egress-connected/runtime-<uuid>/ directory. Retain its
observations.json through cleanup and upstream.json with the result. The
post-restart read is a new positive control, never a replay of the uncertain
dispatch. Stop the owned observer and forwarding, then remove the disposable
installation. Reconcile any unknown resource from its ledger without replay.
