| Age | Commit message (Collapse) | Author |
|
Covers all entry points verified against current code:
- REST API (POST /api/tasks + /run), chatbot MCP (submit_task,
create_story, accept_story), GitHub webhook, Story REST API,
agent spawn_subtask (parent_task_id vs depends_on/role paths),
propose_epic, propose_role_config, StoryOrchestrator's internal
spawning (ensureEvaluators/ensureArbitration/ensureFixAttempt/
spawnNestedFixAttempt/processRetro), Scheduler retry/escalation
and ask_user-timeout escalation, claudomator run <file> CLI.
Includes task state machine diagram and recursive arbitrated-review
cycle showing that builder-role READY means awaiting arbitration,
not done. All diagrams use Mermaid (renders on GitHub).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
SeedProjects) instead of a manual API call
|
|
|
|
|
|
|
|
nested-builder-completion-follows-arbitration (piece 4b-1)
|
|
(lesson from piece 3's dispatch saga)
|
|
|
|
Piece 3 of docs/superpowers/specs/2026-07-09-recursive-arbitrated-review-design.md.
Removes ensureFixAttempt's story.RootTaskID re-pointing write path,
migrating processStory/processRetro/ensureFixAttempt onto
task.CurrentAttempt resolution (piece 2b). RootTaskID becomes a true
immutable anchor after this lands.
|
|
Piece 2b of docs/superpowers/specs/2026-07-09-recursive-arbitrated-review-design.md.
Builds the shared CurrentAttempt primitive (internal/task, behind a
minimal TaskLookup interface so both executor.Store and
scheduler.StoryStore can use it without duplication) and wires
maybeUnblockParent to resolve through it. Deliberately does not touch
ensureFixAttempt/story.RootTaskID (piece 3) or arbitrated-review
triggering (piece 4) -- scoped to the isolated primitive plus its
first real caller.
|
|
Piece 2a of docs/superpowers/specs/2026-07-09-recursive-arbitrated-review-design.md,
discovered while grounding piece 2 in the real executor code: a subtask
that itself spawns subtasks is incorrectly marked COMPLETED the instant
its own agent turn ends, ignoring pending grandchildren. handleRunResult,
maybeUnblockParent, and RecoverStaleBlocked all special-case "is this
top-level" instead of "does this task have its own pending subtasks" --
a prerequisite bug fix the currentAttempt()/fix-loop generalization
(piece 2b) depends on.
|
|
Piece 1 of docs/superpowers/specs/2026-07-09-recursive-arbitrated-review-design.md's
implementation order: adds the field the earlier 2026-07-08 spec
incorrectly claimed already existed, and exposes it on spawn_subtask.
|
|
fix loop)
Replaces the story.RootTaskID re-pointing mechanism shipped in
2026-07-09-story-fix-and-reevaluate-loop.md with a uniform
currentAttempt() resolution that works identically at every depth of
a story's task tree, not just the root. Also corrects the 2026-07-08
spec's incorrect claim that Task.AcceptanceCriteria already exists.
|
|
Closes the recursive-story-decomposition design spec's "fix-and-
re-evaluate loop has to become real" gap -- today NEEDS_FIX is a dead
end requiring manual human intervention. Design decision (re-point
story.RootTaskID at a fresh fix-attempt task, vs. spawning as a
dependent of a fixed root) made with user input before writing this
plan.
|
|
Scopes the "MCP surface: story-level tools, additive to what exists"
piece of the recursive-story-decomposition design spec on its own,
independent of the larger deferred per-node arbitrated-review
generalization and builder role system-prompt work.
|
|
reporting
Plan 1 of the recursive-story-decomposition design (see
docs/superpowers/specs/2026-07-08-recursive-story-decomposition-design.md).
Deliberately scoped to two small, independent, fully-groundable additions
-- SubtaskSpec.DependsOn and a structured report_verdict tool closing the
"arbitration never parses its own verdict" gap -- rather than attempting
the full recursive orchestrator rewrite in one pass. That rewrite becomes
its own plan(s) once story_orchestrator_test.go (1023 lines of existing
convention) has been read in full.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VTUSAEKfsPc6WGDq45yPHD
|
|
Retro from the tasks-board build (see memory
claudomator-sequential-orchestration-gap): claudomator has no native way to
drive a stated intent through review-gated implementation to arbitrary
depth -- that role was played by a human/chatbot controller hand-dispatching
and re-dispatching all session. Design converged through several rejected
drafts (a separate "chain mode" pipeline, a distinct Planner role) before
landing on the actual shape: one role, one recursive decompose-or-evaluate
mechanism, applied at every depth, with arbitrated multi-evaluator review
running at every node instead of once at a story's outer level.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VTUSAEKfsPc6WGDq45yPHD
|
|
This should have been committed alongside the design spec (f626155) before
task execution began. It wasn't -- every claudomator container that cloned
this repo during the Tasks board build never actually had this file, since
containers clone from the pushed remote, not the local working tree. Tasks
dispatched with only a "read this file" instruction had nothing to read and
silently improvised instead, which explains most of the review-cycle churn
during that build far better than "the implementer didn't follow
instructions" did. Committing now for the historical record and so the
gap can't repeat for this specific file.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VTUSAEKfsPc6WGDq45yPHD
|
|
Adds a Tasks tab (Kanban board, 5 columns: Queue/Running/Ready/
Interrupted/Done) covering all tasks regardless of story association,
with inline auto-tailing execution logs on every card. Mostly a
revival/generalization of UI code removed in cc6b323, plus a
generalization of the existing Running-tab log-stream mechanism to
every column.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VTUSAEKfsPc6WGDq45yPHD
|
|
Two parts:
Part A (fixes a gap from Phase 1): Groq/OpenRouter/OpenAI were documented in
docs/api-keys-setup.md as usable once configured, but nothing actually
constructed runners for them. internal/cli/cloudrunners.go consolidates
anthropic/google/groq/openrouter/openai NativeRunner construction into one
table-driven registerCloudRunners() helper, replacing the two hand-written
per-provider blocks in serve.go/run.go. Groq/OpenRouter/OpenAI reuse
openaicompat (no new adapter code) at SandboxKind: "docker".
Part B: the token-husbanding harness's core routing mechanism.
- internal/role: RoleConfig/Tier/Rung -- a role's system prompt and a
multi-tier (provider, model) escalation ladder, versioned via config_json.
- storage: new role_configs table (draft/active/retired, UNIQUE(role,
version)) with transactional activate-retires-prior-active semantics;
new executions.escalation_rung column.
- task.AgentConfig.Role string -- purely additive; every existing task shape
(Agent.Role == "") is unaffected, proven by TestPool_Execute_NonRoleTask_Unaffected
plus the full pre-existing suite passing unchanged.
- executor.Pool.execute(): role-typed tasks with no Agent.Type yet resolve
tier 0 of their active ladder (round-robin across multi-candidate tiers,
skipping rate-limited providers, falling back to soonest-clearing) before
the existing pickAgent/Classifier path runs; SystemPrompt applies to
Agent.SystemPromptAppend. Already-resolved role tasks (scheduler resubmits)
get their escalation_rung re-derived read-only via findTierIndex.
- internal/scheduler: polls role-typed FAILED tasks, retries at the same
rung under MaxRetries or escalates to the next tier's first candidate when
budget.Accountant.Allow() permits (emitting event.KindEscalated), else
leaves the task FAILED with a final:true KindEscalated event. An
in-memory per-execution-ID "handled" set keeps the poll loop convergent.
Started by `serve` only, config knob [scheduler].poll_interval_seconds.
- internal/api: POST/GET /api/roles/{role}/versions, POST
/api/roles/{role}/activate -- unauthenticated, matching the existing
projects/tasks REST endpoints' auth posture (only chatbot MCP, agent MCP,
and WebSocket are api_token-gated in this codebase today).
Documented as stored-but-not-yet-enforced (CLAUDE.md Design Debt, matching
how task.Priority/RetryConfig are already documented): RoleConfig.Tools/
SandboxKind don't affect dispatch yet; DefaultBudgetUSD is read narrowly as
the scheduler's escalation cost estimate, not enforced at initial dispatch;
scheduler escalation always targets Candidates[0] (no round-robin, unlike
initial-dispatch tier-0 resolution); the scheduler's dedupe is per-process
and resets on restart (idempotent, harmless).
go build/vet/test -race -count=1 all pass, 21 packages.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V1moSNCJRcP6kykA4tyUSs
|
|
Adds internal/provider/google, the second native cloud adapter (following
internal/provider/anthropic's pattern) on top of Phase 1's provider-neutral
tool-use loop, wired to a Docker-sandboxed NativeRunner under agent.type:
"google" -- a separate execution path and budget bucket from the existing
CLI-subprocess "gemini" ContainerRunner, which is untouched.
Wire-format research (the highest-risk part of this adapter): Gemini's
multi-turn function-calling shape was resolved by cross-referencing the
REST API reference's own generateContent example against the go-genai SDK's
struct tags on GitHub -- both agree on functionCall/functionResponse parts
keyed by "name" (with an optional "id" for round-tripping ToolCall.ID),
with the response fed back inside a "user"-role Content (Gemini has no
tool/function role, mirroring Anthropic's lack of one). A separate fetched
source (the function-calling guide page) was deliberately discarded as a
reference for this shape -- it documents a different, newer "Interactions
API" whose call_id/type:"function_result" structure doesn't fit the
contents/parts/candidates shape used everywhere else.
- internal/provider/google: request/response translation, systemInstruction
handling, role mapping (assistant->model, tool-results->user role),
per-model-prefix pricing table (2.5 Pro/Flash/Flash-Lite, 2.0, 1.5 tiers)
- internal/retry: IsRateLimitError additively extended for RESOURCE_EXHAUSTED
- internal/config: RunnersConfig.Google/GoogleEnabled()
- internal/cli/serve.go, run.go: runners["google"] construction mirroring
the Anthropic wiring exactly (Docker sandbox default)
- docs/api-keys-setup.md: Google marked wired-up, budget-bucket/disable/
verify guidance added matching the Anthropic section
go build/vet/test -race all pass. No live Gemini API key available in this
environment; verified via fake-httptest-server adapter tests (plain text,
tool-use round-trip, multi-turn tool-result, rate-limit error matching) plus
a Pool/NativeRunner routing test. Live E2E is a follow-up once a key is
configured, same as Phase 2's Anthropic adapter.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V1moSNCJRcP6kykA4tyUSs
|
|
Marks Anthropic as live (agent.type: "anthropic" works once a key is
configured), adds the budget-bucket-separation and [runners] disable notes
that Phase 2's implementation agent independently drafted in a since-discarded
duplicate doc, adds an explicit warning against using claude setup-token /
CLI OAuth session for the native adapter (subscription auth is for Claude
Code/Agent SDK use, not a separate product's API calls, per Anthropic's Agent
SDK terms), and bumps default_model examples from claude-sonnet-4-5 to
claude-sonnet-5.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V1moSNCJRcP6kykA4tyUSs
|
|
Covers signup flow, current free-tier limits, and where credentials land in
config.toml for every provider the harness redesign targets. Written earlier
but never committed, so it was invisible to the Phase 1/2 implementation
worktrees — landing it now before Phase 2 merges to avoid two divergent
versions of this file.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V1moSNCJRcP6kykA4tyUSs
|
|
Captures the locked architectural decisions from the chatbot-driven
redesign discussion: SQLite as source of truth with external trackers
as input feeds, events table replacing ad-hoc task columns, per-runner
structured agent channel, three-runner roster with classifier, scoped
auth, multi-dimensional budget, per-runner sovereign resume.
https://claude.ai/code/session_01SESwn7kQ7oP62trWw6pc39
|
|
Merges 12 commits from github/main (formerly master) that were developed
independently. Key additions:
- LocalRunner: OpenAI-compatible local LLM execution (Ollama, LM Studio)
- Real GeminiRunner with full sandbox parity to ClaudeRunner
- llm.Client for enriching CI failures and elaboration via local model
- retry.ParseRetryAfter moved to shared package
- tokens_in/tokens_out columns in executions table
Conflict resolutions:
- Kept local main's VAPID/push, stories, projects, agent events schema
- Merged both sets of Config fields (local + LocalModel from github/main)
- Unified activePerAgent accounting (decActiveAgent helper)
- Removed duplicate helpers from claude.go (now in helpers.go)
- Fixed double-decrement bug in handleRunResult vs decActiveAgent
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
debt; add improvement plan
- Fix YAML key in Task format (agent: not claude:)
- Document complete state machine including BLOCKED and READY states
- Document sandbox lifecycle and git clone failure root cause (sandboxDir shadowing)
- Document all packages including notify, deployment, version, classifier, preamble
- Call out GeminiRunner as a non-functional stub
- Document design debt: unused priority/retry fields, double changestats extraction,
hardcoded master branch, context.Background() in resume, non-atomic exec creation
- Add docs/IMPROVEMENT_PLAN.md with 20 prioritized issues ranked by effort and impact
https://claude.ai/code/session_01W8P6wwDYF7dpETXWVXCz5L
|
|
Closes the three items left on the deferred queue after the post-epic
cleanup.
GeminiRunner.execOnce now actually executes the gemini binary instead
of writing hardcoded stream data. Mirrors ClaudeRunner.execOnce:
- exec.CommandContext with the same env vars (CLAUDOMATOR_API_URL etc.)
- process group SIGKILL on context cancel
- stdout piped through parseGeminiStream → stdoutFile
- stderr to file
- exit codes captured, stderr tail surfaced on failure
Test infrastructure bug uncovered in passing: testServerWithGeminiMockRunner's
mock script used double-quoted echo with literal triple-backticks, which
bash interpreted as command substitution. The script always produced
empty output. The bug was invisible until now because GeminiRunner
ignored the script entirely. Switched to a single-quoted heredoc.
Frontend: index.html dropdown gains a "Local" option. No JS branching
needed — the value flows through to agent.type verbatim and downstream
display reads the type string as-is.
storage/db.go: removed stale debug-comment scaffolding (the "TODO:
Replace with proper logger" block) that was tracking a dead
`fmt.Printf` call. The path it commented on is fine without logging —
unmarshal errors are returned wrapped.
Test status: `go test -race ./...` green across every package, zero
skips, zero excluded tests.
https://claude.ai/code/session_017Edeq947TpSm1vQTxMhi1J
|
|
Addresses the cleanup queue captured in docs/plans/local-oss-runner.md
after the local-OSS-models epic landed. After this commit
`go test -race ./...` is green across every package with zero `t.Skip`
calls and no excluded tests.
Real bugs fixed:
- claude.go setupSandbox callsites used `sandboxDir, err := ...` which
shadowed the outer variable, so BlockedError.SandboxDir was always
empty. Resume-after-block was broken for both new and stale-sandbox
paths. TestBlockedError_IncludesSandboxDir now exercises the right
invariant.
- TestPool_ActivePerAgent_DeletesZeroEntries flake under -race: the
cleanup defer in execute()/executeResume() runs AFTER
handleRunResult sends on resultCh, so consumers observing a result
could see a still-counted activePerAgent entry. Extracted
decActiveAgent(agentType, *cleaned) helper; called explicitly before
every resultCh send, defer becomes a no-op via the cleaned flag.
Verified clean over `go test -race -count=10`.
Test infrastructure made hermetic:
- gitSafe now also passes -c commit.gpgsign=false / -c tag.gpgsign=false
so sandbox tests pass on hosts whose global config requires signing.
- Bare repos in tests initialized with `-b main` (HEAD symbolic ref
matched to the branch we push) so `git log` after push works.
- TestSandboxCloneSource_FallsBackToOrigin uses a local-FS origin URL,
matching sandboxCloneSource's intentional filter against network URLs.
- TestGeminiLogs_ParsedCorrectly URL fixed to the actual log route
(/api/executions/{id}/log).
GeminiRunner gap closed (partial):
- parseGeminiStream now walks lines for `result` events, surfacing
is_error as an error and total_cost_usd as the float return value.
- GeminiRunner.Run propagates parsed cost to Execution.CostUSD.
- TestParseGeminiStream_ParsesStructuredOutput unskipped.
Notes:
- GeminiRunner is still simulated end-to-end (Run writes hardcoded
stream data instead of execing the binary). The result/cost parser
now exists; finishing the runner is a smaller, contained follow-up.
Kept on the deferred queue.
- Frontend "Local" agent option and a minor storage.db.go logger TODO
remain on the deferred queue, both intentionally — neither blocks
anything in flight.
https://claude.ai/code/session_017Edeq947TpSm1vQTxMhi1J
|
|
Phase 4 of "local OSS models as agents" plan. Closes the epic.
When an execution finishes and the agent did NOT write a "## Summary"
heading in its stdout (so the existing extractSummary path returns
empty), and the Pool has a local LLM configured, we now synthesize a
2-4 sentence summary from the assistant text content of the log tail.
Behavior:
- Primary path unchanged: if the agent wrote "## Summary", that wins
byte-for-byte (TestPool_HandleRunResult_ExtractSummaryWins guards).
- Fallback path: empty extractSummary + Pool.LLM != nil → synthesize.
- All-empty path: when no LLM is configured, summary stays empty —
identical to pre-Phase-4 behavior.
Implementation:
- Pool gains an LLM *llm.Client field, wired in serve.go and run.go
alongside Classifier.LLM (same localClient used everywhere).
- New synthesizeSummary in internal/executor/summary.go:
* 6s timeout so a slow local model can't stall finalization
* 16 KB tail cap on the stdout log
* readAssistantTextTail seeks to the last 16 KB and skips the
first (likely partial) line, parses each line as a stream-json
event, joins assistant `text` blocks (skips system/result/etc).
* Returns "" on any error so the caller's behavior never regresses.
- handleRunResult: 3-tier summary resolution — exec.Summary set by
runner → extractSummary → synthesizeSummary → empty.
- minimalMockStore now records UpdateTaskSummary calls (additive;
existing tests unaffected) so integration tests can assert.
Tests (9 new):
- synthesizeSummary nil client / empty path / missing file all
return "" without HTTP calls.
- empty assistant content short-circuits without LLM call.
- success path returns trimmed body, with both assistant texts in
the user prompt.
- LLM 500 returns "" (caller handles same as no-summary).
- readAssistantTextTail seeks past early content in a large file.
- Pool integration: ## Summary present → LLM not called, agent text
used. ## Summary absent + LLM set → LLM called, synthesized summary
recorded against the right task ID.
Plan: docs/plans/local-oss-runner.md.
Epic complete. Post-epic deep cleanup queue captured in the same plan
file for follow-up.
https://claude.ai/code/session_017Edeq947TpSm1vQTxMhi1J
|
|
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
|
|
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
|
|
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
|
|
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
|
|
|
|
- task.Project type + storage CRUD + UpsertProject + SeedProjects
- Remove AgentConfig.ProjectDir, RepositoryURL, SkipPlanning
- Remove ContainerRunner fallback git init logic
- Project API endpoints: GET/POST /api/projects, GET/PUT /api/projects/{id}
- processResult no longer extracts changestats (pool-side only)
- claude_config_dir config field; default to credentials/claude/
- New scripts: sync-credentials, fix-permissions, check-token
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
- Story state machine: SHIPPABLE → DEPLOYED → VALIDATING → REVIEW_READY | NEEDS_FIX
- Merge-first strategy: no branch review phase, tests are the confidence mechanism
- Elaborator owns validation spec (type, steps, success_criteria)
- Validation types: curl | tests | playwright | gradle
- Nav project (Android): deploy = push to GitHub, validate = gradle test/lint
- Project registry: type + deploy_script fields, initial claudomator + nav entries
- Out of scope: branch review deferred, CI polling out of band for nav
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
- debug-execution: default to most recent execution when no ID given
- docs/adr/007: planning layer and story model design decisions
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
|
|
- Fix push failure swallowing and ensure workspace preservation on push error
- Fix wrong session ID in --resume flag and BlockedError
- Implement safer shell quoting for instructions in buildInnerCmd
- Capture and propagate actual Claude session ID from stream init message
- Clean up redundant image resolution and stale TODOs
- Mark ADR-005 as Superseded
- Consolidate RepositoryURL to Task level (removed from AgentConfig)
- Add unit test for session ID extraction in parseStream
|
|
- Fix host/container path confusion for --env-file
- Fix --resume flag to only be used during resumptions
- Fix instruction passing to Claude CLI via shell-wrapped cat
- Restore streamErr return logic to detect task-level failures
- Improve success flag logic for workspace preservation
- Remove duplicate RepositoryURL from AgentConfig
- Fix app.js indentation and reformat DOMContentLoaded block
- Restore behavioral test coverage in container_test.go
|
|
This commit implements the architectural shift from local directory-based
sandboxing to containerized execution using canonical repository URLs.
Key changes:
- Data Model: Added RepositoryURL and ContainerImage to task/agent configs.
- Storage: Updated SQLite schema and queries to handle new fields.
- Executor: Implemented ContainerRunner using Docker/Podman for isolation.
- API/UI: Overhauled task creation to use Repository URLs and Image selection.
- Webhook: Updated GitHub webhook to derive Repository URLs automatically.
- Docs: Updated ADR-005 with risk feedback and added ADR-006 to document the
new containerized model.
- Defaults: Updated serve command to use ContainerRunner for all agents.
This fixes systemic task failures caused by build dependency and permission
issues on the host system.
|
|
elaboration fallback
|
|
- Add ElaborationInput field to Task struct (task.go)
- Add DB migration and update CREATE/SELECT/scan in storage/db.go
- Update handleCreateTask to accept elaboration_input from API
- Update renderSubtaskRollup in app.js to prefer elaboration_input over description
- Capture elaborate prompt in createTask() form submission
- Update subtask-placeholder tests to cover elaboration_input priority
- Fix missing io import in gemini.go
When a task card is waiting for subtasks, it now shows:
1. The raw user prompt from elaboration (if stored)
2. The task description truncated at word boundary (~120 chars)
3. The task name as fallback
4. 'Waiting for subtasks…' only when all fields are empty
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
Keep file-based summary approach (CLAUDOMATOR_SUMMARY_FILE) from HEAD.
Combine Q&A History and Stats tab CSS from both branches.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
- Extend Resume to CANCELLED, FAILED, and BUDGET_EXCEEDED tasks
- Add summary extraction from agent stdout stream-json output
- Fix storage: persist stdout/stderr/artifact_dir paths in UpdateExecution
- Clear question_json on ResetTaskForRetry
- Resume BLOCKED tasks in preserved sandbox so Claude finds its session
- Add planning preamble: CLAUDOMATOR_SUMMARY_FILE env var + summary step
- Update ADR-002 with new state transitions
- UI style improvements
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
- Export computeTaskStats and computeExecutionStats from app.js
- Add renderStatsPanel with state count grid, KPI row (total/success-rate/cost/avg-duration), and outcome bar chart
- Wire stats tab into switchTab and poll for live refresh
- Add Stats tab button and panel to index.html
- Add CSS for .stats-counts, .stats-kpis, .stats-bar-chart using existing state color variables
- Add docs/stats-tab-plan.md with component structure and data flow
- 14 new unit tests in web/test/stats.test.mjs (140 total, all passing)
No backend changes — derives all metrics from existing /api/tasks and /api/executions endpoints.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
|
|
|