Skip to content

refactor(archon): wire CLAUDE_BIN_PATH for live-workflow agent work orders (#2217) - #2359

Merged
POWERFULMOVES merged 2 commits into
mainfrom
refactor/archon-env-wiring-2217
Aug 3, 2026
Merged

refactor(archon): wire CLAUDE_BIN_PATH for live-workflow agent work orders (#2217)#2359
POWERFULMOVES merged 2 commits into
mainfrom
refactor/archon-env-wiring-2217

Conversation

@POWERFULMOVES

@POWERFULMOVES POWERFULMOVES commented Aug 3, 2026

Copy link
Copy Markdown
Owner

refactor(archon): wire CLAUDE_BIN_PATH for live-workflow agent work orders (Issue #2217)

Issue #2217's "Auth for live workflows" section listed three things: CLAUDE_USE_GLOBAL_AUTH, the token (ambiguous; either API key or OAuth token), and CLAUDE_BIN_PATH. The first two are already wired; CLAUDE_BIN_PATH is the only remaining piece. The TS archon server uses CLAUDE_BIN_PATH when spawning the Claude CLI as a subprocess for the Agent Work Orders feature.

2 stacked commits

SHA Type Files Lines
f4f6cfe2ee P1: refactor(archon) 3 +30
20bcd46e51 docs: AGNOTE CLAIM + spec 2 +139

What ships

P1 — the env wiring:

  • pmoves/docker-compose.yml — add CLAUDE_BIN_PATH=${CLAUDE_BIN_PATH:-} to the archon service env, with a 4-line comment explaining the default (uses $PATH) and the upstream's standard install path (/usr/local/bin/claude).
  • pmoves/docker-compose.agents.yml — regenerated by make -C pmoves compose-split to reflect the new env var on the agents-profile split. All other split overlays are unchanged.
  • pmoves/env.tier-agent.example — new "Archon — Claude / gh live-workflow auth (Issue Archon 0.6.0 integration: first-class main-compose service + fabric wiring + Claude/gh auth #2217)" section that documents the full set of live-workflow tokens (CLAUDE_API_KEY, CLAUDE_CODE_OAUTH_TOKEN, CLAUDE_USE_GLOBAL_AUTH, CLAUDE_BIN_PATH, GH_TOKEN) with comments on each. This makes the operator's env.shared setup explicit.

Docs:

  • AGNOTE CLAIM with full details.
  • ~5KB cold-read spec at pmoves/docs/specs/archon-env-wiring-2026-08-03.md.

Validation

  • yaml.safe_load parses the main compose cleanly
  • make -C pmoves compose-split reports 102/102 services across overlays, all YAML syntactically valid
  • No new failure modes introduced (the new env var has a safe default)

What does NOT change (intentionally)

  • The Makefile archon targets (up-archon-submodule, up-archon-native, archon-smoke, etc.) — they don't reference CLAUDE_BIN_PATH.
  • The archon-data / archon-user-home / archon-pg-data volumes — those are persistent state, not auth.
  • The upstream PMOVES-Archon/.env.example additional env vars (ENABLE_AGENT_WORK_ORDERS, STATE_STORAGE_TYPE, SERVICE_DISCOVERY_MODE, ENABLE_DOCKER_SOCKET_MONITORING, MCP_HEALTH_CHECK_TIMEOUT, LOGFIRE_TOKEN, LOG_LEVEL) — not relevant to PMOVES's single-service deployment. We can wire them in a follow-up lane if Agent Work Orders is ever added as a separate PMOVES service.

What this means for Issue #2217

Items #1 (first-class main-compose service), #2 (fabric wiring), #3 (DB decision), and #5 (retire the dead Python wrapper) were all already done in earlier PRs. Item #4 (auth for live workflows) is now complete with this commit. The issue is effectively closed at the wiring level.

Three-body

  • delivery: Mavis (this lane)
  • control: DARKXSIDE (operator sets CLAUDE_BIN_PATH in env.shared if needed; verifies the archon service still boots)
  • memory: this spec + 1 commit + 1 env var + 5 lines of comments in env.tier-agent.example

Refs: #2217

Summary by CodeRabbit

  • New Features
    • Added configurable Claude CLI path support for Archon deployments, with automatic PATH-based resolution by default.
    • Added documented environment settings for Claude authentication and optional GitHub integration.
  • Documentation
    • Documented Archon live-workflow authentication configuration, defaults, validation results, and remaining scope.
    • Added an issue-tracking note covering the completed authentication wiring.

…rders

Issue #2217 (2026-08-03): the archon service in `pmoves/docker-compose.yml`
already wires the bulk of the live-workflow auth (CLAUDE_API_KEY,
CLAUDE_CODE_OAUTH_TOKEN, CLAUDE_USE_GLOBAL_AUTH, GH_TOKEN). One
last token from the issue's "Auth for live workflows" section is
still missing: `CLAUDE_BIN_PATH` — the path to the Claude CLI binary
inside the container. The TS archon server uses this when spawning
Claude Code as a subprocess for the Agent Work Orders feature.

This is a 1-token, 1-PR change — the lane is small because the
upstream `PMOVES-Archon/.env.example` mapping was mostly already done
in earlier PRs. The only thing this commit adds:

  - `pmoves/docker-compose.yml`: add `CLAUDE_BIN_PATH=${CLAUDE_BIN_PATH:-}`
    to the `archon` service env, with a 4-line comment explaining the
    default behavior ($PATH) and the upstream's standard install path
    (/usr/local/bin/claude).
  - `pmoves/docker-compose.agents.yml`: regenerated by `make -C pmoves
    compose-split` to reflect the new env var on the agents-profile
    split. All other splits are unchanged (they don't include archon).
  - `pmoves/env.tier-agent.example`: new "Archon — Claude / gh
    live-workflow auth (Issue #2217)" section that documents the
    full set of live-workflow tokens (CLAUDE_API_KEY,
    CLAUDE_CODE_OAUTH_TOKEN, CLAUDE_USE_GLOBAL_AUTH, CLAUDE_BIN_PATH,
    GH_TOKEN) with comments on each. This makes the operator's
    `env.shared` setup explicit; previously these were scattered or
    undocumented.

Validation: `yaml.safe_load` parses the main compose; `make -C pmoves
compose-split` reports 102/102 services across overlays, all YAML
syntactically valid.

What does NOT change (intentionally, out of scope for this lane):
  - The Makefile archon targets (`up-archon-submodule`, `up-archon-native`,
    `archon-smoke`, etc.) — they don't reference CLAUDE_BIN_PATH.
  - The upstream `PMOVES-Archon/.env.example` has additional env vars
    (`ENABLE_AGENT_WORK_ORDERS`, `STATE_STORAGE_TYPE`,
    `SERVICE_DISCOVERY_MODE`, etc.) that aren't relevant to PMOVES'
    single-service deployment. We can wire them in a follow-up lane
    if Agent Work Orders is ever added as a separate PMOVES service.
  - The `archon-data` / `archon-user-home` / `archon-pg-data` volumes
    — those are persistent state, not auth.

Refs: #2217
#2217)

Lane 2217 (2026-08-03): closes the lane. The CLAIM goes on the AGNOTE;
the cold-read spec captures the full design for a fresh local model
picking this work up next session.

What lands:
  - pmoves/docs/AGENTS/AGNOTE4482PHI.t1.md: new section "Issue #2217
    — Archon 0.6.0 env wiring (2026-08-03)" with the full CLAIM text.
    Ends with the GRAPHITI_MARK HTML comment so a future graphiti
    loader can index it.
  - pmoves/docs/specs/archon-env-wiring-2026-08-03.md (new, ~5KB):
    cold-read spec covering TL;DR + why now + what shipped (P1 only,
    since the lane is small enough for 1 commit) + validation + out of
    scope + what's left for Issue #2217 + three-body + CHIT trail.

The functional commit is already pushed. The PR is ready to push
after this commit lands: YAML parses, compose-split regenerates
cleanly (102/102 services), 1 env var + 5 lines of comments in
env.tier-agent.example.

Refs: #2217
@github-actions github-actions Bot added compose Compose files / service Dockerfiles docs Documentation governance AGNOTE register / agent definitions / damage-control hooks labels Aug 3, 2026
@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Docker Hardening Validation

Hardening Validation Report

Validated: Mon Aug 3 15:46:33 UTC 2026

Services Checked

PMOVES.AI Docker Hardening Validation

[INFO] Checking: pmoves/docker-compose.hardened.yml

[INFO] Validating: hi-rag-gateway-v2
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: extract-worker
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: langextract
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: presign
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: render-webhook
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: retrieval-eval
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: pdf-ingest
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: jellyfin-bridge
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: invidious-companion-proxy
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: ffmpeg-whisper
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: media-video
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: media-audio
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: hi-rag-gateway-v2-gpu
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: hi-rag-gateway-gpu
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: deepresearch
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: supaserch
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: publisher-discord
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: mesh-agent
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: nats-echo-req
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: nats-echo-res
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: comfy-watcher
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: grayjay-plugin-host
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: agent-zero
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: p7-room-orchestrator
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: archon
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: channel-monitor
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: pmoves-yt
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: notebook-sync
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: supabase_service_role_key
[WARN] No user directive
[WARN] No read_only directive
[WARN] No cap_drop: ["ALL"]
[WARN] No no-new-privileges
[WARN] No resource limits

[INFO] Validating: supabase_jwt_secret
[WARN] No user directive
[WARN] No read_only directive
[WARN] No cap_drop: ["ALL"]
[WARN] No no-new-privileges
[WARN] No resource limits

[INFO] Validating: p7_control_token
[WARN] No user directive
[WARN] No read_only directive
[WARN] No cap_drop: ["ALL"]
[WARN] No no-new-privileges
[WARN] No resource limits

======================================
Summary: 112 passed, 43 warnings, 0 errors

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Archon now supports configurable Claude CLI paths in both compose definitions. The agent-tier environment template documents Claude and GitHub authentication variables. An AGNOTE and specification record the wiring, validation, and Issue #2217 status.

Changes

Archon environment wiring

Layer / File(s) Summary
Compose CLI path wiring
pmoves/docker-compose.agents.yml, pmoves/docker-compose.yml
Both Archon compose definitions accept optional CLAUDE_BIN_PATH values and use an empty default for PATH-based CLI resolution.
Agent authentication configuration
pmoves/env.tier-agent.example, pmoves/docs/specs/..., pmoves/docs/AGENTS/...
The agent-tier template documents Claude and GitHub authentication variables. The specification and AGNOTE record validation, scope, and completion status.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related issues

  • #2217 — The changes implement the issue’s Archon live-workflow authentication wiring.

Suggested reviewers: hunnibear

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main change: wiring CLAUDE_BIN_PATH for Archon live-workflow agent work orders.
Description check ✅ Passed The description clearly explains the change, scope, validation results, intentional exclusions, and issue impact, although it does not mirror every template heading.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/archon-env-wiring-2217

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.

@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: 20bcd46e51

ℹ️ 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 pmoves/docker-compose.yml
# Default empty (uses $PATH). The upstream Archon Dockerfile installs
# Claude at /usr/local/bin/claude; set this only if the image builds
# Claude at a non-standard path or you want to pin a specific binary.
- CLAUDE_BIN_PATH=${CLAUDE_BIN_PATH:-}

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 Let env.tier-agent supply the custom Claude binary path

When an operator follows the new template and sets CLAUDE_BIN_PATH only in env.tier-agent, the documented raw docker compose --profile agents ... invocation in pmoves/README.md:112 does not use that file for Compose interpolation. This expression therefore resolves to an empty string, and the explicit environment entry overrides the value that the service's env_file would otherwise inject. Custom Archon images consequently fall back to $PATH and cannot launch Claude; the repository already identifies this exact empty-default shadowing pattern in pmoves/docs/operations/CREDENTIAL_AND_DRIFT_SITREP.md:85. Omit the explicit entry or ensure every supported invocation supplies the tier file with --env-file.

Useful? React with 👍 / 👎.

@POWERFULMOVES
POWERFULMOVES merged commit 0496ab7 into main Aug 3, 2026
39 of 40 checks passed
@POWERFULMOVES
POWERFULMOVES deleted the refactor/archon-env-wiring-2217 branch August 3, 2026 15:51

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
pmoves/env.tier-agent.example (1)

77-78: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Document least-privilege GitHub permissions.

The template prescribes repo, workflow without identifying the Archon operations that require them. Verify the minimum permissions for Archon 0.6.0. Prefer a fine-grained, repository-scoped token where possible instead of making broad classic-PAT access the default guidance.

🤖 Prompt for 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.

In `@pmoves/env.tier-agent.example` around lines 77 - 78, Update the GH_TOKEN
documentation near the env.tier-agent example to verify and describe the minimum
GitHub permissions required by Archon 0.6.0, mapping each permission to the
specific Archon operation that uses it. Prefer guidance for a fine-grained,
repository-scoped token and present broad classic-PAT scopes only when
unavoidable.
🤖 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 `@pmoves/env.tier-agent.example`:
- Around line 65-70: Update the Archon authentication comment near the Claude/gh
live-workflow section to explicitly identify Archon live workflows as the
exception to the TensorZero-only policy, and state that CLAUDE_API_KEY and
CLAUDE_CODE_OAUTH_TOKEN must not be copied or provided to other agent-tier
services.

---

Nitpick comments:
In `@pmoves/env.tier-agent.example`:
- Around line 77-78: Update the GH_TOKEN documentation near the env.tier-agent
example to verify and describe the minimum GitHub permissions required by Archon
0.6.0, mapping each permission to the specific Archon operation that uses it.
Prefer guidance for a fine-grained, repository-scoped token and present broad
classic-PAT scopes only when unavoidable.
🪄 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: CHILL

Plan: Pro Plus

Run ID: 07bea862-f186-4fd7-8505-cda5669d2748

📥 Commits

Reviewing files that changed from the base of the PR and between 7698608 and 20bcd46.

📒 Files selected for processing (5)
  • pmoves/docker-compose.agents.yml
  • pmoves/docker-compose.yml
  • pmoves/docs/AGENTS/AGNOTE4482PHI.t1.md
  • pmoves/docs/specs/archon-env-wiring-2026-08-03.md
  • pmoves/env.tier-agent.example

Comment on lines +65 to +70
# ---------------------------------------------------------------------------
# Archon — Claude / gh live-workflow auth (Issue #2217)
# ---------------------------------------------------------------------------
# The TS server exits(1) at boot if no Claude auth is present. The compose
# file wires the following tokens to the `archon` service env. Set at least
# one of CLAUDE_API_KEY or CLAUDE_CODE_OAUTH_TOKEN; leave the others empty.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

State the Archon exception to the TensorZero-only policy.

The file says agent-tier services must not receive direct external LLM API keys, but this section instructs operators to set CLAUDE_API_KEY. State that Archon live workflows are the exception and that these credentials must not be copied to other agent services.

🤖 Prompt for 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.

In `@pmoves/env.tier-agent.example` around lines 65 - 70, Update the Archon
authentication comment near the Claude/gh live-workflow section to explicitly
identify Archon live workflows as the exception to the TensorZero-only policy,
and state that CLAUDE_API_KEY and CLAUDE_CODE_OAUTH_TOKEN must not be copied or
provided to other agent-tier services.

POWERFULMOVES added a commit that referenced this pull request Aug 23, 2026
archon boots healthy, passes its health check, and dies on the first
workflow with `billing_error: Credit balance is too low`. The cause is not
a missing value, it is a missing slot.

env.tier-agent.example has declared CLAUDE_CODE_OAUTH_TOKEN since PR #2359,
and both compose files wire `${CLAUDE_CODE_OAUTH_TOKEN:-}` into the archon
service. But the label was never in the CHIT registry, so the funnel had no
route for it and the live env.tier-agent carries none of the five Claude
auth vars the example promises.

Meanwhile ANTHROPIC_API_KEY is a registered slot, is set fleet-wide from
env.shared, and the Claude CLI PREFERS it over the OAuth token. archon says
so in its own source: "the CLI prefers ANTHROPIC_API_KEY over the OAuth
token, so injecting the install key alongside it would silently rebill the
run". So the metered key wins and the coding plan never gets a chance.

MODEL_FABRIC_CONTRACT.md:44 already lists `Claude Code Max` in the approved
coding-plan inventory. This is a missing slot, not a new policy decision.

Registered via the sanctioned path only -- registry entry, then
chit-manifest-register, then chit-manifest-sync. No manifest was hand-edited.

NECESSARY BUT NOT SUFFICIENT. This routes the label; it does not conjure a
value. secrets_sync.py skips an entry entirely when no source value exists
(`if source_key is None: continue`), so until a token is provisioned into
the CGP source the key is emitted NOT AT ALL -- not emitted empty. That is
the same blank-is-not-absent rule #2688 established: an empty secret is not
a secret, so absent stays absent. archon therefore behaves exactly as it
does today until the value lands. No regression, and no fix yet either.

SECOND FIX, unavoidable and deliberate: the same sync emits `min_length: 64`
onto secret_key_base in the v1 manifest. PR #2688 added that constraint to
the registry, to v2, and to the sync logic, but never re-ran the sync -- and
secrets_sync.py reads v1 (tools/secrets_sync.py:336). So the min-length gate
shipped in #2688 has been INERT on main: the constraint lived in v2 and in
the tooling while the file the enforcer reads never carried it. It could not
be excluded here without hand-editing a machine-emitted file, which the
pipeline forbids, so it ships with this change rather than silently.

Gates:
- chit-manifest-register --check: manifest complete, no constraint drift
- negative-tested: an unregistered label fails the check with Error 1
- secrets-funnel run end to end: 0 errors, env.tier-agent regenerated

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X9mpK1ZFjexjthZbvcb94f
POWERFULMOVES added a commit that referenced this pull request Aug 23, 2026
…ugh (#2700)

* fix(secrets): the Claude coding-plan token had no slot to arrive through

archon boots healthy, passes its health check, and dies on the first
workflow with `billing_error: Credit balance is too low`. The cause is not
a missing value, it is a missing slot.

env.tier-agent.example has declared CLAUDE_CODE_OAUTH_TOKEN since PR #2359,
and both compose files wire `${CLAUDE_CODE_OAUTH_TOKEN:-}` into the archon
service. But the label was never in the CHIT registry, so the funnel had no
route for it and the live env.tier-agent carries none of the five Claude
auth vars the example promises.

Meanwhile ANTHROPIC_API_KEY is a registered slot, is set fleet-wide from
env.shared, and the Claude CLI PREFERS it over the OAuth token. archon says
so in its own source: "the CLI prefers ANTHROPIC_API_KEY over the OAuth
token, so injecting the install key alongside it would silently rebill the
run". So the metered key wins and the coding plan never gets a chance.

MODEL_FABRIC_CONTRACT.md:44 already lists `Claude Code Max` in the approved
coding-plan inventory. This is a missing slot, not a new policy decision.

Registered via the sanctioned path only -- registry entry, then
chit-manifest-register, then chit-manifest-sync. No manifest was hand-edited.

NECESSARY BUT NOT SUFFICIENT. This routes the label; it does not conjure a
value. secrets_sync.py skips an entry entirely when no source value exists
(`if source_key is None: continue`), so until a token is provisioned into
the CGP source the key is emitted NOT AT ALL -- not emitted empty. That is
the same blank-is-not-absent rule #2688 established: an empty secret is not
a secret, so absent stays absent. archon therefore behaves exactly as it
does today until the value lands. No regression, and no fix yet either.

SECOND FIX, unavoidable and deliberate: the same sync emits `min_length: 64`
onto secret_key_base in the v1 manifest. PR #2688 added that constraint to
the registry, to v2, and to the sync logic, but never re-ran the sync -- and
secrets_sync.py reads v1 (tools/secrets_sync.py:336). So the min-length gate
shipped in #2688 has been INERT on main: the constraint lived in v2 and in
the tooling while the file the enforcer reads never carried it. It could not
be excluded here without hand-editing a machine-emitted file, which the
pipeline forbids, so it ships with this change rather than silently.

Gates:
- chit-manifest-register --check: manifest complete, no constraint drift
- negative-tested: an unregistered label fails the check with Error 1
- secrets-funnel run end to end: 0 errors, env.tier-agent regenerated

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X9mpK1ZFjexjthZbvcb94f

* fix(secrets): route the OAuth token into the runner bundle too

Review on #2700 caught that the manifest slot alone does not reach production
or self-hosted nodes. sync-secrets-local.yml builds the CGP bundle solely from
its explicit env: map, and the v1 sync discards github_secret targets -- so a
registered label with no row in that map funnels nothing on any node hydrated
from the bundle. Archon would keep the metered-key behaviour this change set
exists to fix.

The workflow says so in its own comment, two lines above where the key was
missing: "Absent from this map = never delivered."

Adds CLAUDE_CODE_OAUTH_TOKEN beside the other prod-environment-scoped
coding-plan keys (ALIBABA_PRO_CODING_PLAN, KIMI_CODING_API, KILOCODE_API_KEY),
which is where it belongs -- it is the same class of credential and resolves
the same way under environment: prod.

This is the third routing layer the token has to cross: the registry entry so
the manifest emits it, this map so the bundle carries it, and the GitHub prod
secret so there is a value at all. Declaring a value and routing a value are
separate acts, and only the last one is load-bearing.

YAML re-parsed clean after the edit.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X9mpK1ZFjexjthZbvcb94f

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

compose Compose files / service Dockerfiles docs Documentation governance AGNOTE register / agent definitions / damage-control hooks

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants