Skip to content

fix(local-delivery): let an offline ticket reach done (git in image, no-op deploy success, .env footgun) - #10

Merged
tobyvee merged 1 commit into
mainfrom
fix/local-delivery-reach-done
Jun 27, 2026
Merged

tobyvee merged 1 commit into
mainfrom
fix/local-delivery-reach-done

Conversation

@tobyvee

@tobyvee tobyvee commented Jun 27, 2026

Copy link
Copy Markdown
Owner

Taking a single ticket all the way to done with DELIVERY_BACKEND=local (no GitHub) on a real model surfaced three blockers. All are fixed here and verified live.

Blockers fixed

  1. spawn git ENOENT — the local-git DeliveryAdapter and the QA repo-context reader shell out to git, but the node:24-bookworm-slim image has none. Every commit failed → nothing committed → QA blocked every ticket. Fix: apt-get install git in apps/server/Dockerfile.
  2. Stuck in deploying — the local adapter's deploymentRunAfter() returned null, so checkDeployStatus reported pending forever. There's no deploy target locally; the ship step should complete. Fix: report the no-op deploy as success.
  3. .env footgun — GITHUB_DEPLOY_WORKFLOW= # e.g. deploy.yml: docker compose's env_file parser keeps everything after =, so the trailing comment became the value, tricking startDeploy into dispatching a deploy that can never finish. Fix: moved the comment to its own line in .env.example and documented the footgun.

Convenience

  • POST /api/tickets now accepts description + acceptanceCriteria so a manually-created ticket can carry a real spec for QA to verify (previously hard-coded empty).

Verified live

A self-contained "minimal URL shortener" ticket ran the full lifecycle:
implement → code_pushed → qa_passed → [merge gate] → pr_merged → [deploy gate] → deployed(success) → done, with the agent's src/shortener.js merged to the local repo's main branch. Ticket model spend: $0.0045 (Haiku).

Tests

Added a regression test asserting the local no-op deploy reports success. pnpm typecheck · lint · test (103) · build all pass.

🤖 Generated with Claude Code

Three blockers surfaced taking a ticket through the full lifecycle with
DELIVERY_BACKEND=local (no GitHub), plus a route convenience:

- Dockerfile: install `git`. The local-git DeliveryAdapter and the QA
  repo-context reader shell out to git, but node:24-slim has none — every
  commit failed with `spawn git ENOENT`, so nothing was committed and QA
  blocked every ticket.
- local adapter: report the no-op deploy as `success` (was `null` →
  `checkDeployStatus` returned `pending` forever, leaving the ticket stuck in
  `deploying`). There is no deploy target locally; the ship step should
  complete, not poll indefinitely.
- .env.example: move the inline comment off `GITHUB_DEPLOY_WORKFLOW=`. docker
  compose's env_file parser keeps everything after `=`, so the trailing
  `# e.g. deploy.yml` became the value — tricking startDeploy into dispatching
  a deploy that can never finish. Documented the footgun.
- POST /api/tickets now accepts `description` + `acceptanceCriteria`, so a
  ticket can carry a real spec for QA to verify (previously hard-coded empty).

Verified live: a self-contained ticket ran implement → commit → QA pass →
merge gate → deploy gate → done, with the agent's code merged to the local
repo's main branch.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@tobyvee
tobyvee merged commit b626983 into main Jun 27, 2026
1 check passed
@tobyvee
tobyvee deleted the fix/local-delivery-reach-done branch June 27, 2026 06:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant