Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
e9ac0ee
chore(deps): bump actions/checkout from 7.0.0 to 7.0.1 (#2381)
dependabot[bot] Jul 21, 2026
744a65d
fix(driver-podman): avoid panic when HOME is unset on macOS (#2327)
mesutoezdil Jul 21, 2026
3ff15a1
fix(ci): fix mirror SHA detection in e2e-label-help workflow (#2236)
rhuss Jul 21, 2026
dae9261
docs(agents): keep project skills synchronized (#2349)
pimlock Jul 21, 2026
472e23f
fix(proxy): include OPA deny reason in CONNECT 403 response (#2363)
zanetworker Jul 21, 2026
bdd1ce8
fix(cli): respect CARGO_TARGET_DIR in openshell wrapper script (#2391)
jhjaggars Jul 21, 2026
396a3b7
docs(brand): add OpenShell brand assets (#2398)
drew Jul 21, 2026
d35d52d
fix(dco): Fix mismatched wording that breaks initial DCO checks (#2399)
matthewgrossman Jul 21, 2026
8b0e54b
docs(extensibility): add gateway interceptor guide (#2397)
drew Jul 21, 2026
2d5652b
docs(docker-compose): replace removed OpenClaw community sandbox with…
Schimuneck Jul 22, 2026
ac3d5c9
docs(prover): correct prove() exit code doc comment (#2395)
eviehoward Jul 22, 2026
cbdeb4d
fix(server): prevent unrelated sandbox deletes from blocking deletion…
pimlock Jul 22, 2026
fd1d3de
fix(e2e): detect gateway workload for health port-forward (#2400)
krishicks Jul 22, 2026
5432d01
feat(tui): add config key support to provider create/update forms (#2…
letv1nnn Jul 22, 2026
ca31805
fix(vm): reduce registry rootfs staging pressure (#2425)
pimlock Jul 22, 2026
cd9a0bf
fix(driver-k8s): add label selector to sandbox watch stream and list …
rhuss Jul 22, 2026
7b444bd
fix(agents): make baked payload readable (#2419)
elezar Jul 22, 2026
0674a00
refactor(cli): extract shared helpers into commands/common module (#2…
varshaprasad96 Jul 22, 2026
8a14b3a
fix(sandbox): skip read-only mounts during recursive chown of /sandbo…
varshaprasad96 Jul 22, 2026
541b97f
fix(mise): initialize Python dependencies in fresh worktrees (#2429)
matthewgrossman Jul 22, 2026
1d4ac70
fix(policy): keep internal allowed IP proposals pending (#2416)
alangou Jul 23, 2026
75d2468
fix(examples): add missing workspace fields to governance interceptor…
pavelanni Jul 23, 2026
59f7839
fix(auth): report gateway authentication status (#2435)
drew Jul 23, 2026
21da343
refactor(supervisor): pass agent proposal state explicitly (#2421)
elezar Jul 24, 2026
f7cd910
fix: eliminate parallel Rust test flakes (#2434)
pimlock Jul 24, 2026
b422b67
feat(cli): add --output json/yaml to sandbox get, status, and sandbox…
rhuss Jul 24, 2026
850bd42
refactor(tui): default create form state (#2458)
elezar Jul 24, 2026
77e5c32
feat(sandbox,gateway): route sandbox egress through corporate HTTP pr…
feloy Jul 24, 2026
01daf3a
chore(deps): bump astral-sh/setup-uv from 8.3.2 to 9.0.0 (#2440)
dependabot[bot] Jul 24, 2026
deced87
refactor(policy): extract shared L7 endpoint validation (#2389)
gracesmith6504 Jul 24, 2026
1a984c5
Merge remote-tracking branch 'upstream/main' into chore/force-sync-up…
ashsolei Jul 24, 2026
d9f46d9
chore: re-apply iAiFy overlay after upstream force-sync
ashsolei Jul 24, 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
76 changes: 66 additions & 10 deletions .agents/skills/debug-openshell-cluster/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
---
name: debug-openshell-cluster
description: Debug why an OpenShell gateway deployment is unhealthy, unreachable, or unable to create sandboxes. Use when the user has a gateway health failure, Docker/Podman runtime issue, Helm install failure, Kubernetes scheduling issue, TLS secret issue, VM driver issue, or sandbox startup problem. Trigger keywords - debug gateway, gateway failing, deployment failing, helm install failing, cluster health, gateway health, gateway not starting, health check failed, sandbox pending, docker driver, podman driver, vm driver.
description: Debug why an OpenShell gateway deployment is unhealthy, unreachable, or unable to create sandboxes. Use for gateway health failures, Docker/Podman runtime issues, Helm failures, Kubernetes scheduling, TLS or auth, gateway interceptors, supervisor middleware startup or runtime failures, external compute-driver sockets, VM drivers, or sandbox startup. Trigger keywords - debug gateway, gateway failing, deployment failing, helm install failing, cluster health, gateway health, gateway not starting, health check failed, sandbox pending, docker driver, podman driver, kubernetes driver, external driver, compute driver socket, gateway interceptor, supervisor middleware, middleware failed, vm driver.
---

# Debug OpenShell Gateway Deployment

Diagnose a gateway and its selected compute platform. Do not assume OpenShell provisions Kubernetes or runs a k3s container. OpenShell targets a reachable gateway endpoint backed by Docker, Podman, Kubernetes, or the experimental VM driver.
Diagnose a gateway and its selected compute platform. Do not assume OpenShell provisions Kubernetes or runs a k3s container. OpenShell targets a reachable gateway endpoint backed by Docker, Podman, Kubernetes, the experimental VM driver, or an operator-managed out-of-tree compute driver.

Use `openshell` first to identify the active endpoint. Then use the platform tools that match the gateway's compute driver: `docker`, `podman`, `kubectl`/`helm`, or VM driver logs.

Expand All @@ -15,7 +15,7 @@ The target deployment flow is:

1. Operator starts or deploys the gateway with system packages, systemd, Helm, or a development task. The CLI does not start, stop, or destroy gateway services.
2. Operator configures the compute driver.
3. Operator provides TLS and SSH relay material for the deployment mode.
3. Operator provides the CLI and supervisor authentication material required by the deployment mode: edge or OIDC user auth, optional CLI mTLS, and gateway-minted sandbox JWTs.
4. The CLI registers a reachable gateway endpoint with `openshell gateway add`.
5. The gateway creates sandboxes through the selected compute driver.

Expand All @@ -25,7 +25,7 @@ For local evaluation only, TLS may be disabled and the gateway can be reached th

- The `openshell` CLI must be available for endpoint checks.
- Know the active gateway name and endpoint, or be able to inspect local gateway metadata.
- Know the compute platform: Docker, Podman, Kubernetes, or VM.
- Know the compute platform: Docker, Podman, Kubernetes, VM, or an out-of-tree driver.
- For Kubernetes: `kubectl` must target the cluster that hosts OpenShell and Helm version 3 or later must be available.
- For Docker or Podman: the runtime socket must be reachable from the gateway host.

Expand All @@ -36,15 +36,24 @@ Run diagnostics in order and stop once the root cause is clear.
### Step 1: Check CLI Reachability

```bash
openshell gateway list --output json
openshell gateway info
openshell status
```

For a one-off endpoint check that bypasses stored gateway selection and metadata:

```bash
openshell --gateway-endpoint <url> status
```

Common findings:

- `No active gateway`: register one with `openshell gateway add <endpoint>`.
- Connection refused: gateway process is not running, service exposure is wrong, or a port-forward/proxy is not active.
- TLS/certificate errors: CLI mTLS bundle does not match the gateway CA, or the gateway is running with unexpected TLS settings.
- TLS/certificate errors: the endpoint scheme or trust chain is wrong, a local mTLS bundle does not match the gateway CA, or TLS termination does not match the gateway listener.
- `Unauthenticated` from an edge or OIDC gateway: refresh stored credentials with `openshell gateway login [name]`, then retry. Use `gateway logout` only when intentionally clearing local credentials.
- A direct development endpoint with a private or self-signed certificate can be isolated with `--gateway-endpoint <url> --gateway-insecure`; do not persist or recommend insecure verification for shared gateways.

### Step 2: Identify the Compute Platform

Expand All @@ -56,8 +65,48 @@ Use gateway metadata, deployment values, or the user's setup notes to identify t
| Podman | Podman socket, rootless networking, sandbox containers, image pulls. |
| Kubernetes | Helm release, gateway workload, service, secrets, sandbox pods, events. |
| VM | VM driver logs, rootfs availability, host virtualization support. |
| Extension | External driver process, Unix socket ownership/mode, configured driver name, capability handshake, gateway logs. |

### Step 3: Check Gateway Startup Dependencies

Before debugging the compute platform, inspect gateway logs for failures in dependencies initialized before the listener becomes ready.

For out-of-tree compute drivers, confirm the custom driver name and socket agree across CLI flags or `gateway.toml`, and that the operator-owned driver is running before the gateway starts:

```bash
rg -n 'compute_drivers|socket_path' /etc/openshell/gateway.toml
stat /run/openshell/<driver>.sock
journalctl -u <driver-service> --no-pager --lines=200
journalctl -u openshell-gateway --no-pager --lines=200
```

The custom driver name must not be a reserved built-in name (`docker`, `podman`, `kubernetes`, or `vm`). The socket must be accessible only to the intended gateway identity. Check gateway logs for connection errors, `GetCapabilities` failures, or an unexpected advertised driver name. The gateway does not create or supervise out-of-tree driver processes or sockets.

For configured gateway interceptors, inspect `[[openshell.gateway.interceptors]]`, their Unix or network endpoints, and gateway startup logs:

```bash
rg -n 'interceptors|provider_profile_sources|grpc_endpoint|binding_policy|failure_policy' /etc/openshell/gateway.toml
stat /run/openshell/interceptors/<name>.sock
journalctl -u <interceptor-service> --no-pager --lines=200
journalctl -u openshell-gateway --no-pager --lines=200
```

The gateway calls each interceptor's `Describe` RPC and validates its manifest at startup. Check for unreachable endpoints, invalid RPC/phase bindings, strict `allowlist` or `exact` mismatches, and `post_commit` bindings that resolve to `fail_closed`. If `provider_profile_sources` names an interceptor, that interceptor must advertise provider-profile capability and return a valid, duplicate-free catalog. A selected interceptor-only source is authoritative; include `builtin` or `user` sources explicitly when composition is intended.

For operator-run supervisor middleware, inspect `[[openshell.supervisor.middleware]]`, service reachability, and both gateway and supervisor logs:

```bash
rg -n 'supervisor|middleware|grpc_endpoint|max_body_bytes|timeout' /etc/openshell/gateway.toml
journalctl -u <middleware-service> --no-pager --lines=200
journalctl -u openshell-gateway --no-pager --lines=200
openshell logs <sandbox-name> --tail --source sandbox
```

The middleware service must start before the gateway and be reachable from both the gateway and sandbox supervisors. Gateway startup fails if `Describe` is unavailable, a manifest exposes duplicate `HttpRequest/pre_credentials` bindings, the registration claims the reserved `openshell/` namespace, or body and timeout limits are invalid. Changing a registration requires a gateway restart. A policy update can also fail before persistence if the selected implementation rejects its `network_middlewares` config.

At request time, distinguish an explicit `middleware_denied` result from `middleware_failed`. A denial is always enforced. A failure follows the policy-local `on_error`: `fail_closed` blocks the request, while `fail_open` bypasses only that stage and emits a detection finding. If a running supervisor cannot install a new registry, it preserves its last-known-good generation and emits a configuration failure event.

### Step 3: Check Docker-Backed Gateways
### Step 4: Check Docker-Backed Gateways

```bash
docker info
Expand Down Expand Up @@ -110,7 +159,7 @@ For source checkout development, restart the local gateway with:
mise run gateway:docker
```

### Step 4: Check Podman-Backed Gateways
### Step 5: Check Podman-Backed Gateways

```bash
podman info
Expand All @@ -126,7 +175,7 @@ Common findings:
- Sandbox image missing or pull denied: verify image reference and registry credentials.
- Supervisor cannot call back: check callback endpoint and gateway logs.

### Step 5: Check Kubernetes Helm Gateways
### Step 6: Check Kubernetes Helm Gateways

```bash
helm -n openshell status openshell
Expand Down Expand Up @@ -319,7 +368,7 @@ kubectl -n <sandbox-namespace> logs <sandbox-pod> -c openshell-supervisor-networ
kubectl -n <sandbox-namespace> logs <sandbox-pod> -c agent --tail=200
```

### Step 6: Check VM-Backed Gateways
### Step 7: Check VM-Backed Gateways

Use the VM driver logs and host diagnostics available in the user's environment. Verify:

Expand All @@ -346,6 +395,13 @@ openshell logs <sandbox-name>
| Kubernetes gateway pod pending | PVC unbound, taint, selector, or insufficient resources | `kubectl -n openshell describe pod <pod>` |
| Kubernetes gateway pod crash loops | Missing secret, bad DB URL, bad TLS config | `kubectl -n openshell logs deployment/openshell -c openshell-gateway` or `kubectl -n openshell logs statefulset/openshell -c openshell-gateway` |
| CLI TLS error | Local mTLS bundle does not match server cert/CA | Check `~/.config/openshell/gateways/<name>/mtls/` |
| Edge or OIDC gateway returns `Unauthenticated` | Stored login expired, audience/scopes mismatch, or gateway auth configuration changed | `openshell gateway info`, `openshell gateway login <name>`, gateway auth logs |
| Gateway fails before serving health after enabling an interceptor | Interceptor endpoint unavailable or manifest/binding validation failed | Gateway and interceptor logs; interceptor socket; `binding_policy`, phases, and failure policy |
| Provider profiles disappear after enabling an interceptor catalog | `provider_profile_sources` selected only an authoritative interceptor or returned invalid/duplicate IDs | Inspect source list and interceptor `Describe`/catalog logs; include `builtin` and `user` when intended |
| Gateway fails after registering supervisor middleware | Service unavailable, invalid manifest, duplicate binding, reserved name, or invalid body/timeout limit | Middleware service and gateway logs; `[[openshell.supervisor.middleware]]`; `Describe` response |
| Policy update rejects `network_middlewares` | Unknown middleware name, implementation-owned config invalid, duplicate order, broad/invalid host selector, or fail-closed coverage of `tls: skip` | Policy error, gateway logs, middleware `ValidateConfig`, selector and order fields |
| HTTP request returns `middleware_failed` or `middleware_denied` | Selected stage failed or explicitly denied the admitted request | Sandbox OCSF logs; policy-local middleware config; service availability; `on_error` |
| Custom compute driver is unavailable | Driver process/socket missing, inaccessible, or configured with a reserved/mismatched name | Socket ownership/mode, driver service logs, gateway `GetCapabilities` logs |
| Image pull failure | Gateway or sandbox image cannot be pulled | Runtime events and image pull credentials |
| `K8s namespace not ready` with `envoy-gateway-openshell.yaml: the server could not find the requested resource` | Optional Gateway API manifest was applied without Envoy Gateway CRDs, or k3s Helm controller startup exceeded the namespace wait | Apply `deploy/kube/manifests/envoy-gateway-openshell.yaml` manually only after Envoy Gateway is installed and `grpcRoute` is enabled |
| HTTPS ingress (`grpcRoute.gateway.listener.protocol=HTTPS`) connection resets or TLS handshake hangs | Envoy terminates TLS but the gateway pod still expects TLS, so the plaintext backend hop fails | Set `server.disableTls=true` so Envoy forwards plaintext to the pod; verify the listener `certificateRefs` Secret exists in the release namespace and `openshell status` over `https://<host>` |
Expand All @@ -359,7 +415,7 @@ When handing results back to the user, include:
- Compute platform and driver.
- Gateway process or workload status.
- Recent gateway log summary.
- Missing or malformed TLS or SSH relay material.
- Missing or malformed TLS, OIDC/mTLS, or sandbox JWT material.
- Service exposure status.
- Sandbox workload status.
- The exact command that failed and the shortest fix.
20 changes: 10 additions & 10 deletions .agents/skills/launch-openshell-gator/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,11 +123,11 @@ pr_number="<digits-only>"
[[ "$pr_number" =~ ^[0-9]+$ ]] || { echo "invalid PR number" >&2; exit 1; }
```

Use a restricted sandbox-name character set:
Use the portable Kubernetes DNS-1123 sandbox-name format even when the selected gateway currently uses another driver:

```bash
sandbox_name="gator-pr-${pr_number}-supervised"
[[ "$sandbox_name" =~ ^[A-Za-z0-9_.-]+$ ]] || { echo "invalid sandbox name" >&2; exit 1; }
[[ "$sandbox_name" =~ ^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$ ]] || { echo "invalid sandbox name" >&2; exit 1; }
```

For local image contexts passed to `--from`, use an agent-created path such as `mktemp -d`; do not pass raw user-supplied paths without validating that they are expected local Dockerfile contexts.
Expand All @@ -144,7 +144,7 @@ pr_number="<digits-only>"
[[ "$gateway_name" =~ ^[A-Za-z0-9_.-]+$ ]] || { echo "invalid gateway name" >&2; exit 1; }
[[ "$pr_number" =~ ^[0-9]+$ ]] || { echo "invalid PR number" >&2; exit 1; }
sandbox_name="gator-pr-${pr_number}-supervised"
[[ "$sandbox_name" =~ ^[A-Za-z0-9_.-]+$ ]] || { echo "invalid sandbox name" >&2; exit 1; }
[[ "$sandbox_name" =~ ^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$ ]] || { echo "invalid sandbox name" >&2; exit 1; }

./scripts/agents/run.sh \
--agent gator \
Expand All @@ -165,7 +165,7 @@ issue_number="<digits-only>"
[[ "$gateway_name" =~ ^[A-Za-z0-9_.-]+$ ]] || { echo "invalid gateway name" >&2; exit 1; }
[[ "$issue_number" =~ ^[0-9]+$ ]] || { echo "invalid issue number" >&2; exit 1; }
sandbox_name="gator-issue-${issue_number}-supervised"
[[ "$sandbox_name" =~ ^[A-Za-z0-9_.-]+$ ]] || { echo "invalid sandbox name" >&2; exit 1; }
[[ "$sandbox_name" =~ ^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$ ]] || { echo "invalid sandbox name" >&2; exit 1; }

./scripts/agents/run.sh \
--agent gator \
Expand All @@ -186,7 +186,7 @@ issue_number="<digits-only>"
[[ "$pr_number" =~ ^[0-9]+$ ]] || { echo "invalid PR number" >&2; exit 1; }
[[ "$issue_number" =~ ^[0-9]+$ ]] || { echo "invalid issue number" >&2; exit 1; }
sandbox_name="gator-pr-${pr_number}-supervised"
[[ "$sandbox_name" =~ ^[A-Za-z0-9_.-]+$ ]] || { echo "invalid sandbox name" >&2; exit 1; }
[[ "$sandbox_name" =~ ^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$ ]] || { echo "invalid sandbox name" >&2; exit 1; }

./scripts/agents/run.sh \
--agent gator \
Expand All @@ -207,7 +207,7 @@ pr_number="<digits-only>"
[[ "$gateway_name" =~ ^[A-Za-z0-9_.-]+$ ]] || { echo "invalid gateway name" >&2; exit 1; }
[[ "$pr_number" =~ ^[0-9]+$ ]] || { echo "invalid PR number" >&2; exit 1; }
sandbox_name="gator-pr-${pr_number}-supervised"
[[ "$sandbox_name" =~ ^[A-Za-z0-9_.-]+$ ]] || { echo "invalid sandbox name" >&2; exit 1; }
[[ "$sandbox_name" =~ ^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$ ]] || { echo "invalid sandbox name" >&2; exit 1; }

./scripts/agents/run.sh \
--agent gator \
Expand All @@ -228,7 +228,7 @@ pr_number="<digits-only>"
[[ "$gateway_name" =~ ^[A-Za-z0-9_.-]+$ ]] || { echo "invalid gateway name" >&2; exit 1; }
[[ "$pr_number" =~ ^[0-9]+$ ]] || { echo "invalid PR number" >&2; exit 1; }
sandbox_name="gator-pr-${pr_number}-gpt56sol-supervised"
[[ "$sandbox_name" =~ ^[A-Za-z0-9_.-]+$ ]] || { echo "invalid sandbox name" >&2; exit 1; }
[[ "$sandbox_name" =~ ^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$ ]] || { echo "invalid sandbox name" >&2; exit 1; }

CODEX_MODEL=gpt-5.6-sol \
./scripts/agents/run.sh \
Expand All @@ -250,7 +250,7 @@ pr_number="<digits-only>"
[[ "$gateway_name" =~ ^[A-Za-z0-9_.-]+$ ]] || { echo "invalid gateway name" >&2; exit 1; }
[[ "$pr_number" =~ ^[0-9]+$ ]] || { echo "invalid PR number" >&2; exit 1; }
sandbox_name="gator-pr-${pr_number}-gpt56sol-supervised"
[[ "$sandbox_name" =~ ^[A-Za-z0-9_.-]+$ ]] || { echo "invalid sandbox name" >&2; exit 1; }
[[ "$sandbox_name" =~ ^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$ ]] || { echo "invalid sandbox name" >&2; exit 1; }
tmp_context="$(mktemp -d "${TMPDIR:-/tmp}/gator-codex-XXXXXX")"
cp -R scripts/agents/gator/. "$tmp_context"/

Expand Down Expand Up @@ -290,7 +290,7 @@ Read that file directly. Important markers:
gateway_name="<selected-gateway-name>"
sandbox_name="<safe-sandbox-name>"
[[ "$gateway_name" =~ ^[A-Za-z0-9_.-]+$ ]] || { echo "invalid gateway name" >&2; exit 1; }
[[ "$sandbox_name" =~ ^[A-Za-z0-9_.-]+$ ]] || { echo "invalid sandbox name" >&2; exit 1; }
[[ "$sandbox_name" =~ ^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$ ]] || { echo "invalid sandbox name" >&2; exit 1; }

openshell --gateway "$gateway_name" sandbox list
openshell --gateway "$gateway_name" sandbox get "$sandbox_name"
Expand Down Expand Up @@ -318,7 +318,7 @@ Before deleting, check that the sandbox is truly stale or that the operator aske
gateway_name="<selected-gateway-name>"
sandbox_name="<safe-sandbox-name>"
[[ "$gateway_name" =~ ^[A-Za-z0-9_.-]+$ ]] || { echo "invalid gateway name" >&2; exit 1; }
[[ "$sandbox_name" =~ ^[A-Za-z0-9_.-]+$ ]] || { echo "invalid sandbox name" >&2; exit 1; }
[[ "$sandbox_name" =~ ^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$ ]] || { echo "invalid sandbox name" >&2; exit 1; }

openshell --gateway "$gateway_name" sandbox delete "$sandbox_name"
./scripts/agents/run.sh \
Expand Down
1 change: 1 addition & 0 deletions .claude/agents/principal-engineer-reviewer.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ When reviewing code or diffs:
5. Reference specific files and line numbers (`file_path:line_number`).
6. When suggesting a change, show the concrete fix — don't just describe it.
7. If something is good, say so briefly. Positive signal is useful too.
8. When behavior, commands, or development workflows change, consult the `sync-agent-infra` maintenance map and verify that related skills were updated. Apply its full consistency checklist when the changes add, remove, or rename skills or crates; change workflow relationships or skill coverage; modify issue or PR templates; or change agent cross-references. Report missing companion updates or drift as a warning.

When reviewing plans or architecture documents:

Expand Down
Loading
Loading