Skip to content

feat: add the isolated single-stack launcher - #64

Merged
eXPerience83 merged 48 commits into
mainfrom
feat/single-stack-launcher
Aug 1, 2026
Merged

feat: add the isolated single-stack launcher#64
eXPerience83 merged 48 commits into
mainfrom
feat/single-stack-launcher

Conversation

@eXPerience83

@eXPerience83 eXPerience83 commented Aug 1, 2026

Copy link
Copy Markdown
Owner

What changed

  • implements the fixed REMOTE_DEV_ROLE=launcher role in the canonical runtime;
  • adds a project-owned Python standard-library launcher on primary port 7680;
  • keeps the independently authenticated Codex ttyd endpoint on port 7681;
  • starts launcher and Codex from the exact same REMOTE_DEV_IMAGE reference in generic and TrueNAS Compose;
  • navigates the browser to Codex without reverse-proxying or relaying terminal HTTP/WebSocket traffic;
  • uses separate launcher and Codex password secrets and separate insecure-web overrides;
  • keeps the launcher free of workspace, Codex, GitHub, Git, SSH and container-socket mounts;
  • preserves the existing Codex service name, container name, CODEX_DATA_ROOT and persistent paths;
  • changes the TrueNAS portal to the launcher while retaining the direct Codex port;
  • adds role-aware diagnostics and health checks;
  • updates English/Spanish usage, architecture, security, release and agent instructions.

Launcher security boundary

The launcher:

  • reads its root-readable launcher secret and then clears supplementary groups and permanently drops to UID/GID 65532 before binding or serving;
  • serves a fixed page for the built-in Codex service only;
  • requires Basic authentication unless the launcher-specific explicit insecure override is enabled;
  • validates DNS names/IP literals, rejects an embedded destination port, and restricts paths to safe RFC 3986 URL-path characters;
  • checks a supplied Origin against the request host;
  • sends a nonce-based restrictive CSP, no-store and anti-framing headers;
  • accepts only GET/HEAD and exposes an unauthenticated, secret-free health endpoint;
  • never embeds, forwards or mounts the Codex terminal password;
  • never receives agent state or a Docker/Podman socket.

The second browser authentication challenge at the Codex endpoint is intentional. This PR does not introduce a trusted terminal proxy.

Validation

  • launcher role/start-mode resolution and state-boundary tests;
  • launcher authentication, malformed/non-ASCII credentials, origin rejection, CSP, method restrictions, privilege drop and unsafe-route rejection;
  • deterministic Compose topology checks for exactly launcher and codex;
  • same canonical image reference for both services;
  • exactly one independent password source per service;
  • independent launcher/Codex insecure-web overrides;
  • absence of agent paths, agent variables, Docker/Podman sockets, privileged mode and added capabilities from the launcher;
  • role-aware health checks and launcher-safe diagnostics;
  • runtime smoke test proving launcher and Codex containers reuse one image ID and the launcher test container has no mounts;
  • all existing Codex policy, start/resume, ttyd, tmux, notices, SBOM, Trivy and fixable-critical checks.

Deliberately out of scope

No reverse proxy, one-origin transport, CODEX_DATA_ROOT migration, neutral persistent-data layout, Antigravity, Claude Code, Context7, outer-container hardening or cross-service canaries.

Part of #25. Real TrueNAS browser navigation and exact-digest evidence remain manual gates before this slice is considered validated in the target environment.

@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@eXPerience83, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 29 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 9ec9c907-cd6f-45af-8ba3-1ef33884b20e

📥 Commits

Reviewing files that changed from the base of the PR and between f25e913 and 7f4cc5e.

📒 Files selected for processing (10)
  • .env.example
  • compose/docker-compose.yml
  • compose/truenas.yml
  • docs/architecture.md
  • docs/security.md
  • scripts/remote-dev-healthcheck.sh
  • scripts/remote-dev-launcher.py
  • scripts/runtime-smoke-test.sh
  • scripts/test-remote-dev-launcher.sh
  • scripts/test_single_stack_compose.py

Summary by CodeRabbit

  • New Features
    • Added an authenticated Remote Dev Launcher on port 7680 with navigation to the Codex terminal on port 7681.
    • Added independent credentials, origin validation, security headers, and configurable endpoint settings.
    • Added role-aware diagnostics and health checks for launcher, Codex, and shell services.
  • Security
    • Isolated launcher state and mounts from Codex workspace data.
    • Restricted launcher behavior and documented exposure, authentication, and isolation requirements.
  • Documentation
    • Updated setup, architecture, release, security, and Spanish documentation for the new deployment model.
  • Validation
    • Expanded automated checks for authentication, routing, health, isolation, and Compose configuration.

Walkthrough

The PR adds an authenticated Remote Dev launcher beside the Codex terminal. Both services use one image with separate credentials and state. Runtime roles, health checks, Compose topology, security controls, documentation, and automated validation are updated.

Changes

Remote Dev launcher stack

Layer / File(s) Summary
Launcher runtime and security
scripts/remote-dev-launcher.py, scripts/remote-dev-healthcheck.sh, scripts/start-remote-dev-web.sh, images/codex/Dockerfile, scripts/test-remote-dev-launcher.sh, scripts/runtime-smoke-test.sh, .env.example
Adds the launcher HTTP server, authentication, origin checks, CSP, routing, health handling, configuration validation, and isolated runtime smoke coverage.
Shared Compose topology and validation
compose/*, scripts/test_single_stack_compose.py, scripts/test-compose-image-compat.sh, .coderabbit.yaml
Adds launcher services to both Compose stacks, shares one image with Codex, separates secrets and mounts, and validates topology, privileges, ports, and image identity.
Role-aware runtime and diagnostics
scripts/lib/remote-dev-runtime.sh, scripts/remote-dev-doctor.sh, scripts/test-role-neutral-runtime.sh
Adds launcher role and menu-only constraints, prevents tmux use, and separates launcher diagnostics and state checks from agent checks.
Build and validation wiring
.github/workflows/build-amd64.yml, Makefile
Adds Python compilation and launcher and Compose validation to workflow and local validation targets.
Architecture, security, and release documentation
AGENTS.md, README*, docs/*, CHANGELOG.md, PROJECT_STATUS.md
Documents the two-service architecture, authentication boundaries, state isolation, exposure rules, runtime roles, deployment checks, and current limitations.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related issues

Possibly related PRs

Sequence Diagram(s)

sequenceDiagram
  participant Browser
  participant RemoteDevLauncher
  participant CodexTTYD
  Browser->>RemoteDevLauncher: Authenticate and request launcher page
  RemoteDevLauncher-->>Browser: Return validated Codex endpoint link
  Browser->>CodexTTYD: Authenticate and open terminal
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the primary change: an isolated single-stack launcher.
Description check ✅ Passed The description is detailed and covers the change, security boundary, validation, scope, and manual gates, but omits several template headings and checkboxes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/single-stack-launcher

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copy link
Copy Markdown
Owner Author

@codex review

Please review the exact head f25e9133ccb4689bf35be606dd016d8542cf0c88. Focus on the bounded launcher slice: authentication/origin/CSP and safe route construction, strict separation of launcher and Codex password secrets/state, same-image two-service Compose topology, role-aware startup/health checks, and preservation of existing Codex behavior. Do not broaden this into a reverse proxy, data migration, optional agents or outer-hardening work.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f25e9133cc

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/remote-dev-launcher.py Outdated

Copy link
Copy Markdown
Owner Author

@codex review

Please review the updated exact head 9fe32dc5a2705f2738a0b8bdbb834251974cae85. The follow-up hardens malformed/non-ASCII Basic credentials and Origin/Host comparison, adds bounded socket timeouts, and keeps the existing launcher scope unchanged.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 9

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.env.example:
- Around line 26-29: Rename the documented environment variables in the
`.env.example` block from REMOTE_DEV_CODEX_PUBLIC_HOST and
REMOTE_DEV_CODEX_PUBLIC_SCHEME to REMOTE_DEV_LAUNCHER_CODEX_HOST and
REMOTE_DEV_LAUNCHER_CODEX_SCHEME, preserving their existing comments and empty
defaults.

In `@compose/docker-compose.yml`:
- Line 21: Update the launcher service’s ALLOW_INSECURE_WEB configuration to use
a LAUNCHER_-prefixed environment variable, separating it from the Codex
service’s override while preserving the existing default value and
launcher-specific setting pattern.
- Line 8: Update the launcher service definition in docker-compose.yml to run
with an explicit non-root user instead of user "0:0"; choose a service-specific
unprivileged UID/GID compatible with the image and preserve the launcher’s
access to its secret and Python HTTP server.

In `@compose/truenas.yml`:
- Line 37: Rename the host-side secret source in the TrueNAS compose mount from
web_password.txt to launcher_password.txt, while preserving the
/run/secrets/launcher_password destination and read-only mode. Update all
English and Spanish deployment documentation references to use the new
launcher_password.txt path.

In `@docs/architecture.md`:
- Around line 146-156: The TrueNAS launcher secret filename differs from the
compose-mounted secret and local configuration. Align the launcher secret path
in the architecture documentation with the filename used by the compose mount
and local config, while preserving the existing Codex secret path.

In `@docs/security.md`:
- Line 24: Update the `/healthz` descriptions to use accurate network-scope
wording: in docs/security.md lines 24-24, describe it as an unauthenticated,
secret-free health endpoint; in docs/architecture.md lines 107-107, remove
“local” from the healthcheck description.

In `@scripts/test_single_stack_compose.py`:
- Around line 135-153: Update the credential validation around the top-level
secrets and bind-mount checks to require exactly one launcher credential source
and exactly one Codex credential source. Ensure each service has either its
corresponding top-level secret or password bind mount, reject missing sources
and multiple sources, and retain the existing checks that the launcher and Codex
sources are independent.
- Around line 18-31: Update FORBIDDEN_LAUNCHER_TEXT to also reject the socket
path without the /var prefix and Podman socket mount paths, ensuring all valid
Docker/Podman socket spellings are covered; you may use a broader docker.sock
entry if preferred.
- Around line 34-37: Update compose_config so docker compose config receives a
minimal, explicitly constructed environment rather than os.environ.copy(), while
preserving only the variables required for Compose invocation and committed
defaults. Ensure exported values such as LAUNCHER_BASE_PATH, LAUNCHER_USERNAME,
and WEB_BASE_PATH cannot alter rendering, so the existing topology assertions
deterministically validate image references, roles, launcher isolation, Docker
access restrictions, and Codex compatibility.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 07b497b2-ab76-4541-9bee-32910227d379

📥 Commits

Reviewing files that changed from the base of the PR and between 18b1d6d and f25e913.

📒 Files selected for processing (25)
  • .coderabbit.yaml
  • .env.example
  • .github/workflows/build-amd64.yml
  • AGENTS.md
  • CHANGELOG.md
  • Makefile
  • PROJECT_STATUS.md
  • README.es.md
  • README.md
  • compose/docker-compose.yml
  • compose/truenas.yml
  • docs/architecture.md
  • docs/releases.md
  • docs/security.md
  • images/codex/Dockerfile
  • scripts/lib/remote-dev-runtime.sh
  • scripts/remote-dev-doctor.sh
  • scripts/remote-dev-healthcheck.sh
  • scripts/remote-dev-launcher.py
  • scripts/runtime-smoke-test.sh
  • scripts/start-remote-dev-web.sh
  • scripts/test-compose-image-compat.sh
  • scripts/test-remote-dev-launcher.sh
  • scripts/test-role-neutral-runtime.sh
  • scripts/test_single_stack_compose.py
📜 Review details
⏰ Context from checks skipped due to timeout. (1)
  • GitHub Check: build
🧰 Additional context used
📓 Path-based instructions (7)
.github/workflows/**

⚙️ CodeRabbit configuration file

.github/workflows/**: Review GitHub Actions for least-privilege permissions, safe event triggers, untrusted input handling,
accidental publication, tag-channel correctness, secret exposure, reproducible builds, SBOM/provenance
generation and appropriate validation before pushing images.

Files:

  • .github/workflows/build-amd64.yml
**/*

📄 CodeRabbit inference engine (AGENTS.md)

**/*: Before changing runtime architecture or support claims, read the current GitHub issues listed as sources of truth; report discrepancies between issues and repository code before expanding scope.
Work on a branch and open a pull request; never push implementation changes directly to main. Keep one focused objective per PR and obtain approval before adding a subsystem or changing the agreed PR boundary.
Do not build universal Dockerfile, shell, package-manager, license, or static-analysis parsers; prefer explicit mappings and bounded validators for known repository inputs.
Do not introduce speculative support for Antigravity or Claude Code. Missing optional roles must remain unavailable and must never download silently.
Do not change unrelated dependency pins, generated legal evidence, image names, Compose layouts, or persistent mounts unless explicitly included in the issue and PR.
Preserve compatibility wrappers until their documented and reviewed removal point.
A PR is merge-ready only when the exact final head has the required build check green, review findings are evaluated and fixed, conversations are resolved, and the branch is up to date with main; use squash merge.
Never use privileged containers, Docker or Podman sockets, SYS_ADMIN, host-root mounts, or broad /root, /home, /opt, /usr/local, or parent data-root persistence.
Do not share writable agent credentials, GitHub CLI state, Git configuration, SSH state, caches, histories, or workspaces between role services.
Do not give the launcher access to agent credentials or workspaces.
Never expose secret values in diagnostics, logs, tests, issues, or pull-request descriptions.
Treat the supported TrueNAS isolation boundary as the outer container. Approval prompts are not a sandbox or isolation boundary, and Bubblewrap, Landlock, or another inner sandbox must not be claimed active without a positive runtime test proving it.
Keep product-specific variables such as CODEX_HOME inside the C...

Files:

  • scripts/start-remote-dev-web.sh
  • scripts/remote-dev-healthcheck.sh
  • scripts/test-role-neutral-runtime.sh
  • scripts/test-compose-image-compat.sh
  • Makefile
  • scripts/runtime-smoke-test.sh
  • docs/security.md
  • compose/truenas.yml
  • AGENTS.md
  • compose/docker-compose.yml
  • scripts/lib/remote-dev-runtime.sh
  • scripts/remote-dev-doctor.sh
  • images/codex/Dockerfile
  • scripts/test_single_stack_compose.py
  • scripts/test-remote-dev-launcher.sh
  • docs/releases.md
  • CHANGELOG.md
  • README.es.md
  • README.md
  • PROJECT_STATUS.md
  • scripts/remote-dev-launcher.py
  • docs/architecture.md
**/*.{sh,bash}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{sh,bash}: Never use eval, sourced editable state, or user-controlled shell fragments for role, mode, installer, routing, or command dispatch.
Use fixed, validated enums for roles and start modes; reject unknown values with a deterministic non-zero exit status and a clear message.
Build command invocations with Bash arrays, preserve arguments without re-evaluating them, and preserve command exit status.

Files:

  • scripts/start-remote-dev-web.sh
  • scripts/remote-dev-healthcheck.sh
  • scripts/test-role-neutral-runtime.sh
  • scripts/test-compose-image-compat.sh
  • scripts/runtime-smoke-test.sh
  • scripts/lib/remote-dev-runtime.sh
  • scripts/remote-dev-doctor.sh
  • scripts/test-remote-dev-launcher.sh
scripts/**/*.sh

⚙️ CodeRabbit configuration file

scripts/**/*.sh: Review as production Bash. Check quoting, set -euo pipefail behavior, cleanup traps,
bounded retries and timeouts, non-interactive execution, idempotency and useful failure messages.
Flag commands that can hang, leak credentials, silently ignore failures or mutate persistent data unexpectedly.

Files:

  • scripts/start-remote-dev-web.sh
  • scripts/remote-dev-healthcheck.sh
  • scripts/test-role-neutral-runtime.sh
  • scripts/test-compose-image-compat.sh
  • scripts/runtime-smoke-test.sh
  • scripts/lib/remote-dev-runtime.sh
  • scripts/remote-dev-doctor.sh
  • scripts/test-remote-dev-launcher.sh
**/*.md

⚙️ CodeRabbit configuration file

**/*.md: Check that documentation matches the implemented behavior and clearly distinguishes experimental edge builds
from stable releases. Flag outdated versions, unsafe deployment guidance and claims not proven by CI or testing.

Files:

  • docs/security.md
  • AGENTS.md
  • docs/releases.md
  • CHANGELOG.md
  • README.es.md
  • README.md
  • PROJECT_STATUS.md
  • docs/architecture.md
compose/**

⚙️ CodeRabbit configuration file

compose/**: Review Docker Compose files for TrueNAS and generic Docker compatibility.
Flag privileged mode, host networking, Docker socket mounts, overly broad host mounts,
missing authentication, unsafe public bindings and persistence paths that could lose credentials or workspaces.

Files:

  • compose/truenas.yml
  • compose/docker-compose.yml
images/**/Dockerfile

⚙️ CodeRabbit configuration file

images/**/Dockerfile: Review for reproducibility, supply-chain security and minimal image growth.
Require pinned upstream versions and checksum or digest verification for downloaded binaries.
Flag secrets, floating base tags, unsafe remote-script execution, broken multi-architecture logic,
cache misuse, unnecessary packages and changes that weaken the secure-by-default runtime.

Files:

  • images/codex/Dockerfile
🪛 ast-grep (0.45.0)
scripts/runtime-smoke-test.sh

[warning] 8-8: A credential-bearing variable (e.g. PASSWORD, PASSWD, SECRET, TOKEN, API_KEY) is assigned a hardcoded string literal. Secrets committed to a script are exposed in source control, process listings, and shell history, and cannot be rotated without a code change. Read the value from a secrets manager or an injected environment variable at runtime instead (e.g. PASSWORD="${DB_PASSWORD:?must be set}"), and never commit the literal.
Context: launcher_secret='synthetic-launcher-secret'
Note: [CWE-798] Use of Hard-coded Credentials.

(hardcoded-password-assignment-bash)

scripts/test_single_stack_compose.py

[error] 37-55: Command coming from incoming request
Context: subprocess.run(
[
"docker",
"compose",
"--env-file",
str(env_file),
"-f",
str(path),
"config",
"--format",
"json",
],
cwd=ROOT,
env=env,
text=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
check=False,
)
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').

(subprocess-from-request)


[info] 127-127: use jsonify instead of json.dumps for JSON output
Context: json.dumps(launcher, sort_keys=True)
Note: [CWE-116] Improper Encoding or Escaping of Output.

(use-jsonify)

scripts/test-remote-dev-launcher.sh

[warning] 15-15: A credential-bearing variable (e.g. PASSWORD, PASSWD, SECRET, TOKEN, API_KEY) is assigned a hardcoded string literal. Secrets committed to a script are exposed in source control, process listings, and shell history, and cannot be rotated without a code change. Read the value from a secrets manager or an injected environment variable at runtime instead (e.g. PASSWORD="${DB_PASSWORD:?must be set}"), and never commit the literal.
Context: secret='synthetic-launcher-secret'
Note: [CWE-798] Use of Hard-coded Credentials.

(hardcoded-password-assignment-bash)

scripts/remote-dev-launcher.py

[info] 167-175: use jsonify instead of json.dumps for JSON output
Context: json.dumps(
{
"host": config.codex_host,
"port": config.codex_port,
"scheme": config.codex_scheme,
"path": config.codex_path,
},
separators=(",", ":"),
)
Note: [CWE-116] Improper Encoding or Escaping of Output.

(use-jsonify)

🪛 Betterleaks (1.7.0)
scripts/test-remote-dev-launcher.sh

[high] 65-66: Discovered a potential basic authorization token provided in a curl command, which could compromise the curl accessed resource.

(curl-auth-user)

🪛 dotenv-linter (4.0.0)
.env.example

[warning] 5-5: [UnorderedKey] The LAUNCHER_PASSWORD_PATH key should go before the REMOTE_DEV_IMAGE key

(UnorderedKey)


[warning] 11-11: [UnorderedKey] The LAUNCHER_BASE_PATH key should go before the LAUNCHER_PUBLISH_IP key

(UnorderedKey)


[warning] 13-13: [UnorderedKey] The LAUNCHER_CHECK_ORIGIN key should go before the LAUNCHER_PUBLISH_IP key

(UnorderedKey)

🪛 LanguageTool
docs/security.md

[style] ~48-~48: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...- Never mount /var/run/docker.sock. - Never use privileged: true, host PID, or ho...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

CHANGELOG.md

[style] ~68-~68: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...gacy package tags without rebuilding. - Changed the normal TrueNAS x-portal entry from ...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[style] ~69-~69: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...enticated Codex port and data layout. - Changed the image healthcheck from Codex-specif...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

README.md

[style] ~224-~224: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...er. - Do not mount the Docker socket. - Do not use privileged mode. - The default ...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

🪛 Ruff (0.16.0)
scripts/test_single_stack_compose.py

[warning] 38-56: Prefer capture_output over sending stdout and stderr to PIPE

Replace with capture_output keyword argument

(UP022)


[error] 38-38: subprocess call: check for execution of untrusted input

(S603)


[error] 39-49: Starting a process with a partial executable path

(S607)


[warning] 58-60: Avoid specifying long messages outside the exception class

(TRY003)


[warning] 64-64: Boolean-typed positional argument in function definition

(FBT001)

scripts/remote-dev-launcher.py

[warning] 25-25: Boolean-typed positional argument in function definition

(FBT001)


[warning] 33-33: Avoid specifying long messages outside the exception class

(TRY003)


[warning] 41-41: Avoid specifying long messages outside the exception class

(TRY003)


[warning] 43-43: Avoid specifying long messages outside the exception class

(TRY003)


[warning] 49-51: Avoid specifying long messages outside the exception class

(TRY003)


[warning] 61-61: Avoid specifying long messages outside the exception class

(TRY003)


[warning] 63-63: Avoid specifying long messages outside the exception class

(TRY003)


[warning] 69-69: Avoid specifying long messages outside the exception class

(TRY003)


[warning] 81-81: Avoid specifying long messages outside the exception class

(TRY003)


[warning] 86-86: Avoid specifying long messages outside the exception class

(TRY003)


[warning] 89-89: Boolean positional value in function call

(FBT003)


[warning] 92-94: Avoid specifying long messages outside the exception class

(TRY003)


[warning] 136-136: Avoid specifying long messages outside the exception class

(TRY003)


[error] 139-139: Possible binding to all interfaces

(S104)


[warning] 144-144: Boolean positional value in function call

(FBT003)


[warning] 229-230: Use format specifiers instead of percent format

Replace with format specifiers

(UP031)


[warning] 390-393: Use contextlib.suppress(KeyboardInterrupt) instead of try-except-pass

Replace try-except-pass with with contextlib.suppress(KeyboardInterrupt): ...

(SIM105)

🪛 Shellcheck (0.11.0)
scripts/test-role-neutral-runtime.sh

[info] 51-51: Expressions don't expand in single quotes, use double quotes for that.

(SC2016)


[info] 52-52: Expressions don't expand in single quotes, use double quotes for that.

(SC2016)


[info] 53-53: Expressions don't expand in single quotes, use double quotes for that.

(SC2016)


[info] 54-54: Expressions don't expand in single quotes, use double quotes for that.

(SC2016)


[info] 56-56: Expressions don't expand in single quotes, use double quotes for that.

(SC2016)


[info] 57-57: Expressions don't expand in single quotes, use double quotes for that.

(SC2016)


[info] 58-58: Expressions don't expand in single quotes, use double quotes for that.

(SC2016)


[info] 59-59: Expressions don't expand in single quotes, use double quotes for that.

(SC2016)


[info] 60-60: Expressions don't expand in single quotes, use double quotes for that.

(SC2016)


[info] 61-61: Expressions don't expand in single quotes, use double quotes for that.

(SC2016)


[info] 62-62: Expressions don't expand in single quotes, use double quotes for that.

(SC2016)


[info] 63-63: Expressions don't expand in single quotes, use double quotes for that.

(SC2016)


[info] 64-64: Expressions don't expand in single quotes, use double quotes for that.

(SC2016)


[info] 65-65: Expressions don't expand in single quotes, use double quotes for that.

(SC2016)

🔇 Additional comments (29)
AGENTS.md (1)

15-15: LGTM!

Also applies to: 42-42, 57-65, 66-88, 104-104

CHANGELOG.md (1)

22-38: LGTM!

Also applies to: 68-69, 71-92

PROJECT_STATUS.md (2)

9-9: LGTM!

Also applies to: 22-26, 34-43, 49-49


65-65: 📐 Maintainability & Code Quality

No change needed.

The updater dispatches build-amd64.yml for the updated automation branch; that workflow runs scripts/build-local.sh, which executes the launcher/Codex smoke tests and scripts/runtime-smoke-test.sh, and then runs the Trivy scans plus the enforcer.

README.es.md (1)

6-63: LGTM!

Also applies to: 73-128, 141-166

README.md (1)

6-28: LGTM!

Also applies to: 30-58, 60-80, 102-102, 126-139, 146-168, 200-200, 218-236

docs/architecture.md (2)

5-17: LGTM!

Also applies to: 31-85, 89-106, 108-129, 131-145, 157-158, 169-186, 190-205, 209-227, 231-252, 256-265


18-30: 📐 Maintainability & Code Quality

No changes needed.

The referenced issues state that #24 is closed, #25 and #31 are open work items, #36 is closed, and #46 remains under separate approval-mode work.

docs/releases.md (1)

25-45: LGTM!

Also applies to: 69-87, 91-91

docs/security.md (1)

7-23: LGTM!

Also applies to: 25-55, 82-84

.coderabbit.yaml (2)

35-46: LGTM!


58-58: LGTM!

compose/docker-compose.yml (1)

1-1: LGTM!

Also applies to: 10-20, 22-40, 42-50, 105-106

compose/truenas.yml (1)

1-36: LGTM!

Also applies to: 38-52, 85-85, 104-106

scripts/test_single_stack_compose.py (1)

64-133: LGTM!

Also applies to: 155-193

scripts/test-compose-image-compat.sh (2)

19-22: LGTM!

Also applies to: 29-62


23-28: 📐 Maintainability & Code Quality

No change needed.

scripts/test-compose-image-compat.sh already enables set -euo pipefail, so the docker compose ... | sort -u pipeline preserves the left-hand exit status.

.github/workflows/build-amd64.yml (1)

32-33: LGTM!

Also applies to: 55-57

Makefile (1)

14-18: LGTM!

.env.example (1)

5-15: LGTM!

images/codex/Dockerfile (1)

60-65: LGTM!

Also applies to: 74-95, 133-141

scripts/remote-dev-launcher.py (1)

1-399: LGTM!

scripts/start-remote-dev-web.sh (1)

13-16: LGTM!

scripts/remote-dev-healthcheck.sh (1)

1-37: LGTM!

scripts/test-remote-dev-launcher.sh (1)

1-131: LGTM!

scripts/runtime-smoke-test.sh (1)

4-12: LGTM!

Also applies to: 68-68, 116-179, 180-184

scripts/lib/remote-dev-runtime.sh (1)

16-24: LGTM!

Also applies to: 56-59, 74-77

scripts/remote-dev-doctor.sh (1)

29-72: LGTM!

Also applies to: 89-97, 123-147

scripts/test-role-neutral-runtime.sh (1)

51-69: LGTM!

Also applies to: 83-88, 109-109

Comment thread .env.example Outdated
Comment thread compose/docker-compose.yml
Comment thread compose/docker-compose.yml Outdated
Comment thread compose/truenas.yml Outdated
Comment thread docs/architecture.md
Comment thread docs/security.md Outdated
Comment thread scripts/test_single_stack_compose.py
Comment thread scripts/test_single_stack_compose.py Outdated
Comment thread scripts/test_single_stack_compose.py Outdated

Copy link
Copy Markdown
Owner Author

Review follow-up on the exact current branch:

  • destination hosts are now parsed structurally as DNS/IPv4/IPv6 values and embedded ports are rejected in favor of the separate port setting;
  • malformed/non-ASCII Basic credentials fail with 401 instead of reaching string comparison errors;
  • the launcher reads its root-readable secret, clears supplementary groups and permanently drops to UID/GID 65532 before binding or serving; the build test verifies the effective server UID;
  • launcher and Codex now have separate insecure-web overrides and separate password sources;
  • the TrueNAS launcher file is consistently launcher_password.txt;
  • health documentation now says unauthenticated/secret-free rather than local;
  • Compose tests use a minimal environment, reject Docker/Podman socket spellings and require exactly one independent credential source per service.

The .env.example names REMOTE_DEV_CODEX_PUBLIC_HOST and REMOTE_DEV_CODEX_PUBLIC_SCHEME are intentionally public deployment variables. Generic Compose maps them explicitly to the internal runtime variables REMOTE_DEV_LAUNCHER_CODEX_HOST and REMOTE_DEV_LAUNCHER_CODEX_SCHEME; the comment now states that mapping. Renaming them to the internal names would remove the intended public/internal separation, so that one suggestion was not applied.

Copy link
Copy Markdown
Owner Author

@codex review

Please review the exact current head e144a3e58f26571593860c80efcfffb48d3b1610. The final review fixes include structural host validation, effective UID/GID 65532 before serving, independent insecure-web overrides and password sources, deterministic non-vacuous Compose assertions, broader socket detection, and the corrected TrueNAS launcher secret path. Keep feedback within the launcher/Codex slice.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e144a3e58f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/remote-dev-healthcheck.sh Outdated

Copy link
Copy Markdown
Owner Author

@codex review

Please verify the exact current head 7f4cc5ebb59b29b206939b4fd9d64b658420c888. The final change normalizes every trailing slash in WEB_BASE_PATH identically in the launcher healthcheck and adds a runtime smoke case using /launcher//. Keep feedback limited to that regression and the existing launcher/Codex slice.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7f4cc5ebb5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +25 to +27
curl --fail --silent --show-error \
--connect-timeout 2 --max-time 4 \
"http://127.0.0.1:${WEB_PORT:-7680}${health_path}" >/dev/null

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve accepted dot segments in health requests

When LAUNCHER_BASE_PATH produces a WEB_BASE_PATH containing a dot segment such as /a/../b/, the launcher validator accepts it and serves the literal /a/../b/healthz, but this curl invocation normalizes the request to /b/healthz, so Docker marks the running launcher unhealthy. Checked curl 8.5.0's --help all, which describes --path-as-is as “Do not squash .. sequences in URL path”; either reject dot segments in the shared path validation or add that option so the probe preserves every accepted path.

AGENTS.md reference: AGENTS.md:L88-L88

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant