Skip to content

Let cc-harness helpers route with env credentials (swarm 0.17.1) - #102

Merged
gering merged 4 commits into
mainfrom
task/fix-swarm-cc-harness-env-filter
Nov 4, 2026
Merged

gering merged 4 commits into
mainfrom
task/fix-swarm-cc-harness-env-filter

Conversation

@gering

@gering gering commented Nov 3, 2026 •

Copy link
Copy Markdown
Owner

Problem

Every cc-harness:<id> exec failed with rc=3 "no gateway token" (10/10 calls in the PR #100 review) while readiness reported the voices ready. cc-router's remote route reads CLIPROXY_API_KEY_<PROFILE> / CLIPROXY_CF_ACCESS_<PROFILE>_CLIENT_SECRET from the env, and the adapter stripped secret-shaped names before the helper ran; list ran unfiltered.

Fix

  • _harness_env_prefix splits the filter around the helper:
    • HARNESS_PRE (before the helper, for list and exec): strips only the Anthropic credentials the helper replaces, the parent's Claude Code markers, and redirects git config.
    • HARNESS_POST (exec <id> -- env -u … before the jail): strips every secret-shaped name the parent holds, derived from the same _env_filter_args (no profile names). The routing ANTHROPIC_AUTH_TOKEN the helper injects survives.
  • Readiness runs list under HARNESS_PRE, so ready and exec see the same env.
  • _hardened_env_prefix loses its now-unused extra-names parameter.

Tests

New hermetic tests in test_cc_harness.py with a stub helper that needs a *_SECRET var: exec succeeds, the claude stub sees neither the secret, GH_TOKEN, nor the parent's Anthropic creds (but does see the helper's routing token); the helper sees identical env names in list and exec; a helper that cannot route is not ready. The first two fail on 0.17.0. scripts/check-structure.py green.

Local review (swarm, 1 round)

5 findings, all acted on in f6268fe:

  • 🔴 The secret-name filter and scrub were suffix-only, so CLIPROXY_API_KEY_<PROFILE> reached every jailed voice (already true in 0.17.0). Both now match infix forms; tests cover it.
  • Exec target shape (env -u … [jail] claude) and the helper trust boundary (the helper's own exports are its call) are documented in cc-harness-agents.md.
  • HARNESS_POST is built only at exec; the git redirects are shared.

CI fix after review

9e769a7: the readiness/exec parity test failed on Linux CI only. Bash exports OLDPWD valueless at startup, and exec's cd into the empty cwd gave it the repo path, so exec saw one env name more than list. HARNESS_PRE now unsets OLDPWD; the test asserts it. Not covered by the recorded local review.

Local review, round 2 (swarm)

8 findings on 9e769a7, all applied in 5d8be5e (now covers the OLDPWD commit too; merge gate covered=yes):

  • The workflow output gate (scrubField in swarm-review.js) gets the same profile-suffixed rule as the adapter scrub; a test runs both on the same cases.
  • The env filter also strips *_PASSWORD_*, *_CREDENTIALS_*, *_ACCESS_KEY*, *_PRIVATE_KEY* (no blanket *_KEY).
  • The round-1 tail wildcard in the scrub is replaced by a case-sensitive rule for uppercase env names that keeps the name and also covers *_CLIENT_ID; token_path/password_hash stay untouched.
  • CLAUDE_CONFIG_DIR moves behind the helper, so list and exec see exactly the same env; the parity test compares all names.
  • README Linux checklist, knowledge note, CHANGELOG and a doc-path comment updated.

Rebased onto main (#100).

Live check (approved by Robert)

One real cc-harness:sol voice through the 0.17.1 adapter on a planted off-by-one diff: rc=0 in ~7 s, 1 correct critical finding, schema-valid output. The same call through the installed 0.17.0 adapter fails with rc=3 (no gateway token) in the helper, which confirms the root cause live.

🤖 Generated with Claude Code

https://claude.ai/code/session_01RtoWD2CayLPgnn8FrtyqLG

gering and others added 4 commits November 4, 2026 14:03
- Split the secret-shaped env filter around the helper: before it, strip
  only the Anthropic credentials it replaces, Claude Code markers and git
  config; after it (`exec <id> -- env -u ...`), strip every secret-shaped
  name the parent holds, so the jailed claude still never sees them
- Run readiness (`list`) under the same pre-helper env as exec, so a
  helper that cannot route there is not reported ready
- Hermetic tests with a stub helper that needs a *_SECRET var

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RtoWD2CayLPgnn8FrtyqLG
- Match infix secret names (CLIPROXY_API_KEY_<PROFILE>, *_CLIENT_ID,
  *_TOKEN_*, *_SECRET_*) in the env filter and the findings scrub; the
  suffix-only patterns let a gateway API key reach every jailed voice
- Build HARNESS_POST only where exec uses it; share the git redirects
- Document the exec target shape and the helper trust boundary in the
  cc-harness contract

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RtoWD2CayLPgnn8FrtyqLG
Bash exports OLDPWD valueless at startup; exec's cd into the empty cwd
gave it the repo path, so exec saw one env name more than list (Linux
CI only; a zsh parent already exports it).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RtoWD2CayLPgnn8FrtyqLG
- Mirror the profile-suffix scrub in the workflow output gate and test
  that both scrubbers redact identically
- Replace the (?i) keyword tail, which redacted token_path and friends,
  with a case-sensitive uppercase env-name rule that keeps the name and
  also covers *_CLIENT_ID
- Strip *_PASSWORD_*, *_CREDENTIALS_*, *_ACCESS_KEY*, *_PRIVATE_KEY*
- Set CLAUDE_CONFIG_DIR after the helper so list and exec give it the
  same env; the parity test now compares the full name sets
- Bring README, CHANGELOG and knowledge in line with 0.17.1

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RtoWD2CayLPgnn8FrtyqLG
@gering
gering force-pushed the task/fix-swarm-cc-harness-env-filter branch from 9e769a7 to 5d8be5e Compare November 4, 2026 13:12
@gering
gering merged commit ddbe44d into main Nov 4, 2026
2 checks passed
@gering
gering deleted the task/fix-swarm-cc-harness-env-filter branch November 4, 2026 13:18
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