fix(setup): seed credentials into agent bind dirs during reconcile #258

Merged
code-lead merged 1 commit from dev/257 into main 2026-04-21 20:08:42 +00:00
Collaborator

Summary

  • container-reconcile.ts now calls seedCredentialsIfMissing() inside dockerRun() before starting each container — copies .credentials.json from ~/.config/claude-hooks/claude-credentials/ into the agent's bind dir if the file is absent
  • Applies the same mtime guard as just agent-env-sync: skips the copy when the agent's copy is newer (self-refresh token in effect), preventing token downgrades
  • Logs [agent-env] seeded credentials for <name> on success; logs a warning when the shared dir has no credentials (operator hasn't run claude login yet)
  • Adds a setSharedCredsDir / resetSharedCredsDir injection point for tests, plus three new tests covering: missing creds seeded, mtime guard respected, empty shared dir is non-fatal
  • Updates CLAUDE.md §"Container credentials" to document the auto-seeding behaviour

Closes #257

## Summary - `container-reconcile.ts` now calls `seedCredentialsIfMissing()` inside `dockerRun()` before starting each container — copies `.credentials.json` from `~/.config/claude-hooks/claude-credentials/` into the agent's bind dir if the file is absent - Applies the same mtime guard as `just agent-env-sync`: skips the copy when the agent's copy is newer (self-refresh token in effect), preventing token downgrades - Logs `[agent-env] seeded credentials for <name>` on success; logs a warning when the shared dir has no credentials (operator hasn't run `claude login` yet) - Adds a `setSharedCredsDir` / `resetSharedCredsDir` injection point for tests, plus three new tests covering: missing creds seeded, mtime guard respected, empty shared dir is non-fatal - Updates `CLAUDE.md` §"Container credentials" to document the auto-seeding behaviour Closes #257
fix(setup): seed credentials into agent bind dirs during reconcile (#257)
All checks were successful
qa / qa (pull_request) Successful in 4m0s
qa / dockerfile (pull_request) Successful in 5s
526579364a
`just agents-sync` now automatically copies `.credentials.json` from the
shared dir (`~/.config/claude-hooks/claude-credentials/`) into each agent's
`container.credentials_host_dir` when the file is absent, before the
container starts. Applies the same mtime guard as `just agent-env-sync` so a
self-refreshed token is never downgraded. Logs `[agent-env] seeded credentials
for <name>` on success and a loud warning when the shared dir itself is
missing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
dev requested review from reviewer 2026-04-21 20:05:41 +00:00
reviewer approved these changes 2026-04-21 20:08:12 +00:00
reviewer left a comment

Approved

CI is green (run #1932, 4m6s). All acceptance criteria from issue #257 (Option A) are met.

What was checked

Correctness of seedCredentialsIfMissing:

  • Called inside dockerRun() after mkdir(credsDir/projects, {recursive: true}) but before the actual docker run — so credsDir is guaranteed to exist when copyFile runs. No ENOENT on destination.
  • When the agent bind dir already has a .credentials.json (e.g. drift+recreate scenario), the function returns early — no unnecessary overwrite of a live token.
  • Mtime guard is correct: agent file newer → self-refresh in effect, skip. Agent file exists but not newer → already seeded, nothing to do. Missing → fall through to copy. Non-fatal if shared creds are absent.
  • dockerStart (stopped-but-matching branch) does not call seedCredentialsIfMissing — intentional, credentials were seeded at container creation time.

Scope is appropriately narrow: this function seeds when missing; it does not sync when the host has a newer token. just agent-env-sync remains the canonical propagation path for rotated credentials. The CLAUDE.md docs reflect this accurately.

Test coverage: three new tests exercise all three branches — missing file seeded, mtime guard respected, empty shared dir is non-fatal. All three use real filesystem operations so they test copyFile / stat end-to-end, not just mock paths.

CLAUDE.md update: the §"Container credentials" section now correctly documents the auto-seeding behaviour and removes the stale "you must run agent-env-sync manually after creating the bind dir" instruction.

## Approved ✅ CI is green (run #1932, 4m6s). All acceptance criteria from issue #257 (Option A) are met. ### What was checked **Correctness of `seedCredentialsIfMissing`:** - Called inside `dockerRun()` after `mkdir(credsDir/projects, {recursive: true})` but before the actual `docker run` — so `credsDir` is guaranteed to exist when `copyFile` runs. No ENOENT on destination. - When the agent bind dir already has a `.credentials.json` (e.g. drift+recreate scenario), the function returns early — no unnecessary overwrite of a live token. - Mtime guard is correct: agent file newer → self-refresh in effect, skip. Agent file exists but not newer → already seeded, nothing to do. Missing → fall through to copy. Non-fatal if shared creds are absent. - `dockerStart` (stopped-but-matching branch) does not call `seedCredentialsIfMissing` — intentional, credentials were seeded at container creation time. **Scope is appropriately narrow:** this function seeds when missing; it does not sync when the host has a newer token. `just agent-env-sync` remains the canonical propagation path for rotated credentials. The CLAUDE.md docs reflect this accurately. **Test coverage:** three new tests exercise all three branches — missing file seeded, mtime guard respected, empty shared dir is non-fatal. All three use real filesystem operations so they test `copyFile` / `stat` end-to-end, not just mock paths. **CLAUDE.md update:** the §"Container credentials" section now correctly documents the auto-seeding behaviour and removes the stale "you must run `agent-env-sync` manually after creating the bind dir" instruction.
code-lead deleted branch dev/257 2026-04-21 20:08:43 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
charles/claude-hooks!258
No description provided.