summaryrefslogtreecommitdiff
AgeCommit message (Collapse)Author
2026-05-02feat(api): enrich CI failure task instructions via local LLMClaude
Phase 3 of "local OSS models as agents" plan. When the webhook handler creates a task for a failed CI run AND a local LLM is configured on the server, the hardcoded 4-step investigation template is replaced with a project-aware investigation plan generated by the LLM. Scope adjustment from the original sketch: the original plan said "summarize fetched workflow logs", but fetching logs requires GitHub API auth that isn't wired. Narrowed to project-context triage — recent git log + CLAUDE.md content + webhook metadata, fed to the LLM with a system prompt asking for 6-12 lines of concrete next steps. Deferred GitHub log fetching to post-epic cleanup. Implementation: - New internal/api/webhook_llm.go holds enrichCIInstructions and its helpers (readRecentCommits via `git log`, readProjectDoc). - enrichCIInstructions is truly additive: any failure mode (no client, HTTP error, empty body, 10s timeout) returns the original fallback template unchanged. Existing webhook tests pass byte-for-byte. - Always preserves a metadata header (repo/branch/SHA/check/URL) ahead of the LLM body so investigators don't lose context if the LLM is terse. - Reuses s.llm (set via Server.SetLLM in Phase 2) — no new config knob, no per-feature gating. Asymmetric opt-out (yes-elaborate, no-CI-triage) deferred until there's actual demand. Tests: - enrichCIInstructions: nil client, LLM 500, empty body all return fallback unchanged. - enrichCIInstructions: success path produces enriched body with metadata header preserved; user prompt contains repo/branch/SHA. - enrichCIInstructions: real git repo (init + 2 commits) → recent commits appear in user prompt. - Webhook handler regression guard: no-LLM path produces the exact legacy template substrings. - Webhook handler with LLM stubbed: task instructions contain LLM body + metadata header. Plan: docs/plans/local-oss-runner.md. https://claude.ai/code/session_017Edeq947TpSm1vQTxMhi1J
2026-04-28feat(api): route elaboration through local LLM when configuredClaude
Phase 2 of "local OSS models as agents" plan. Adds a third elaboration path that calls the local OpenAI-compatible LLM via the internal/llm client, and reorders dispatch so the cheap path is tried first: local → claude → gemini, with each next attempt only on hard failure of the prior. Wiring is opt-out, not opt-in: when [local_model].endpoint is set, elaboration prefers local by default. Users with a slow or low-quality local model can disable just elaboration via: [local_model] endpoint = "..." prefer_for_elaborate = false without giving up the runner or the classifier path. Implementation: - Server gains an optional *llm.Client field via SetLLM (matches the existing SetNotifier/SetWorkspaceRoot setter pattern, no NewServer signature break). - elaborateWithLocal() reuses buildElaboratePrompt verbatim and asks for response_format=json_object so we skip markdown-fence cleanup. - handleElaborateTask reorders try chain; existing Claude-first behavior is preserved exactly when SetLLM is not called. - LocalModel.UseForElaborate() encapsulates the default-true gating with a *bool so explicit-false survives TOML parse. Tests: - elaborateWithLocal: parses valid response, errors on nil client, errors on bad JSON. - handler: local preferred when wired; falls back to claude when local fails; unchanged behavior when no LLM is configured. - config: UseForElaborate gating across empty/default/explicit-true/ explicit-false cases. Pre-existing test failures noted in docs/plans/local-oss-runner.md (post-epic cleanup): TestGeminiLogs_ParsedCorrectly returns 404 for gemini execution log fetch — predates this change. Plan: docs/plans/local-oss-runner.md. https://claude.ai/code/session_017Edeq947TpSm1vQTxMhi1J
2026-04-28feat(executor): add LocalRunner and OpenAI-compat LLM clientClaude
Phase 1 of "local OSS models as agents" plan. Adds a third Runner backed by any OpenAI-compatible HTTP server (Ollama, vLLM, LM Studio, llama.cpp), and migrates the Gemini-CLI classifier to route through the same client when configured. Two-layer split: internal/llm.Client is the workhorse (HTTP, no Pool, no DB) used directly by the classifier and any future internal helper that needs cheap reasoning. internal/executor.LocalRunner is a thin adapter implementing Runner for user-facing tasks. This avoids Pool reentrancy/deadlock when sub-second internal calls fire from inside Pool.execute(). Highlights: - internal/retry: relocated runWithBackoff/IsRateLimitError/ParseRetryAfter into a shared package reused by executor and llm. - internal/llm: Chat (non-streaming) and ChatStream (SSE) over /chat/completions with optional bearer auth, json_object response format, retry on 429/503, Retry-After parsing. - internal/executor/LocalRunner: streams deltas into stdout.log in the same stream-json envelope ClaudeRunner emits, then writes one consolidated assistant block plus a result terminator so existing parsers (extractSummary, ParseChangestatFromOutput) work unchanged. - internal/executor/Classifier: gains optional LLM field; uses json_object response format (no markdown-fence cleanup needed). Falls back to Gemini-CLI subprocess when LLM is nil. - Pool.skipClassification: now skips only when the requested agent type is registered, so unknown types still reach the load balancer. - Storage: additive tokens_in/tokens_out ALTERs on executions; CLI runners record cost_usd as before, LocalRunner records 0 + tokens. - Config: [local_model] section (endpoint, model, timeout_seconds, default_temperature, api_key). Empty endpoint = no LocalRunner registered, classifier falls back to Gemini. Pre-existing test issues fixed in passing: - claude_test.go setupSandbox callsites updated to current signature. - gemini_test.go TestParseGeminiStream skipped (asserts unimplemented GeminiRunner stream-error parsing; tracked separately). Plan: docs/plans/local-oss-runner.md. https://claude.ai/code/session_017Edeq947TpSm1vQTxMhi1J
2026-04-11fix: tie pool submissions to server lifecycle contextClaude Agent
Fix 1 (server.go): Replace context.Background() with s.ctx in handleAnswerQuestion, handleResumeTimedOutTask, and handleRunTask. Add a ctx field to Server (defaulting to context.Background()) and a SetContext method so the serve command can wire in the signal- cancellable lifecycle context. Fix 2 (serve.go): Call srv.SetContext(ctx) before StartHub so all pool submissions use the server's root context (already cancelled on SIGTERM/SIGINT). Pool.Shutdown and its wiring were already present. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11cleanup: remove dead code (QuestionRegistry, changestats wrappers, scanner.Err)Claudomator Agent
Fix 1: Remove QuestionRegistry and related types (QuestionHandler, PendingQuestion) from question.go -- nothing reads Pool.Questions or uses the registry. Remove NewQuestionRegistry() call from NewPool and the Questions field from Pool. Remove the now-superfluous registry tests; keep stream/parse helpers which are still used by the claude runner. Fix 2: Check scanner.Err() after the parseStream loop so I/O errors from the scanner are not silently swallowed when streamErr is still nil. Fix 3: Delete internal/api/changestats.go -- the parseChangestatFromFile and parseChangestatFromOutput wrappers were only needed to support processResult(), which no longer calls them; they are unreachable dead code. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04feat: Ship button on SHIPPABLE stories; checker report on READY task cardsPeter Stone
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04feat: acceptance_criteria per story task in elaboration and approvalPeter Stone
Add AcceptanceCriteria field to elaboratedStoryTask struct, update buildStoryElaboratePrompt schema and rules, pass the value through handleApproveStory into task.Task, and add a test verifying the field is persisted on approved story tasks. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04fix: ShipStory — use context.Background() to avoid request context ↵Peter Stone
cancellation killing deploy
2026-04-04feat: story ship gate — explicit POST /api/stories/{id}/ship; remove ↵Peter Stone
auto-deploy - checkStoryCompletion now guards against re-running on already-SHIPPABLE stories and no longer auto-triggers triggerStoryDeploy on completion - New Pool.ShipStory method validates SHIPPABLE state then fires triggerStoryDeploy - POST /api/stories/{id}/ship route registered and handleShipStory handler added - Two new tests: 202 for SHIPPABLE story, 409 for non-SHIPPABLE story Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04fix: executor checker — close race, test flakiness, checker report for all ↵Peter Stone
failure states Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04feat: spawn checker task on READY; auto-accept on pass; attach report on failPeter Stone
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04feat: add checker task columns, UpdateTaskCheckerReport, GetCheckerTaskPeter Stone
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04feat: add AcceptanceCriteria, CheckerForTaskID, CheckerReport to Task structPeter Stone
2026-04-04docs: task checker + story ship implementation planPeter Stone
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04docs: task checker agent and story ship gate design specPeter Stone
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03feat: fold completed tab into ready panel; stories tab firstPeter Stone
- Remove the standalone "All" tab; completed tasks (last 24h) now appear at the bottom of the Ready tab under a "Completed (24h)" section header - Move Stories tab to the first position in the nav bar - Drop 'all' from badge count computation Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03docs: add task→project FK migration planPeter Stone
2026-04-03feat: require repository_url on tasks; fix UpdateTask to persist it; fix ↵Peter Stone
cascade-retry test race Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03fix: remove drain-lock circuit breaker that halted all executions after 3 ↵Peter Stone
consecutive failures Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29docs: add seed.go pointer to essential commands tablePeter Stone
2026-03-29feat: register modal-shell project; document project registryPeter Stone
Adds modal-shell to SeedProjects() and documents how to find and edit seed.go in .agent/design.md.
2026-03-29feat: add rotating background wallpaperPeter Stone
Uses time-bucketed picsum seed (5-min intervals) so all sites show the same image simultaneously. Sets --bg-url CSS custom property on body, consumed by .bg-body background-image rule.
2026-03-26fix: story stays PENDING when all subtasks complete but parent task stays QUEUEDPeter Stone
When a story is approved with pre-created subtasks, parent tasks are QUEUED but never run. Their subtasks complete, but: - maybeUnblockParent only handled BLOCKED parents, not QUEUED ones - checkStoryCompletion required ALL tasks (incl. subtasks) to be done Fixes: - maybeUnblockParent now also promotes QUEUED parents to READY when all subtasks are COMPLETED - checkStoryCompletion only checks top-level tasks (parent_task_id="") - RecoverStaleBlocked now also scans QUEUED parents on startup and triggers checkStoryCompletion if it promotes them - Add QUEUED→READY to valid state transitions (subtask delegation path) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26feat: graceful shutdown — drain workers before exit (default 3m timeout)Peter Stone
- Add workerWg to Pool; Shutdown() closes workCh and waits for all in-flight execute/executeResume goroutines to finish - Signal handler now shuts down HTTP first, then drains the pool - ShutdownTimeout config field (toml: shutdown_timeout); default 3m - Tests: WaitsForWorkers and TimesOut Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26feat: show tasks and subtasks in story detail viewPeter Stone
Story detail modal now fetches /api/stories/{id}/tasks and renders top-level tasks as a numbered list with subtasks nested beneath, using the same state emoji as the blocked/task views. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26fix: ensure story branch exists before cloning at task startPeter Stone
Add ensureStoryBranch() that runs git ls-remote to check, then clones into a temp dir to create and push the branch if missing. Called before the task's own clone so checkout is guaranteed to succeed. Removes the post-checkout fallback hack added in the previous commit. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26fix: auto-create story branch if missing at clone timePeter Stone
If git checkout of the story branch fails (branch never pushed to bare repo), create it from HEAD and push to origin instead of hard-failing the task. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26fix: next-task fallback should not exclude previously-executed tasksPeter Stone
The `id NOT IN (SELECT task_id FROM executions)` guard prevented retried tasks (FAILED→PENDING) from ever being picked up by start-next-task. Only the rejection_comment check is needed to avoid re-running rejected tasks. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26feat: cascade retry deps when running a task with failed dependenciesPeter Stone
When /run is called on a CANCELLED/FAILED task that has deps in a terminal failure state, automatically reset and resubmit those deps so the task isn't immediately re-cancelled by the pool's dep check. Also update reset-failed-tasks script to handle CANCELLED tasks and clean up preserved sandbox workspaces. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26fix: cancel waiting tasks when dep hits terminal failure (QUEUED→CANCELLED)Peter Stone
QUEUED→FAILED is not a valid state transition. When a dependency enters a terminal failure state, cancel the waiting task instead. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26fix: story branch push to bare repo; drain at 3 consecutive failuresPeter Stone
createStoryBranch was pushing to 'origin' which doesn't exist — branches never landed in the bare repo so agents couldn't clone them. Now uses the project's RemoteURL (bare repo path) directly for fetch and push. Raise drain threshold from 2 to 3 consecutive failures to reduce false positives from transient errors. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26test: add TestPool_DependsOn_NoDeadlockstory/repo-urlPeter Stone
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26fix: resolve dep-chain deadlock; broadcast task_started for UI visibilityPeter Stone
With maxPerAgent=1, tasks with DependsOn were entering waitForDependencies while holding the per-agent slot, preventing the dependency from ever running. Fix: check deps before taking the slot. If not ready, requeue without holding activePerAgent. Also accept StateReady (leaf tasks) as a satisfied dependency, not just StateCompleted. Add startedCh to pool and broadcast task_started WebSocket event when a task transitions to RUNNING, so the UI immediately shows the running state during the clone phase instead of waiting for completion. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26fix: expose drained state in agent status API; fix AgentEvent JSON casingPeter Stone
AgentStatusInfo was missing drained field so UI couldn't show drain lock. AgentEvent had no JSON tags so ev.agent/event/timestamp were undefined in the stats timeline. UI now shows "Drain locked" card state with undrain CTA. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26fix: set RepositoryURL on tasks created via story approvePeter Stone
handleApproveStory was creating tasks without RepositoryURL, causing executions to fail with "task has no repository_url". Now looks up the project's RemoteURL and sets it on all tasks and subtasks. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26fix: story tasks get Project field; elaborate reads worklog; deploy chmod ↵Peter Stone
scripts - handleApproveStory: set Project = input.ProjectID on tasks and subtasks so the executor can resolve RepositoryURL from the project registry (was causing "task has no repository_url" on every story task) - elaborate.go: read .agent/worklog.md instead of SESSION_STATE.md for project context injected into elaboration prompts - deploy: explicitly chmod +x all scripts before restart (same root cause as the binary execute-bit loss — chown -R was stripping it) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26fix: ensure claudomator binary is executable before service restart in deployPeter Stone
chown -R in fix-permissions was stripping the execute bit on the binary, causing the service to fail with 203/EXEC on next restart. Explicitly chmod +x both bin paths as the final step before systemctl restart. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-25fix: update deploy script to pull from main instead of masterPeter Stone
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-25feat: add Stories UI — tab, list, new story elaborate/approve flowPeter Stone
- Stories tab (📖) with story card list, status badges, project/branch meta - New Story modal: project picker + goal textarea + AI elaboration → plan review → approve & queue - Story detail modal: status, project, branch, created date - Export storyStatusLabel() and renderStoryCard() with 16 unit tests - CSS for story cards, status badges, and modals Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-25fix: remove duplicate summary section in task panel, fix test mock DOMPeter Stone
renderTaskPanel was rendering the summary twice — once with .task-summary before Overview, and again with .task-summary-text after it. Remove the second (post-Overview) duplicate. Add `dataset: {}` to the test mock DOM so makeMetaItem's state badge path doesn't crash during renderTaskPanel tests. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-25chore: worklog — mark proxy work done, status idlePeter Stone
2026-03-25chore: replace all master branch references with mainPeter Stone
- executor.go: merge story branch to main before deploy - container.go: error messages reference git push origin main - api/stories.go: create story branch from origin/main (drop master fallback) - executor_test.go: test setup uses main branch Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-25feat: add ct-submit script for permission-free task creationPeter Stone
Wraps POST /api/tasks + run in a single script callable from /workspace/** (auto-permitted). Used by the ct-create skill to avoid per-call auth prompts. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-25chore: worklog — ADR-007 item 9 done, workspace leak resolved, doot atom ↵Peter Stone
task queued Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-25chore: update worklog — proxy done, workspace leak backlog itemPeter Stone
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24feat: merge story branch to master before deploy, add doot project to registryPeter Stone
- triggerStoryDeploy: fetch/checkout/merge --no-ff/push before running deploy script (ADR-007) - executor_test: TestPool_StoryDeploy_MergesStoryBranch proves merge happens - seed.go: add doot project with deploy script; wire claudomator deploy script Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24chore: merge agent commits — deploy trigger + post-deploy validation task ↵Peter Stone
(ADR-007) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24Merge branch 'master' of /site/git.terst.org/repos/claudomatorPeter Stone
2026-03-24feat: validation result transitions story to REVIEW_READY or NEEDS_FIX (ADR-007)Claudomator Agent
Add checkValidationResult which inspects the final task.State of a completed validation task and updates the story to REVIEW_READY (pass) or NEEDS_FIX (fail). Wire into handleRunResult so stories in VALIDATING state are dispatched to checkValidationResult instead of checkStoryCompletion, covering both success and FAILED terminal paths. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24feat: auto-create validation task on story DEPLOYED (ADR-007)Claudomator Agent