Skip to content

v0.2.1

Choose a tag to compare

@dcx dcx released this 06 Jul 22:59
b48754a

Shepherd 0.2.1 — Claude CLI lane diagnostics, interrupted-run recovery, and hardening.

This release packages PRs #24#29. Highlights:

Fixed — the Claude CLI agent lane (#23)

The claude CLI (headless) lane is the supported public agent provider, and this release makes
its failures diagnosable and its preflight honest (PRs #27, #28):

  • Actionable failures. A nonzero claude exit now surfaces the CLI's own reason plus a
    remedy — not a blind 300-char tail-slice. Not-logged-in, org-policy access_denied (HTTP 403),
    and rootful root_permission are classified, with the safe envelope scalars kept in the trace.
    A budget_seconds alarm kill (rc=-14) maps to a trace-preserving BudgetExhausted, with a
    hung-body hint when the CLI produced no output at all (e.g. a stale claude version).
  • Fail-fast preflight. A jailed run with no usable credential (or an expired seeded
    subscription login) is refused before launch (auth_missing / auth_expired,
    launch_attempted: false) instead of spending a confined launch that fails not-logged-in.
    Wrappers that authenticate out-of-band can opt back in with SHEPHERD_ALLOW_KEYLESS_CLAUDE=1.
  • Honest doctor. shepherd doctor claude hard-fails an expired subscription token instead of
    reporting a merely readable credential blob as ready, and names which credential source failed
    (config file unreadable, keychain denied/timed out, nothing found). New
    shepherd doctor claude --probe performs a real auth round-trip under the provider's
    scrubbed-config conditions.
  • Recommended for subscription users: export CLAUDE_CODE_OAUTH_TOKEN=$(claude setup-token)
    a long-lived token survives the sandbox; a short-lived signed-in session cannot be refreshed
    from inside it.

Added — interrupted-run recovery (#26)

  • Ctrl-C and SIGTERM now discard cleanly instead of leaving orphaned operations.
  • A dead prior run's orphaned operations auto-recover at run start.
  • New shepherd run repair command, and an honest OrphanedOperationsError that names it.
  • Session-lock reclaim is process-identity authoritative (PID-reuse safe), not time-based.

Internal — engine refactor and hygiene (#24, #25, #29)

  • vcs-core controller extractions + strict-mypy cleanup (behavior-neutral), with the strict gate
    now in CI.
  • Public-surface contract baseline synced (#25).
  • Repo-wide ruff format alignment (#29).

Evidence

  • Lane C jail-enforcement sentinel executed GREEN at the tagged revision on macOS Seatbelt:
    all 10 required ids passed, all 7 jailed legs skip-free. (Linux Landlock remains
    container-gated, unchanged from 0.2.0.)
  • Real-token happy path verified end-to-end on macOS: doctor claude--probe (live auth
    round-trip) → jailed retained run with fail-closed ground.
  • Failure paths (not-logged-in, org-403, rootful, alarm-kill) reproduced in a login-free Linux
    cleanroom and pinned by envelope-fixture tests that run in CI without credentials.

Thanks to the reporter and commenter on #23 for exact envelopes, the Linux datapoint, and the
stale-CLI rc=-14 triage note.

🤖 Generated with Claude Code