Skip to content

feat(cloak): -p cloak stealth-browser profile, auth sessions, non-gating release - #487

Closed
lroolle wants to merge 2 commits into
feat/kimi-455from
feat/cloak-456
Closed

feat(cloak): -p cloak stealth-browser profile, auth sessions, non-gating release#487
lroolle wants to merge 2 commits into
feat/kimi-455from
feat/cloak-456

Conversation

@lroolle

@lroolle lroolle commented Jul 27, 2026

Copy link
Copy Markdown
Member

Stacked on #486 (feat/kimi-455). Review that first; base retargets to main on merge.

deva.sh -p cloak <agent> runs agents in a new image (Dockerfile.cloak,
extends :rust) with CloakBrowser stealth Chromium, headed on Xvfb :99 +
openbox. Chromium is baked at build time (hermetic, auto-update off);
CLOAKBROWSER_WRAPPER_VERSION pins the wrapper and thereby Chromium.

Authenticated sessions, three composable pieces:

  • persistent profile: ~/.config/deva/cloak-profile -> Chromium userDataDir,
    so one login survives container removal
  • interactive login over VNC: on OrbStack/Linux the host reaches the
    container directly (x11vnc on demand, no flag). --cloak-vnc is the
    Docker-Desktop fallback that publishes VNC on a host-loopback port
  • --cloak-browser: an always-on daemon holds one headed persistent browser
    with a loopback CDP endpoint; the agent drives it via connectOverCDP --
    the same live browser, not a throwaway

Image policy, the part worth arguing about
cloak is an auxiliary image on its own cadence, NOT a general releasable
profile. It holds no agent CLIs and only changes when Dockerfile.cloak,
cloak-entrypoint.sh or CLOAKBROWSER_WRAPPER_VERSION change -- never on a
deva.sh version bump. So:

  • the release cloak job is continue-on-error and is OUT of the release
    job's needs. A ~200MB Chromium bake per arch (arm64 under QEMU) must not
    sit on the critical path of every release, and a flake in an optional layer
    must not fail a release whose artifact is deva.sh
  • nightly already skips it, same reasoning
  • notes present :cloak as rolling, :vX.Y.Z-cloak as possibly lagging
  • CI stays paths-filtered

Follow-up #485 makes this policy data instead of a comment: profile identity
is currently duplicated across deva.sh, Makefile and three workflows.

Also fixed here: a .deva config setting DEVA_DOCKER_TAG silently overrode the
real environment and made CLI -p a no-op. Precedence is now
environment > config files > -p profile > default, guarded by
scripts/test-image-precedence.sh in CI.

Test plan

  • make test-cloak green
  • LIVE against the built image (wrapper 0.5.2, Chrome 146.0.7680.177):
    x11vnc answers RFB 003.008 on :5900; cloak-browserd serves CDP on
    127.0.0.1:9222; a separate playwright-core client connectOverCDPs,
    drives a page, and the daemon survives that client's close()
  • stealth confirmed live: UA spoofs Windows NT 10.0, navigator.webdriver
    === false
  • this closes the 2026-07-21 dev-log gap that marked exactly these two
    claims unverified
  • image-precedence, mount-shape, container-slug suites green
  • skill documents the setContent() footgun found while proving it:
    it hangs on a fresh daemon page; use goto(data:, domcontentloaded)

Closes #456

@claude-yolo

claude-yolo Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Claude encountered an error after 1s —— View job


I'll analyze this and get back to you.

@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: cea4391c29

ℹ️ 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 deva.sh
Comment on lines +3372 to +3374
DOCKER_ARGS+=("-e" "DEVA_CLOAK_BROWSER=1")
DOCKER_ARGS+=("-e" "DEVA_CLOAK_CDP_PORT=${cdp_port}")
DOCKER_ARGS+=("-e" "CLOAK_CDP_ENDPOINT=http://127.0.0.1:${cdp_port}")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Isolate the browser-enabled persistent container

When a normal persistent -p cloak container already exists, a later run with --cloak-browser only appends these settings and the profile mount to DOCKER_ARGS; the attach path instead executes the existing container while passing only _trace_env, so DEVA_CLOAK_BROWSER is absent, the daemon never starts, and CLOAK_CDP_ENDPOINT is unavailable. The inverse also retains an opted-in daemon for later runs without the flag. Include the browser mode in the persistent-container shape or explicitly reconcile it when attaching.

Useful? React with 👍 / 👎.

Comment thread deva.sh
Comment on lines +3414 to +3417
DOCKER_ARGS+=("-p" "127.0.0.1:${free_port}:5900")
DOCKER_ARGS+=("-e" "DEVA_CLOAK_VNC=1")
DOCKER_ARGS+=("-e" "DEVA_CLOAK_VNC_PASSWORD=${DEVA_CLOAK_VNC_PASSWORD_EFFECTIVE}")
DEVA_CLOAK_VNC_URL="vnc://127.0.0.1:${free_port}"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Reuse the published VNC port on attach

On the second persistent --cloak-vnc launch, the existing container's published host port is already occupied, so this probe chooses the next free port and records a new URL/password. The attach path ignores these new DOCKER_ARGS and reuses the old container, yet announce_cloak_vnc existing prints the newly selected, unpublished port, leaving the user with a dead VNC URL and wrong password. Inspect the existing mapping instead of allocating a create-time port before deciding to attach.

Useful? React with 👍 / 👎.

Comment on lines +10 to +14
paths:
- "Dockerfile.cloak"
- "scripts/cloak-entrypoint.sh"
- "versions.env"
- ".github/workflows/cloak-image.yml"

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 Trigger cloak CI when the browser daemon changes

The checked cloak-image.yml path filters omit scripts/cloak-browserd.mjs, even though Dockerfile.cloak copies that file into the image and make test-cloak validates it. A PR or main push changing only the daemon therefore skips the cloak build-and-test job entirely, allowing syntax or image-integration regressions through without this workflow running; include the daemon path in both filters.

Useful? React with 👍 / 👎.

Comment on lines +29 to +31
XDG_CACHE_HOME="$tmp_home/.cache" \
DEVA_NO_DOCKER=1 \
${1+"$@"} ./deva.sh claude --dry-run

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Keep the precedence smoke test independent of registry images

On a clean runner, DEVA_NO_DOCKER=1 only disables Docker-socket mounting; it does not bypass check_image, which runs before the --dry-run exit. Consequently these cases inspect/pull ghcr.io/thevibeworks/deva:{rust,cloak,latest} and produce no deva.image label when a tag is unavailable—the newly introduced :cloak case is especially guaranteed to fail before that image has first been published. I reproduced all four failures from a clean archive without those local images; mock image lookup or otherwise bypass it so this CI test exercises precedence rather than registry state.

Useful? React with 👍 / 👎.

lroolle and others added 2 commits July 27, 2026 02:15
…pport

Second of two commits on this branch, on top of the kimi batch. Adds the
CloakBrowser profile (#456) and the image/tag precedence fix it needs.

- cloak profile: `-p cloak` runs agents in a CloakBrowser image
  (Dockerfile.cloak, extends :rust) -- source-patched stealth Chromium,
  headed on Xvfb :99 + openbox, binary baked at build (auto-update off).
  Ships the deva-cloak skill, make build-cloak/test-cloak, a
  paths-filtered cloak-image.yml, and release :cloak / :vX.Y.Z-cloak tags.
- auth sessions: a persistent host profile mount (~/.config/deva/
  cloak-profile -> userDataDir) so a login survives container removal.
  Interactive login over VNC is on-demand and direct-reach on
  OrbStack/Linux -- the agent starts x11vnc and you connect at the
  container IP; --cloak-vnc is the Docker-Desktop fallback that publishes
  a loopback port. --cloak-browser is an optional always-on cloak-browserd
  daemon the agent attaches to over CDP.
- fix(precedence): env > config > -p > default, so an explicit -p beats a
  .deva DEVA_DOCKER_TAG (guarded by scripts/test-image-precedence.sh).

Not built/smoke-tested locally (container network blocks apt); release CI
builds the image on GitHub runners.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- release job no longer needs build-and-push-cloak; the cloak job is
  continue-on-error. A ~200MB Chromium bake per arch (arm64 under QEMU)
  must not sit on the critical path of a GitHub Release, and a flake in
  an optional layer must not fail a release whose artifact is deva.sh
- cloak holds no agent CLIs and only changes when Dockerfile.cloak,
  cloak-entrypoint.sh or CLOAKBROWSER_WRAPPER_VERSION change -- never on
  a version bump. Nightly already skipped it for the same reason
- release notes: :cloak is the rolling tag, :vX.Y.Z-cloak may lag
- skill: goto(data:,{domcontentloaded}) not setContent() -- setContent
  hangs on a fresh daemon page waiting for a load event that never fires
- dev log records the live proofs that close the 07-21 unverified gap:
  RFB 003.008 on :5900, CDP on :9222, connectOverCDP drives the live
  browser and the daemon survives client disconnect

Refs #456
@claude-yolo

claude-yolo Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Claude encountered an error after 1s —— View job


I'll analyze this and get back to you.

@lroolle

lroolle commented Jul 27, 2026

Copy link
Copy Markdown
Member Author

Superseded by #492 -- GitHub auto-closed this when the base branch feat/kimi-455 was deleted on merge of #486. Same content, rebased onto main.

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