Skip to content

Latest commit

 

History

History
380 lines (248 loc) · 35.1 KB

File metadata and controls

380 lines (248 loc) · 35.1 KB

Changelog

[Unreleased]

[0.11.6] - 2026-04-20

Fixed

  • Follow-up on the v0.11.5 single-connection switch: workers were hitting Sequel::PoolTimeout: timeout: 5.0 because Sequel's default pool timeout is 5s. With max_connections: 1, any caller mid-iteration on a dataset holds the connection through the entire loop (SQLite keeps the cursor open across .each), and if the loop body does slow external I/O — as poll_unassignment and poll_done_unassigned do, with GitLab API calls per issue — workers waiting for the connection blow through 5s.
    • Raised pool_timeout to 60s for SQLite.
    • Materialized the two poll_unassignment/poll_done_unassigned iterations with .all.each so the DB connection is released before GitLab calls run. Applied the same shape defensively to poll_pipelines / poll_discussions for consistency, though their loop bodies only enqueue (fast).
  • Startup log now includes pool_timeout alongside journal_mode/busy_timeout/max_connections so the effective pool config is visible without re-instrumenting.

[0.11.5] - 2026-04-20

Fixed

  • SQLite database is locked errors are finally gone. The v0.11.2–v0.11.4 attempts relied on Sequel's after_connect hook to apply per-connection PRAGMAs/busy_handler to every pooled connection; in practice the hook did not fire in our setup (confirmed in logs: busy_timeout=0ms at startup, no [DB-LOCK] dumps under contention), which is why increasing timeouts and adding defensive handlers changed nothing. Switched to max_connections: 1 so Sequel's ThreadedConnectionPool serializes all DB access through a Ruby mutex. For SQLite this is strictly better: writes are already serialized at the file level, so multiple pool connections only add contention (and trigger BusyException when writers collide). journal_mode=WAL and busy_timeout=30000 are now applied directly to the single connection via @db.run. Startup logs the effective values so they're visible without re-instrumenting.
  • Dropped the unused after_connect, busy_handler, and thread-backtrace dump code added in v0.11.3–v0.11.4 — the root-cause fix makes them moot.

[0.11.4] - 2026-04-20

Added

  • SQLite busy_handler now dumps all thread backtraces to stderr after 20 retries on the same contention episode (prefixed [DB-LOCK]). Since the handler runs in the thread that is waiting for the lock, the dump captures what every other thread is doing at the exact moment of contention — making it possible to identify which operation is holding the write lock. Diagnostic only; does not change the retry policy.

[0.11.3] - 2026-04-20

Fixed

  • Follow-up on the v0.11.2 SQLite lock fix: 5s busy_timeout was still being exceeded under real-world contention (3 workers + poller all writing). Bump to 30s and add a Ruby-side busy_handler as a safety net in case the PRAGMA is silently ignored on some connection. Also log the effective busy_timeout at startup so the applied value is verifiable from the autodev output.

[0.11.2] - 2026-04-20

Fixed

  • SQLite busy_timeout=5000 PRAGMA is now applied to every connection in the pool via Sequel's after_connect hook, not just the first one. busy_timeout is per-connection, so under worker contention the other pool connections were falling back to the default (0) and raising SQLite3::BusyException: database is locked immediately instead of waiting for the writer lock.

[0.11.1] - 2026-04-14

Changed

  • Usage checker now runs danger-claude -p instead of calling the Anthropic API directly — uses the same Docker environment and auth as the rest of autodev. No API key needed.

[0.11.0] - 2026-04-14

Added

  • Proactive Claude usage check before each poll cycle. Skips the cycle if the account is rate-limited. Result is cached for 5 minutes.

[0.10.2] - 2026-04-14

Fixed

  • Pipeline monitor now checks MR state before dispatching — if the MR is merged or closed, the issue transitions to done immediately instead of attempting mr-review on a branch that no longer exists.

[0.10.1] - 2026-04-13

Fixed

  • Fix CLEAN_ENV constant resolution in PipelineMonitor::Reviewer and IssueProcessor::MrManager — fully qualify as DangerClaudeRunner::CLEAN_ENV (same bug previously fixed in PostCompletion). Was causing non-fatal uninitialized constant PipelineMonitor::Reviewer::CLEAN_ENV errors that skipped mr-review on every green pipeline.
  • Activity log timestamps now include the date (MM-DD HH:MM) and use the host's local timezone instead of UTC. Previously logs spanning multiple days were ambiguous (just HH:MM) and times were displayed in UTC even though the autodev host runs in CEST.
  • On reentry (donepending when label_todo is re-applied), the activity_note_id is now reset so a fresh activity log comment is created at the bottom of the issue thread. Previously the existing activity log was edited in place, leaving it stranded above any user comments posted between the two runs and giving the impression that autodev was idle.

[0.10.0] - 2026-04-10

Changed

  • Renamed label_mr config key to label_done (internal rename, GitLab label value unchanged). The old label_mr key is now deprecated with a warning.

Added

  • Localized notification comment posted on the issue when autodev finishes normally (done_nominal): explains how to relaunch autodev or move on.
  • Localized notification comment posted on the issue when a question/investigation is complete (done_question): explains how to go further or request an implementation.

[0.9.1] - 2026-04-10

Fixed

  • Pipeline fixer now checks git log output content (not just exit status) to detect new commits before pushing, matching the correct pattern already used in MrFixer.
  • Legacy status migration no longer resets legitimately done issues with an MR back to checking_pipeline on every startup. Only the extinct mr_fixed status is migrated.
  • Branch names with slashes no longer create nested subdirectories in /tmp for context files.

Changed

  • Extracted default_branch, push_with_lease_fallback, and safe_mark_failed! into DangerClaudeRunner to eliminate duplication across IssueProcessor, MrFixer, and PipelineMonitor.

Added

  • pickup_delay config (default 600s): prevents processing issues created less than N seconds ago, giving authors time to finalize specs.
  • stagnation_threshold config (default 5): consecutive identical failures before marking an issue as done with an alert.
  • Reviewer module in PipelineMonitor: runs mr-review after the first green pipeline instead of immediately after MR creation. Review count incremented only on successful execution. Hard limit of 3 review rounds.
  • Stagnation detection for both pipeline failures (SHA256 of failed job names) and unresolved discussions (SHA256 of discussion IDs). Replaces max_fix_rounds.
  • Unassignment detection: active issues no longer assigned to autodev transition to done at the next poll cycle.
  • post_completion now triggers when autodev is unassigned from a done issue (instead of immediately after pipeline green). Skipped if MR is already merged or closed.
  • Reentry: done issues with label_todo detected at poll time transition back to pending via reenter!, resetting stagnation signatures and review count.
  • New DB columns: review_count (INTEGER DEFAULT 0), stagnation_signatures (TEXT, JSON).
  • Per-project app: config block with optional setup, test, and lint subsections. Each subsection accepts a list of commands (Docker CMD format) that are passed to danger-claude prompts as environment-specific instructions. Validated at boot with clear error messages.
  • AppInstructions module: formats app: config into a prompt section injected in all danger-claude prompts (implementer, split/parallel, pipeline fixer, MR fixer). Instructions are marked as taking priority over CLAUDE.md and skills.
  • app.run config: list of background server commands with optional port for Docker port exposure. Ports are dynamically allocated on the host via PortAllocator and mapped to container ports. Resolved URLs (http://localhost:<host_port>) are injected into prompts for Chrome DevTools access.
  • PortAllocator module: allocates ephemeral host ports via TCPServer and generates danger-claude -P args for Docker port mappings.
  • ScreenshotUploader module: reads screenshot index written by Claude in the shared /tmp directory, uploads each PNG to GitLab via client.upload_file, and posts a formatted comment on the issue. Supports mr_fix context annotation. Integrated after implementation and after MR discussion fixes.
  • Screenshot prompt instructions injected when app.run is configured: tells Claude to capture impacted pages after implementation, save PNGs with an index.json manifest in a shared directory.

Changed

  • State machine overhaul (v0.10): terminal state renamed from over to done. blocked state removed entirely — infrastructure failures and canceled pipelines now stay in checking_pipeline until manual intervention or natural resolution.
  • Review after pipeline: mr-review now runs after the first green pipeline instead of immediately after MR creation. mr_created! transitions directly to checking_pipeline (no intermediate reviewing step).
  • Polling by assignee: replaced trigger_label-based polling with assignee_id-based polling filtered by labels_todo.
  • 3 labels only: simplified label workflow to labels_todo, label_doing, label_mr. Label stays label_doing during the entire cycle and switches to label_mr only on done.
  • Chrome DevTools is now auto-enabled when any project has app.run entries with exposed ports. The chrome_devtools config flag has been removed — Chrome and MCP injection are managed automatically.

Removed

  • blocked state and all associated label management (label_blocked, apply_label_blocked).
  • trigger_label config (replaced by assignee-based polling).
  • max_fix_rounds config (replaced by stagnation detection).
  • label_done and label_blocked config fields (deprecated with warnings).
  • labels_to_remove / label_to_add deprecated config fields.
  • pipeline_failed_infra! and pipeline_canceled! events.
  • resume_todo! and resume_mr! events (replaced by reenter!).
  • review_complete! event (replaced by review_done!).

Fixed

  • Fix new_commits? in MrFixer always returning true: git log exits 0 even with empty output, so the check must verify output is non-empty. Previously finalize_no_commits was dead code — the push path was always taken even when discussion fixes produced no changes.
  • Fix misleading log message in finalize_green_done: always said "no discussions" regardless of actual discussion count.
  • Fix port allocation TOCTOU race in PortAllocator: hold TCPServer sockets open until the consuming subprocess has started, preventing the OS from reassigning the port between allocation and Docker bind.

Changed

  • Replace WorkerPool busy-polling (pop(true) + sleep 0.5) with blocking Queue#pop. Idle workers now sleep on the queue instead of polling at 2Hz. Shutdown uses nil sentinels to unblock threads.

[0.9.0] - 2026-04-07

Added

  • GitLab activity log: each issue now gets a single, continuously updated comment that tracks every autodev action in real time — processing start, clone, spec check, implementation, push, MR creation, review, pipeline checks, discussion fixes, errors, retries, resume events, and polling. Localized in French and English (41 activity templates per locale). Powered by a new ActivityLogger module with both instance (log_activity) and class (ActivityLogger.post) entry points, and activity_note_id / pipeline_poll_since columns. Pipeline polling lines are compacted: repeated checks update a single line showing the time of the first poll (🔍 Polling pipeline status since 18:20...) instead of creating a new line per cycle. Resume events (resume_todo, resume_mr) are now logged when an issue re-enters the processing pipeline after human intervention.
  • Chrome DevTools MCP support: new chrome_devtools config option launches headless Chrome with remote debugging and injects the MCP server config, proxy, and skill into danger-claude containers.
  • ChromeLauncher module: detects/launches Chrome with --remote-debugging-port=9222 --headless=new.
  • ChromeDevtoolsInjector module: injects mcpServers.chrome-devtools into the Docker volume's .claude.json and provides bind-mount args for proxy scripts and skill.

[0.8.5] - 2026-04-07

Fixed

  • Fix CLEAN_ENV constant resolution in PostCompletion module — fully qualify as DangerClaudeRunner::CLEAN_ENV.

[0.8.4] - 2026-04-07

Fixed

  • Fix PostCompletion#run_with_timeout shadowing ProcessRunner#run_with_timeout, causing ArgumentError: wrong number of arguments (given 3, expected 5) when PipelineMonitor runs danger-claude during pipeline fixes.

[0.8.3] - 2026-04-03

Fixed

  • Fix label workflow routing: issues in pending state with label_mr are now correctly routed to processing instead of being silently skipped. Previously, only label_todo triggered processing for pending issues.

[0.8.2] - 2026-04-03

Fixed

  • Fix issues with existing MRs reset to pending on startup recovery: recover_stuck_processing! now resumes at checking_pipeline when the issue already has a MR, matching the behaviour of recover_errored!.

[0.8.1] - 2026-04-03

Added

  • Comprehensive config validation (Config.validate!) at startup: validates global numeric fields are positive integers, log_level is a valid level, gitlab_token is present, and per-project fields (path required, post_completion must be array of strings, post_completion_timeout requires post_completion, clone_depth non-negative, sparse_checkout array of strings).
  • Localized GitLab issue comments: language is auto-detected from the issue body (French/English heuristic via function-word frequency) and stored in a locale column. All 14 notify_issue calls now use locale-aware templates (Locales.t).
  • JSON Lines structured log files (.jsonl): log files now emit one JSON object per line with timestamp, level, project, issue_iid, state, event, message, and context fields for LLM consumption. Console output remains human-readable with colors.
  • Minitest test suite with 278 tests covering state machine transitions and guards, startup recovery, pipeline pre-triage classification, config validation, language detection, locales, logger JSON output, and error classes.

Changed

  • Refactor all modules to fix Metrics RuboCop offenses: extract LabelManager, IssueNotifier, and ProcessRunner from DangerClaudeRunner; decompose IssueProcessor, PipelineMonitor, MrFixer, SkillsInjector, GitlabHelpers, Config, Database, and bin/autodev into focused sub-modules.
  • Hoist GitLab client and MrFixer helper instantiation above the error retry loop so they are reused across retried issues in the same poll tick instead of being recreated per issue.
  • Deduplicate error retry branches: the MR vs non-MR paths now share a single code path that selects the transition method, label, and log target based on mr_iid presence.

Fixed

  • Write context files to /tmp instead of the git work tree so they cannot be accidentally committed by danger-claude. Mount /tmp into the container via -v /tmp.
  • Use process groups (pgroup: true) for subprocess spawning so that timeout kills (TERM/KILL) reach the entire process tree, not just the direct child. Prevents orphaned grandchild processes (e.g., Docker containers) from lingering after a timeout.
  • Fix NoMethodError: private method 'cleanup_labels' called for an instance of MrFixer when polling detects a done label.
  • Fix issues stuck on label_doing after error retry: restore labels_todo on retry so the polling loop picks them up correctly.
  • Fix issues with existing MRs restarting from scratch after error retry: resume at checking_pipeline instead of pending.

[0.8.0] - 2026-04-02

Added

  • Label-driven workflow: new per-project config fields labels_todo (array), label_doing, label_mr, label_done, label_blocked replace labels_to_remove/label_to_add with a full lifecycle. Labels are set/removed at each state transition: labels_todolabel_doing (processing) → label_mr (MR created, discussion monitoring) → label_done (set by reviewer, triggers cleanup). label_blocked is set on infra failures or max fix rounds.
  • Resume from over: issues in over state can be re-activated via labels. Adding a labels_todo label triggers full re-processing (spec check → implement → MR). Leaving label_mr with unresolved MR discussions triggers automatic discussion fix. New AASM events: resume_todo! (over → pending), resume_mr! (over → fixing_discussions).
  • Context file: issue context (title, body, comments) and all MR discussions (resolved + unresolved) are written to a single markdown file at the clone root (named after the branch, e.g. 123-fix-login.md). All prompts reference this file instead of embedding context inline. File is deleted after each danger-claude call.
  • Per-project post_completion hook: configurable command (Docker CMD format, e.g. ["./bin/deploy", "--env", "staging"]) executed after pipeline green and discussions resolved, just before over. New running_post_completion state. Non-fatal — errors are logged and visible in --errors. Environment variables AUTODEV_ISSUE_IID, AUTODEV_MR_IID, AUTODEV_BRANCH_NAME available. Timeout configurable via post_completion_timeout (default 300s).
  • Issue assignment management: autodev assigns itself to the issue when starting work, then reassigns the issue author when reaching over (question answered or pipeline green).
  • New code-conventions skill injected into all projects: language-agnostic rules for code comments (WHAT/WHY/HOW) and commit messages (Conventional Commits). Previously these rules were embedded in the Rails-specific skill and ignored for JS/other languages.
  • All prompts (implementation, MR fix, pipeline fix) now explicitly list the skills to load (e.g. code-conventions, rails-conventions, etc.) before starting work.
  • --version / -v CLI flag to display the current version.
  • Version tag now appears in every GitLab comment (e.g. :robot: **autodev** (v0.7.0) : traitement en cours...).

Changed

  • needs_clarification now sets the first labels_todo label (removing label_doing), enabling re-processing when a human responds.
  • question_answered now removes label_doing without adding any label back — the human decides the next step by manually setting a label. This avoids an infinite loop where the question would be re-detected every poll cycle.
  • Crash recovery: issues stuck in active processing states (cloning, checking_spec, implementing, etc.) are now reset to pending on startup. In label workflow, this means label_doing issues are recovered automatically.
  • rails-conventions skill no longer contains Code Comments and Commit Messages sections — these are now in the language-agnostic code-conventions skill.

Deprecated

  • labels_to_remove and label_to_add project config fields. Still accepted but emit a deprecation warning to stderr. Use the new label workflow fields instead (labels_todo, label_doing, label_mr, label_done, label_blocked).

[0.7.0] - 2026-03-31

Added

  • Question/investigation ticket handling: autodev now recognizes tickets that ask questions about existing behavior (not implementation requests), investigates the codebase, and posts an answer as a GitLab comment instead of attempting code changes. New state answering_question with events question_detected and question_answered.

Changed

  • Spec check now instructs Claude to resolve app URLs from tickets (e.g. https://app.example.com/companies/test/drivers/history) by looking up the route in config/routes.rb, reading the controller and view code, and using that context to self-answer questions before requesting clarification.
  • --errors now includes blocked issues in addition to errored ones, with distinct color coding (yellow for blocked, red for error).
  • New model and effort config keys (global and per-project) forwarded to danger-claude as --model and --effort. Project-level overrides global.
  • rails-conventions skill now requires code comments in English covering WHAT, WHY, and HOW, and commit messages in English using Conventional Commits format (<type>: <description>) with a detailed body.
  • Pipeline auto-retrigger is now conditional on pre-triage verdict. Previously, every pipeline failure was retriggered once before analysis. Now, only :infra and :uncertain verdicts trigger a retry — :code failures go straight to the fix phase, saving a full pipeline cycle.

Fixed

  • Worker pool now deduplicates enqueue calls: if an issue is already queued or being processed, subsequent enqueue attempts for the same issue_iid are silently skipped. Fixes a race condition where the polling loop could enqueue the same fixing_discussions task twice, causing a git clone failure when two workers tried to clone to the same temp directory.
  • Image download errors now include the exception class and message (e.g. SocketError, URI::InvalidURIError) instead of a generic "download failed", making it possible to diagnose failures from logs.
  • Skills are now injected as subdirectories with SKILL.md files (e.g. .claude/skills/rails-conventions/SKILL.md) instead of bare .md files. This matches the Claude Code skill format. Existing legacy .md skills are automatically migrated to the new format.
  • Jobs with allow_failure: true are now excluded from pipeline failure analysis and fix attempts. These jobs don't block the pipeline and should not trigger retriggers or fixes.
  • API rate limit errors ("You've hit your limit") no longer burn retry attempts. Rate limits are detected from danger-claude output and the issue is parked until the reset time without incrementing retry_count. Applies to all three processors (IssueProcessor, MrFixer, PipelineMonitor).
  • Deploy jobs (deploy_review, etc.) no longer sent to danger-claude for fixing. Jobs matching deploy/release/provision/terraform/helm/k8s patterns are now classified as infra in pre-triage and skipped during pipeline fix. Previously, a deploy job with script_failure would be classified as code, causing a 30-minute timeout with no useful result.

[0.6.3] - 2026-03-30

Added

  • --status now shows the worker assigned to each active issue (e.g. [worker-3]), matching the poll status summary. Worker assignments are persisted to ~/.autodev/workers.json by the running instance.
  • --errors [IID] shows error details (message, stderr) for issues in error state. Without IID, shows all; with IID, shows a specific issue.
  • --reset [IID] resets errored issues to pending (retry_count zeroed). Without IID, resets all; with IID, resets a specific issue.

Fixed

  • Fix datetime('now') and datetime('now', '+N seconds') stored as literal strings instead of being evaluated by SQLite for started_at, finished_at, and next_retry_at fields. This broke automatic error retries since next_retry_at comparisons never matched. Same root cause as the clarification_requested_at fix in v0.6.0 — use dataset-level Issue.where(id:).update() instead of model-level issue.update() so Sequel.lit() expressions are passed through to SQLite.

[0.6.2] - 2026-03-30

Added

  • Poll status summary: after each polling cycle, print a compact status of all active (non-over) issues to stdout with their state, project, and assigned worker. Not written to log files.

Changed

  • Dashboard (--status) now hides completed (over) issues by default. Use --status --all to show all issues.

Fixed

  • Fix branch checkout on shallow clones: fetch the remote branch before checkout when reusing an existing branch. Shallow clones (--depth 1) only fetch the target branch, so git checkout autodev/... would fail with "pathspec did not match". Uses explicit refspec to bypass --single-branch restriction.
  • Fix Could not process image API error: validate downloaded images by checking Content-Type header before writing to disk. Non-image responses (HTML error pages, etc.) are replaced with a text placeholder instead of being passed to Claude.
  • Fix Ctrl+C during danger-claude marking issues as errored: detect SIGINT on subprocess exit and re-raise Interrupt so the worker pool shuts down gracefully instead of treating it as an implementation failure.
  • Fix garbled stdout when multiple workers run in parallel. Multiline messages (full prompts) are now truncated to the first line on the console; full content goes to log files only. Also close stdin on spawned subprocesses to prevent TTY inheritance.

[0.6.1] - 2026-03-30

Fixed

  • Fix crash on transient network errors (DNS resolution, connection refused) during issue polling. The rescue clause caught only AutodevError instead of StandardError, letting Socket::ResolutionError and similar exceptions kill the process.

[0.6.0] - 2026-03-30

Added

  • Dashboard: autodev --status displays a table of all tracked issues with their state, project, MR link, and contextual comments. Color-coded by status with a summary line.

Fixed

  • Fix clarification detection: compare timestamps as parsed Time objects instead of raw strings. SQLite's datetime('now') format and GitLab's ISO 8601 format were compared lexicographically, causing needs_clarification issues to never detect human replies.
  • Fix clarification_requested_at stored as literal string "datetime('now')" instead of evaluated timestamp. Sequel.lit() is not interpreted by Sequel::Model#update — use dataset-level update instead.
  • Fix GitLab image download failing with 302: follow HTTP redirects (up to 3 hops) when downloading issue attachments. GitLab redirects authenticated upload URLs, and Net::HTTP does not follow redirects automatically.

[0.5.1] - 2026-03-27

Fixed

  • Add logger gem to inline Gemfile for Ruby 4.0 compatibility (logger was removed from default gems).
  • Fix AASM + Sequel compatibility on Ruby 4.0: name the Issue class via const_set before include AASM so that AASM's StateMachineStore registers under the correct key ("Issue" instead of the anonymous class name).

[0.5.0] - 2026-03-26

Added

  • Parallel agents mode: when parallel_agents: true is set in project config, autodev evaluates issue complexity via a Claude call. Simple issues fall back to single/split mode. Complex issues (multi-layer, multi-domain) are decomposed into a work plan of up to 4 tasks, each executed by a specialized agent in its own git worktree in parallel. Results are merged back. All-agents-failed is fatal; partial failures are tolerated. Disabled by default.
  • Split implementation mode: when split_implementation: true is set in project config, the implementation step runs two specialized agents in parallel using git worktrees — an implementer (code only) and a test-writer (tests only, from spec). Each runs in its own working directory via git worktree add. Test files are merged back after both complete. Code errors are fatal; test-writer errors are non-fatal. Each agent is injected automatically if not present in the project. Default agents use model: sonnet. Disabled by default; single-pass mode unchanged.
  • MR discussion fix: use project-level mr-fixer subagent when .claude/agents/mr-fixer.md exists in the target repo. The agent is passed to danger-claude via the new -a flag, enabling persistent memory that accumulates fix patterns across conversations. Configurable per-project via mr_fixer_agent in config.
  • Pipeline pre-triage: classify pipeline failures using GitLab failure_reason before cloning or calling Claude. Infrastructure failures (runner_system_failure, stuck_or_timeout_failure, etc.) are blocked immediately — no clone, no tokens spent. Code failures (script_failure) skip the Claude evaluation call and go straight to fix. Only uncertain cases fall back to Claude evaluation.
  • Pipeline fix categorization: classify failed jobs as test/lint/build by job name, stage, and log patterns. Fix prompts are tailored per category with specific guidance (e.g., "fix source code not tests" for test failures, "fix only flagged files" for lint).
  • MR discussion fix: enrich context passed to danger-claude with issue title/description, MR description, exact line numbers, and the relevant diff hunk extracted via git diff. Eliminates the exploration turn Claude previously needed to locate the code.
  • Skills injection: auto-detect project stack (Ruby version, Rails version, database, test framework) and inject default Claude Code skills (rails-conventions, test-patterns, database-patterns) into .claude/skills/ of the cloned repo when the project doesn't provide its own. Skills are version-aware (Rails 4.x through 8.x) and DB-aware (PostgreSQL, MySQL). Existing skills are always preserved. Also detects Devise, Pundit, CanCanCan, Sidekiq, RuboCop, and API-only mode for targeted guidance.

[0.4.0] - 2026-03-26

Refactored

  • Split single-file script into lib/autodev/ modules: errors, logger, config, database, shell_helpers, gitlab_helpers, danger_claude_runner, issue_processor, mr_fixer, pipeline_monitor, worker_pool. Entry point bin/autodev reduced from ~2200 to 340 lines.
  • Extract shared DangerClaudeRunner module: run_with_timeout, danger_claude_prompt, danger_claude_commit, clone_and_checkout, notify_issue, logging. Included by IssueProcessor, MrFixer, and PipelineMonitor, eliminating ~200 lines of duplication.
  • Extract ShellHelpers and GitlabHelpers modules.

Added

  • AASM state machine: formalized all status transitions using the aasm gem with Sequel::Model. Each state corresponds to exactly one action. Events with guards enforce valid transitions. Issue model is built dynamically after DB connection (Database.build_model!).
  • Pipeline monitoring: checking_pipeline state checks MR pipeline status each poll cycle. Green + no conversations → over, green + conversations → fixing_discussions, running → skip, red → retrigger once then evaluate via danger-claude.
  • Pipeline code fix: code-related pipeline failures are fixed directly by PipelineMonitor (fixing_pipeline state). Full job logs are written to tmp/ci_logs/ files in the work directory (no truncation) and referenced by path in prompts. Each failed job is fixed in a separate danger-claude call + commit.
  • blocked status for issues requiring manual intervention (non-code pipeline failures, canceled/skipped pipelines).
  • checking_spec state: specification clarity check is now a dedicated state (previously embedded in implementing).

Changed

  • State machine rationalized: eliminated pass-through states done and mr_fixed. reviewing transitions directly to checking_pipeline. fixing_discussions/fixing_pipeline transition directly to checking_pipeline.
  • Status renamed: mr_pipeline_runningchecking_pipeline, mr_fixingfixing_discussions, mr_pipeline_fixingfixing_pipeline. Automatic migration of existing DB records.
  • Database module simplified: removed update_issue, find_issue, insert_issue, issues_for_*, transition_to_pipeline_running!, mark_max_rounds_as_over!. Replaced by Issue Sequel::Model with AASM events.
  • over is the terminal success status, reached only when pipeline is green and no open conversations remain.

[0.3.0] - 2026-03-24

Added

  • MR comment fixing: automatically fix unresolved MR discussions (from mr-review or humans). One discussion = one danger-claude call = one commit. Discussions are resolved after fixing. Status lifecycle: donemr_fixingmr_fixed → ... → over. Configurable max_fix_rounds (default: 3, per-project overridable). Only processes issues that still have the autodev trigger label.
  • Random suffix in branch names (autodev/{iid}-{slug}-{hex8}) to allow re-processing the same issue. Reuses the existing branch from the database if it still exists on the remote; otherwise generates a new name.
  • Download GitLab images from issue descriptions and comments into .autodev-images/ in the workdir so Claude can see screenshots and diagrams during implementation.

Changed

  • Exclude autodev's own comments from the issue context passed to the implementation prompt.
  • Log all danger-claude prompts at DEBUG level for troubleshooting.

Fixed

  • Shallow clone with target_branch: pass --branch to git clone so the target branch is fetched even with --depth 1 (previously failed with "pathspec did not match").

[0.2.0] - 2026-03-23

Added

  • Shallow clone by default (--depth 1) for faster cloning of large repos.
  • Per-project clone_depth config option (0 for full clone, default: 1).
  • Per-project sparse_checkout config option for monorepo support.
  • Better branch slug generation using i18n transliteration (incohérentincoherent instead of incohrent).
  • --dry-run flag to poll and display which issues would be processed without side effects.
  • Capture and store danger-claude stdout/stderr (dc_stdout, dc_stderr columns) from all calls (-p and -c) in the database for debugging and audit.
  • Configurable danger-claude timeout (dc_timeout, default: 1800s/30min). Global or per-project. Uses Process.spawn with TERM/KILL for reliable subprocess cleanup.
  • Structured logging with levels (DEBUG/INFO/WARN/ERROR), timestamps, dual output (stdout + file), daily log rotation. Global logs in ~/.autodev/logs/autodev/, per-project logs in ~/.autodev/logs/{project}/. Configurable via log_dir and log_level in config.
  • Retry with exponential backoff and max retries per issue (max_retries default: 3, retry_backoff default: 30s). Global or per-project. Issues that exceed max retries are skipped. Backoff doubles each attempt (30s → 60s → 120s).
  • Partial progress recovery: on retry, if the branch was already pushed, skip directly to MR creation instead of re-implementing from scratch.
  • Issue notifications: post comments on GitLab issues when processing starts, succeeds (with MR link), or fails (with error summary).
  • Specification check: before implementation, analyse the spec for ambiguities via a dedicated danger-claude call. If unclear, post a comment listing questions and mark as needs_clarification. On each poll, check for new human comments to automatically resume.

Fixed

  • Label guard: labels are now updated after MR creation succeeds, preventing issues from being left in a bad state if MR creation fails.

[0.1.0] - 2026-03-23

Added

  • Automated GitLab issue implementation via danger-claude.
  • Poll configured projects for issues with a trigger label (default: autodev).
  • Clone repo, create branch, implement changes, commit, push, create MR automatically.
  • GitLab label management: remove configured labels, add completion label.
  • Optional headless mr-review on created MRs.
  • SQLite persistence for issue tracking with status lifecycle.
  • Concurrent worker pool (configurable, default 3 threads).
  • 4-layer configuration: defaults, ~/.autodev/config.yml, environment variables, CLI flags.
  • Graceful shutdown on SIGINT/SIGTERM.
  • Auto-retry of errored issues on restart.
  • --once flag for single poll cycle.
  • Auto-generation of CLAUDE.md for projects that lack one.