<feed xmlns='http://www.w3.org/2005/Atom'>
<title>claudomator.git/internal/scheduler, branch main</title>
<subtitle>claudomator — task automation server
</subtitle>
<id>https://git.terst.org/claudomator.git/atom?h=main</id>
<link rel='self' href='https://git.terst.org/claudomator.git/atom?h=main'/>
<link rel='alternate' type='text/html' href='https://git.terst.org/claudomator.git/'/>
<updated>2026-07-11T08:33:10+00:00</updated>
<entry>
<title>fix(scheduler): retry role-typed FAILED tasks even with no active role_configs</title>
<updated>2026-07-11T08:33:10+00:00</updated>
<author>
<name>Peter Stone</name>
<email>thepeterstone@gmail.com</email>
</author>
<published>2026-07-11T08:32:45+00:00</published>
<link rel='alternate' type='text/html' href='https://git.terst.org/claudomator.git/commit/?id=7978760316319d22670cd6369c15b68c649761bc'/>
<id>urn:sha1:7978760316319d22670cd6369c15b68c649761bc</id>
<content type='text'>
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.
</content>
</entry>
<entry>
<title>fix(scheduler): make arbitration fail-closed on a missing verdict, seed planner's system prompt</title>
<updated>2026-07-11T05:38:25+00:00</updated>
<author>
<name>Peter Stone</name>
<email>thepeterstone@gmail.com</email>
</author>
<published>2026-07-11T05:37:45+00:00</published>
<link rel='alternate' type='text/html' href='https://git.terst.org/claudomator.git/commit/?id=204fe6c536d5d3bca2cb712f66b1d63054807dac'/>
<id>urn:sha1:204fe6c536d5d3bca2cb712f66b1d63054807dac</id>
<content type='text'>
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.
</content>
</entry>
<entry>
<title>refactor(scheduler): migrate story fix loop off RootTaskID re-pointing onto CurrentAttempt resolution</title>
<updated>2026-07-10T20:06:20+00:00</updated>
<author>
<name>Claudomator Agent</name>
<email>agent@claudomator.local</email>
</author>
<published>2026-07-10T20:06:20+00:00</published>
<link rel='alternate' type='text/html' href='https://git.terst.org/claudomator.git/commit/?id=34380da06b1b0f2088f83c1edcb0b506e3196cca'/>
<id>urn:sha1:34380da06b1b0f2088f83c1edcb0b506e3196cca</id>
<content type='text'>
</content>
</entry>
<entry>
<title>refactor(scheduler): recurse processStory into a tree walk over every READY builder-role node</title>
<updated>2026-07-10T19:29:58+00:00</updated>
<author>
<name>Claudomator Agent</name>
<email>agent@claudomator.local</email>
</author>
<published>2026-07-10T19:29:58+00:00</published>
<link rel='alternate' type='text/html' href='https://git.terst.org/claudomator.git/commit/?id=c812eeac49f5ebbcf8b9855a3f56ac4940e074d8'/>
<id>urn:sha1:c812eeac49f5ebbcf8b9855a3f56ac4940e074d8</id>
<content type='text'>
</content>
</entry>
<entry>
<title>refactor(scheduler): generalize finalizeArbitration to any builder-role node, add nested fix-attempt spawning and acceptance-criteria fallback</title>
<updated>2026-07-10T05:49:36+00:00</updated>
<author>
<name>Claudomator Agent</name>
<email>agent@claudomator.local</email>
</author>
<published>2026-07-10T05:49:36+00:00</published>
<link rel='alternate' type='text/html' href='https://git.terst.org/claudomator.git/commit/?id=063a6c1661a91370e2f70d7fab670acd09561619'/>
<id>urn:sha1:063a6c1661a91370e2f70d7fab670acd09561619</id>
<content type='text'>
</content>
</entry>
<entry>
<title>refactor(scheduler): promote story root to COMPLETED only after arbitration approves it, not eagerly on READY</title>
<updated>2026-07-10T00:49:10+00:00</updated>
<author>
<name>Claudomator Agent</name>
<email>agent@claudomator.local</email>
</author>
<published>2026-07-10T00:49:10+00:00</published>
<link rel='alternate' type='text/html' href='https://git.terst.org/claudomator.git/commit/?id=dba9c2e0293f7dd0a4c08d9516df1c7f473c6d8f'/>
<id>urn:sha1:dba9c2e0293f7dd0a4c08d9516df1c7f473c6d8f</id>
<content type='text'>
</content>
</entry>
<entry>
<title>refactor(scheduler): migrate story fix loop off RootTaskID re-pointing onto CurrentAttempt resolution</title>
<updated>2026-07-09T19:45:21+00:00</updated>
<author>
<name>Agent</name>
<email>agent@claudomator</email>
</author>
<published>2026-07-09T19:45:21+00:00</published>
<link rel='alternate' type='text/html' href='https://git.terst.org/claudomator.git/commit/?id=a90ac76f3ccf0bf1259b7ef45e5f331d2b4ec26f'/>
<id>urn:sha1:a90ac76f3ccf0bf1259b7ef45e5f331d2b4ec26f</id>
<content type='text'>
</content>
</entry>
<entry>
<title>feat(scheduler): automatically spawn and re-point a fix attempt when a story is rejected</title>
<updated>2026-07-09T01:51:47+00:00</updated>
<author>
<name>Claudomator Agent</name>
<email>agent@claudomator</email>
</author>
<published>2026-07-09T01:51:47+00:00</published>
<link rel='alternate' type='text/html' href='https://git.terst.org/claudomator.git/commit/?id=ef22ba51d426690cb500aad6fdce0db92bba7f72'/>
<id>urn:sha1:ef22ba51d426690cb500aad6fdce0db92bba7f72</id>
<content type='text'>
</content>
</entry>
<entry>
<title>feat(scheduler): finalizeArbitration consults a structured verdict instead of always routing to REVIEW_READY</title>
<updated>2026-07-08T09:43:25+00:00</updated>
<author>
<name>Claudomator Agent</name>
<email>agent@claudomator</email>
</author>
<published>2026-07-08T09:43:25+00:00</published>
<link rel='alternate' type='text/html' href='https://git.terst.org/claudomator.git/commit/?id=c82def744f23d09562f0bd980ee8333eeb1b90e4'/>
<id>urn:sha1:c82def744f23d09562f0bd980ee8333eeb1b90e4</id>
<content type='text'>
</content>
</entry>
<entry>
<title>feat(story,role): add retro ceremony -- closes the self-improvement loop (Phase 8)</title>
<updated>2026-07-04T05:05:36+00:00</updated>
<author>
<name>Claude Sonnet 5</name>
<email>noreply@anthropic.com</email>
</author>
<published>2026-07-04T05:05:36+00:00</published>
<link rel='alternate' type='text/html' href='https://git.terst.org/claudomator.git/commit/?id=8cb291ad7cdb317ff80947278ee055b1a4925b41'/>
<id>urn:sha1:8cb291ad7cdb317ff80947278ee055b1a4925b41</id>
<content type='text'>
The final mechanism the versioned role-config model (Phase 5) was built for:
when a story reaches DONE, StoryOrchestrator spawns a retro-role task that
reflects on the story's full history and proposes draft role_configs
versions for a human to review and activate via the existing (unchanged)
POST /api/roles/{role}/activate.

- AgentChannel gains a 6th method, ProposeRoleConfig(ctx, role.RoleConfig)
  (version, err), following ProposeEpic's precedent (Phase 7c): a structured
  tool call, not summary-parsing. storeChannel.ProposeRoleConfig calls the
  same Store.CreateRoleConfig the human-facing POST /api/roles/{role}/versions
  endpoint already uses (proposed_by: "retro"), landing a new draft row
  without touching whatever's currently active. Wired through both
  transports exactly like ProposeEpic: internal/agentloop/tools.go (native
  loop) and internal/executor/agentmcp.go (MCP).
- StoryOrchestrator.Tick now routes a story at status DONE to a new
  processRetro stage instead of processStory -- a sibling stage, not a
  continuation, since the Builder-&gt;Evaluators-&gt;Arbitration chain is long
  settled by then. processRetro only *reads* that settled pipeline
  (read-only findEvaluators/findArbitration counterparts to
  ensureEvaluators/ensureArbitration -- it never spawns/mutates
  Builder-pipeline tasks) to locate the Arbitration task the retro task
  depends on, then spawns (idempotently -- checks for an existing
  retro-role dependent first) one retro-role task with instructions
  assembled from the story's spec/acceptance-criteria, full task tree, per-
  task cost/escalation history, active role_configs per role encountered,
  and the story's own event stream (evaluator verdicts, arbitration
  decision).
- event.KindRetroCaptured (attached to the story's ID, matching
  KindEvalVerdict/KindArbitrationDecided's convention) fires once the retro
  task completes (auto-accepted like every other pipeline task), aggregating
  every event.KindRoleConfigProposed the retro task recorded (one per
  propose_role_config call) into {task_id, proposals: [{role, version}],
  summary} -- the summary is the "capturing lessons" half of this ceremony,
  the proposals are the versioned-config half.
- Human activation is completely untouched: drafts land through the
  identical CreateRoleConfig/config_json path Phase 5's endpoints already
  handle, confirmed via existing role-endpoint tests passing unmodified.

go build/vet/test -race -count=1 all pass, full suite (20 packages) -- one
run hit a known, pre-existing, intermittent flake under full-suite load
(unrelated to this phase's files) that did not reproduce on two immediate
reruns, both in isolation and full-suite.

Co-Authored-By: Claude Sonnet 5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01V1moSNCJRcP6kykA4tyUSs
</content>
</entry>
</feed>
