Same bug as upstream agent-runtimes: scoped form never matched
because the dispatcher does literal scope.id compare and
owner_principal_id stores the user UUID, not 'paul'.
Pairs with PATCH /v1/accounts/{id} renaming the live account_label
to 'anthropic-cloud-paul-oauth' so the bare ref resolves uniquely.
Closes BUG-22a.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Mirrors agent-runtimes audit + fix. All three M22 Phase 9 wrapper-script
auth paths were broken since the cutover: each one ran as the agent UID
trying to `cat` a 0400 root-only ESO mount. Same root cause we hit on
minimax/z-ai earlier today.
Changes:
1. anthropic-cloud-paul-oauth/v1 (NEW in framework)
- Mirrors agent-runtimes — was previously only present there.
- init.sh stages oauth_token into ~/.claude/.credentials.json (Claude
Code's native subscription-OAuth schema). No env, no apiKeyHelper,
no wrapper. Restores the equivalent of what harness_init.py used to
do for the legacy SOPS path.
- The legacy `bin/anthropic-wrapper.sh` was dead code (never wired).
2. gitea-https/v1
- init.sh stages the token to $HOME/.config/git/gitea-https-token
(0600 agent:agent) and points the per-host git credential helper at
the staged copy. Previously the helper `cat`d the ESO mount path
and silently failed at every git invocation.
3. gitea-admin/v1
- init.sh stages the token to $HOME/.config/gitea-admin/token
(0600 agent:agent). Wrapper updated to read from the staged copy.
- Removes stale `requires: anthropic-cloud/v1` (the only anthropic
harness in agent-runtimes is anthropic-cloud-paul-oauth/v1).
Pattern matches gitea-ssh / minimax / z-ai: ESO mount stays root-only,
init.sh runs as root and `install -m 0600 -o agent -g agent`s a single
explicit copy. Per-secret enumeration; future ESO Secret keys remain
inaccessible by default.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Mirrors agent-runtimes commit 6f20b51. CRS serves these harness files to
dispatchers, so this repo must match.
Switches from "mount mode 0444 so the agent user can `cat` the ESO file"
to the gitea-ssh staging pattern: keep the ESO mount root-only (0400),
init.sh as root `install`s a per-secret 0600 agent-owned copy, and
apiKeyHelper points at the staged copy. Stronger blast-radius guarantee
— if the ESO Secret later grows additional keys, they remain root-only
unless the harness explicitly stages them.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Mirrors agent-runtimes commit 166c19b. CRS serves these harness files to
dispatchers, so this repo must match.
Two fixes from the failing smoke test:
1. init.sh resolves the agent user's home via getent (init.sh runs as
root, but claude runs as the agent user — different $HOME).
2. secrets_required mode "0400" → "0444" so the agent user can read the
ESO-mounted secret via apiKeyHelper. The file is in pod-local tmpfs.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Mirrors the minimax fix to z-ai. Replaces bin/anthropic-compat-wrapper.sh
(which did `exec env ANTHROPIC_AUTH_TOKEN="$(cat ...)" claude "$@"`,
exposing the secret in the claude subprocess' /proc/<pid>/environ) with
init.sh that writes ~/.claude/settings.json with:
apiKeyHelper: "cat /run/agent/secrets/z-ai/auth_token"
Claude Code routes apiKeyHelper output to `Authorization: Bearer <value>`
when ANTHROPIC_BASE_URL is non-anthropic.com — exactly what the Z.ai
proxy at api.z.ai/api/anthropic requires.
The legacy K8s Secret may still ship a `base_url` file; it is
intentionally ignored by init.sh (the base URL is not a credential and
lives in harness.yaml).
Mirrors agent-runtimes commit (z-ai apiKeyHelper). CRS serves these
harness files to dispatchers, so this repo must match.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Mirrors agent-runtimes commit 1b83c81. CRS serves these harness files
to dispatchers, so this repo must match for the fix to take effect.
The minimax harness now writes ~/.claude/settings.json with an
apiKeyHelper that `cat`s the ESO-mounted /run/agent/secrets/minimax/
api_key file. Claude Code routes apiKeyHelper output to
`Authorization: Bearer <value>` for non-anthropic.com base URLs, which
is what MiniMax's /anthropic proxy requires. The secret is never read
into env, never written into a config file, and ESO rotation is
auto-recovered via Claude Code's per-session helper invocation
(also re-runs after a 401).
- harness.yaml: drop ANTHROPIC_AUTH_TOKEN_FILE env var
- init.sh: write (or jq-merge) settings.json with apiKeyHelper, chmod 0600
- bin/anthropic-compat-wrapper.sh: deleted
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Mirrors agent-runtimes — adds ANTHROPIC_AUTH_TOKEN_FILE pointer so the
Claude runner sets apiKeyHelper. Without it Claude Code CLI exits with
'Not logged in'.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
gitea-ssh has 3 accounts (ai_enablement, accelerators, homelab) and
gitea-https has 2 (primary, admin) — bare provider_type refs hit
MultipleAccountsError per SR-DISP-8. Switch to scoped name.space:platform
form. Mirrors the agent-runtimes commit; the dispatcher-side parser
also gains underscore support for account names like 'ai_enablement'.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The CRS-served harnesses still carried `secrets_files: [{encrypted: true}]`
which now hard-fails on H-SECRET-1 ("SOPS-encrypted secrets_files entries
are no longer permitted") in the dispatcher's harness validator. Sync the
8 provider harnesses with the agent-runtimes copies: same `secrets_required`
shape, same `init.sh` (ESO-mounted file paths), same `bin/` wrappers.
Use bare `account_ref: "<provider>"` (not `<provider>.cp:cp` — that
scope-kind isn't valid per SR-DISP-1-FIELD).
Provider key names follow the per-provider schema as emitted by the CP
provisioner: minimax/airouter/z-ai → api_key; gitea-https/gitea-admin →
{token,base_url,username}; gitea-ssh* → {host,private_key}.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds the tdd-gate harness context (TEST_PASS_REQUIRED=true + CLAUDE.md
methodology) and five provider-specific TDD composites that layer
tdd-protect + tdd-gate + python-dev + tdd-file-lock on top of the
existing code-* layer stacks. Matching task templates for sonnet, opus,
haiku, minimax, and airouter. allowed_failing_tests support noted in
warnings pending M19 pre-test hook implementation.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Mount best-practices context at /workspace/best-practices/ (was
/opt/harness/context/best-practices/) for consistent agent access
- Fix /workspace/working/ → /workspace/project/ in all CLAUDE.md files
(planning, spec-writing, security-review, code-methodology,
qwen-code-methodology, test-writing)
- Update best-practices path references in all CLAUDE.md files to
/workspace/best-practices/
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>