Skip to content

Releases: lsfera/agentic-dev

v0.7.1 — headroom OAuth-credential docs correction

Choose a tag to compare

@lsfera lsfera released this 06 Jul 09:03
2339e93

Docs correction: headroom + subscription auth

ANTHROPIC_API_KEY is not required to use the headroom compression proxy with a Claude Pro/Max subscription. ADR-0023, the docker-compose.yml comment, and the README's "Context compression (headroom)" section previously claimed CLAUDE_CODE_OAUTH_TOKEN "does not work" here and that OAuth-through-proxy was unverified — both were stale against the currently pinned ghcr.io/chopratejas/headroom:latest image (v0.27.0).

Corrected via direct source inspection of the running proxy plus a live round trip (two POST /v1/messages calls authenticated with only CLAUDE_CODE_OAUTH_TOKEN, both returning genuine 200s from real Anthropic infra):

  • #103 — ADR-0023 addendum + docker-compose.yml comment fix
  • #104 — README's "Context compression (headroom)" section fix (the more prominent doc most adopters read first)

No functional/code changes — docs-only release.

v0.7.0 — transient-error retry resilience, headroom investigation closed

Choose a tag to compare

@lsfera lsfera released this 04 Jul 00:29
7097fb4

Highlights

Sandbox runs now survive transient network blips. Live dogfooding kept hitting real, non-deterministic failures — API Error: Server disconnected mid-run — that had nothing to do with the task itself but still burned a full orchestrator-level retry (issue #76's ready-for-agent re-queue) to recover from. sandbox.run() calls are now wrapped in a backoff retry gated by a new isTransientAgentError classifier, so a genuine network hiccup is retried in place instead of requeuing the whole issue — while errors retrying can't fix (session limits, auth failures) still fail immediately rather than wasting attempts (#102). The retry helper itself moved out of main.ts into a standalone retry.ts so both main.ts and sandbox-runner.ts can use it without a circular import.

Headroom compression investigation closed out (#100). Following up on v0.6.0's "0% savings, off by default" finding: a safe, working tuning combination does exist (HEADROOM_SAVINGS_PROFILE=balanced + HEADROOM_PROTECT_RECENT=2) — verified both at the SDK level (18139→92 tokens, −99.5%, zero risk to user messages) and live, on a real multi-turn sandbox run reading a large file end-to-end. But net dollar savings still measure ~$0 on real Claude Code traffic, because Anthropic's own native prompt-caching already protects nearly all reusable context — headroom's compression has negligible marginal value once that's accounted for. Conclusion: HEADROOM_MODE=off stays the correct shipped default; the tuning knobs are real but undocumented upstream internals, left as a documented manual opt-in for anyone who wants to experiment, not something wired into docker-compose.yml.

Dependency maintenance. @ai-hero/sandcastle bumped 0.10.0 → 0.12.0. This also retired a dead patch-package patch left over from PR #85 — it typed a promptCompression callback field this codebase never actually adopted (compression is applied directly to the prompt string before run() is called, not via that callback), and it no longer applied cleanly against 0.12.0 anyway (#101).

Images

  • ghcr.io/lsfera/agentic-dev/devcontainer:0.7.0 (also :0.7, :latest) — multi-arch (amd64/arm64), baked at this commit with everything above included.

Full changelog: v0.6.0...v0.7.0

v0.6.0 — durable crash recovery, honestly-evaluated headroom compression, visible AI review feedback

Choose a tag to compare

@lsfera lsfera released this 03 Jul 11:43
61aad46

Highlights

Durable agent lifecycle labels — crash recovery for /afk (#79 / #92). agent:in-progress and agent:in-review are now written to the issue at each transition and read back once at orchestrator boot, so work left mid-flight by a crashed predecessor is recovered instead of silently stuck. A label-ordering bug found during re-review — agent:in-review was being attached after the review had already finished, since main.ts processes finish-actions sequentially and the review handler awaits the whole review inline — was fixed on the same branch before merge, so the label is actually durable for the full duration of the review, not just retroactively correct.

Headroom compression: routed correctly, then honestly evaluated. This release closes out the full arc from wiring to verified real-world behavior:

  • The compose proxy (#89) and full-session routing (#90) landed, then a doubled-entrypoint bug was silently crash-looping the proxy container since day one (#94).
  • Once the proxy was actually up, a deeper bug surfaced: @ai-hero/sandcastle 0.10.0 silently discards AgentProvider.env on the createSandbox() + .run() path this repo uses — ANTHROPIC_BASE_URL was being set but never reaching the running container. Root-caused by reading sandcastle's own source rather than guessing; fixed by moving the override onto the docker() sandbox provider's own env field instead (#97).
  • With routing actually verified live (real /stats deltas, real token/cost counters), #84's Phase 1 validation (#96) measured the real number: 0% compression savings, live, twice, under both conservative and aggressive modes. A follow-up investigation (#100) traced this to Headroom's own default behavior — it correctly protects user-authored instructions and short conversations from compression — and then verified, via a live sandbox run, that forcing that protection off (HEADROOM_SAVINGS_PROFILE=agent-90) does produce real savings but also reliably destroys the agent's own task instructions, causing complete task failure. Net result: compression ships off by default and stays that way — the mechanism is now proven correct end-to-end rather than assumed to work, and the unsafe workaround is ruled out with evidence instead of left as a tempting unknown.

AI review feedback is now actually visible to a human. Two bugs were silently swallowing every review verdict:

  • The reviewer was authenticating with a depleted API key instead of the working Claude subscription token, so every review call failed outright (#98).
  • Once that was fixed, GitHub's own API rejects REQUEST_CHANGES reviews from a PR's own author (gh's single token both opens every PR and posts its review) — a structural 422 on every single attempt. postPrReview now falls back to a plain PR comment carrying the same verdict and inline notes when the formal review API is unavailable (#99).

Smaller fixes, all live-discovered during dogfooding:

  • docker-outside-of-docker's socket permission fixup never ran under a bare docker compose up (only under the CLI-injected devcontainer up wrapper), breaking every sandbox attempt; .sandcastle/node_modules's platform-specific deps could also drift when the bind mount was last touched by the wrong OS (#91).
  • gh issue create --label agent:memory fails outright if the label doesn't already exist — gh never auto-creates labels — which had been silently failing every cross-run memory write since v0.5.0 shipped. createIssue() now ensures every label it uses exists first, idempotently (#93).

Images

  • ghcr.io/lsfera/agentic-dev/devcontainer:0.6.0 (also :0.6, :latest) — multi-arch (amd64/arm64), baked at this commit with everything above included.

Full changelog: v0.5.0...v0.6.0

v0.5.0 — AI review gate, bounded retry, cross-run agent memory

Choose a tag to compare

@lsfera lsfera released this 02 Jul 11:06
cca2170

Highlights

AI review gate lands before auto-merge (#74). /afk now runs a read-only reviewer sandbox on every PR branch — diff + ADRs + acceptance criteria in, a structured pass/changes-requested verdict out — and gates auto-merge on it instead of merging on green CI alone. Two hardening fixes landed on top after real-world runs exposed bugs:

  • Single-pass produce (#80): the produce pass was re-running up to 8× instead of once; pinned to maxIterations: 1.
  • Pass-2 crash fix (part of #85): the extraction pass's compressed branch was dropping name/maxIterations when resuming the session, reintroducing the same class of bug as #80 through a different path.

Failed sandboxes now retry automatically (#76). A sandbox that throws or produces no commits gets re-labelled ready-for-agent and picked up again next tick, bounded by Policy.maxRetries (default 2) — no more silent drops, no infinite loop either. Attempt counts are in-run only for v1 (documented limitation in CLAUDE.md); cross-run persistence is exactly what memory (below) starts to close.

Cross-run agent memory (#86 / #87, ADR-0022). Sub-agents can now leave notes for their future selves and each other, persisted as comments on a pinned per-repo GitHub issue (agent:memory label) — no new infra, GitHub issues stay the single source of durable state. Three categories, each with its own retrieval rule:

  • repo-convention — agent-emitted, always injected in full.
  • gotcha — agent-emitted, capped at the last 5.
  • outcome — orchestrator-emitted automatically at every terminal state (success or retries-exhausted), capped at the last 5.

Retrieval is implementing-agent-only (the reviewer never sees it, so memory can't bias its verdict), and every read/write fails open — a memory hiccup degrades to an empty context, never blocks a run or burns a retry.

Context compression (headroom-ai) landed off-by-default (part of #85) — HEADROOM_MODE=conservative|aggressive shrinks compiled prompts before they reach the agent. Ships inert (off by default) in this release; wiring it into docker-compose.yml for cockpit-mode use is in flight.

Execution layer leaned out (#72): sandbox-runner.ts now uses sandcastle's high-level createSandbox lifecycle (await using for deterministic teardown, declarative onSandboxReady hooks) instead of a bespoke try/finally — less code, same guarantees.

This release's own build was caught by its own bar. While preparing it, verification turned up that publish-devcontainer.yml's path filter only watched .devcontainer/**, even though the image bakes .sandcastle via git clone at build time — an orchestrator-only push never triggered a rebuild. No rebuild had run since PR #71 (2026-06-28), so everything above was baked-image-stale until #88 added .sandcastle/** to the filter (and, found in the same pass, fixed a docker-compose.yml bug where forwarding GH_TOKEN/GITHUB_TOKEN as two separate ${VAR:-} lines broke gh's own fallback for anyone who only exports GITHUB_TOKEN). This tag is the first build produced under the fixed trigger.

Images

  • ghcr.io/lsfera/agentic-dev/devcontainer:0.5.0 (also :0.5, :latest) — multi-arch (amd64/arm64), baked at this commit with everything above included.

Full changelog: v0.4.0...v0.5.0

v0.4.0 — cockpit mode + autonomous /afk empty-turn fix

Choose a tag to compare

@lsfera lsfera released this 28 Jun 15:33
22fd564

Highlights

Cockpit mode lands — drive the full /grill → /to-issues → /afk workflow from inside the published outer image, no host-side Claude required.

  • Slice A (#67): the baked workflow commands now run end-to-end from within the container.
  • Slice B (#68): detached /afk and /hitl with a run-mode resolver, so the orchestrator can be launched in the background and monitored.

The autonomous /afk empty-turn bug is fixed (#71). The docker-outside-of-docker feature fronts the host docker socket with a socat proxy, which tears down docker exec's hijacked bidirectional stream after the first data burst. sandcastle streams the agent's stream-json over docker exec, so only system/init survived — every agent turn silently emptied out (commits=0, "Agent started → Agent stopped"). The orchestrator now detects the proxy and points its docker CLI at the real socket (/var/run/docker-host.sock), bypassing socat:

  • resolveDockerHost() in .sandcastle/main.ts — a guarded, pure decider (4 tests). No-op when an explicit DOCKER_HOST is set, or when the direct socket is absent (so a bare docker compose up, which has no socat and no direct socket, is untouched).
  • Proven end-to-end: with the fix in place, #67 and #68 were both implemented and merged autonomously (commits=1, completed=true) instead of 2-second empty turns.

This is the second distinct empty-turn cause root-caused in agentic-dev — the first was an MTU mismatch on Docker's default bridge (v0.x). Both stemmed from the inner sandbox's docker plumbing.

Images

  • ghcr.io/lsfera/agentic-dev/devcontainer:0.4.0 (also :0.4, :latest) — multi-arch, baked at this commit with the fixed orchestrator source.

Full changelog: v0.3.0...v0.4.0

v0.3.0 — baked workflow commands + upstream skills; standalone compose

Choose a tag to compare

@lsfera lsfera released this 26 Jun 15:44
ea6459e

Highlights

The published image now bakes the workflow itself (ADR-0017):

  • User-invoked slash commands (/afk, /hitl, /exec, /to-prd, /to-issues, /tdd, /grill-me-with-docs) at /opt/agentic-commands — the project's own (coupled to the sandcastle flow), so they stay vendored.
  • Four model-invoked engineering disciplines (tdd, diagnosing-bugs, domain-modeling, codebase-design) pulled from mattpocock/skills (MIT) at /opt/agentic-skills.
  • claude-persist-setup installs them into ~/.claude/commands and ~/.claude/skills at container creation.

docker-compose.yml boots standalone — every variable carries a fallback (LOCAL_WORKSPACE_FOLDER:-${PWD}, …), so a bare docker compose up from a project root works with no .env and no init.sh. ${PWD} preserves the path-matched mount (ADR-0011); init.sh is now an optimization, not a requirement.

Groundwork toward distributing only the compose file. The baked ~/.claude commands/skills are consumed by a claude running inside the container; the current flow runs Claude on the host, so they're inert for the host flow until that inversion lands.

Images

  • ghcr.io/lsfera/agentic-dev/devcontainer:0.3.0 (also :0.3, :latest) — multi-arch, baked at this commit.
  • Inner sandbox images republished at the same tag.

Full changelog: v0.2.0...v0.3.0

v0.2.0 — orchestrator baked into the outer image

Choose a tag to compare

@lsfera lsfera released this 26 Jun 09:04
273b527

Highlights

  • The outer image now bakes the orchestrator (#58, ADR-0016). The published ghcr.io/lsfera/agentic-dev/devcontainer image ships the orchestrator source at /opt/agentic-orchestrator, so adopters can run without vendoring .sandcastle/*.ts — keep only your config in .sandcastle/ (orchestrator.env, .env, opencode.json) and run afk/hitl.
  • No more per-run npm installrun.sh installs deps only when missing/stale (once per container).
  • run.sh/afk prefer a workspace .sandcastle/ when it carries the source (this repo and vendoring adopters are unchanged), else fall back to the baked copy (AGENTIC_ORCHESTRATOR_HOME overrides).

Safety

  • The image bakes committed code only (git-fetched at the build sha), so gitignored secrets (.sandcastle/.env, orchestrator.env) are never baked — verified absent from the built image.
  • Bake is build-arg-gated; the local compose/devcontainer build stays lean and builds from source as before.

Images at :v0.2.0

  • ghcr.io/lsfera/agentic-dev/devcontainer:v0.2.0 (outer — now with baked orchestrator)
  • ghcr.io/lsfera/agentic-dev/sandbox:v0.2.0, sandbox-opencode:v0.2.0 (inner)

Full changelog: v0.1.3...v0.2.0

🤖 Generated with Claude Code

v0.1.3 — outer orchestrator image (build fix)

Choose a tag to compare

@lsfera lsfera released this 26 Jun 07:21
ce66a0d

Fixes the outer-image publish that failed in v0.1.2 (--platform or --push not supported — the devcontainer CLI rejects those flags for compose configs). The publishable image now builds from a dockerfile-based config (devcontainer.build.json).

Images at :v0.1.3

  • ghcr.io/lsfera/agentic-dev/devcontainer:v0.1.3 (outer — first successful publish)
  • ghcr.io/lsfera/agentic-dev/sandbox:v0.1.3 (inner, claude)
  • ghcr.io/lsfera/agentic-dev/sandbox-opencode:v0.1.3 (inner, local)

Full changelog: v0.1.2...v0.1.3

🤖 Generated with Claude Code

v0.1.2 — outer orchestrator image + pinned inner images

Choose a tag to compare

@lsfera lsfera released this 26 Jun 07:17
e09cf18

Highlights

  • Outer orchestrator image published to GHCR (#53, ADR-0015): ghcr.io/lsfera/agentic-dev/devcontainer, multi-arch. The devcontainer the orchestrator runs in, features baked in — adopters can skip the local ~2.3 GB build. Built with the devcontainer CLI (devcontainer build --push).
  • Pinned prebuilt images to a version tag (:v0.1.x) instead of :latest in the README and orchestrator.env.example, for reproducible runs.
  • Bugfix: .devcontainer/.dockerignore now allowlists afk, fixing a COPY afk failure that would have broken ./up.sh . rebuilds after v0.1.1.

Images at :v0.1.2

  • ghcr.io/lsfera/agentic-dev/devcontainer:v0.1.2 (new — outer)
  • ghcr.io/lsfera/agentic-dev/sandbox:v0.1.2 (inner, claude)
  • ghcr.io/lsfera/agentic-dev/sandbox-opencode:v0.1.2 (inner, local)

Full changelog: v0.1.1...v0.1.2

🤖 Generated with Claude Code

v0.1.1 — baked-in afk/hitl launchers

Choose a tag to compare

@lsfera lsfera released this 26 Jun 07:00
7d8c477

Highlights

  • Ergonomic afk / hitl commands baked into the devcontainer image (#52). Run afk [tier] [model] [flags] or hitl … from anywhere inside a project instead of .sandcastle/run.sh afk …. The launcher resolves the project root and sets LOCAL_WORKSPACE_FOLDER from .devcontainer/.env, so the run honours the path-matched host mount (ADR-0011) regardless of cwd. afk --dry-run prints the resolved env without launching.

Notes

  • The commands land in the outer devcontainer image, so they appear after a devcontainer rebuild (./up.sh . with a rebuild).
  • Inner sandbox images are also published at :v0.1.1 (ghcr.io/lsfera/agentic-dev/{sandbox,sandbox-opencode}); unchanged from v0.1.0.

Full changelog: v0.1.0...v0.1.1

🤖 Generated with Claude Code