<feed xmlns='http://www.w3.org/2005/Atom'>
<title>claudomator.git/internal/executor/container.go, branch fix/dockersandbox-gitpush-host-security</title>
<subtitle>claudomator — task automation server
</subtitle>
<id>https://git.terst.org/claudomator.git/atom?h=fix%2Fdockersandbox-gitpush-host-security</id>
<link rel='self' href='https://git.terst.org/claudomator.git/atom?h=fix%2Fdockersandbox-gitpush-host-security'/>
<link rel='alternate' type='text/html' href='https://git.terst.org/claudomator.git/'/>
<updated>2026-06-05T09:21:32+00:00</updated>
<entry>
<title>chore: remove stories/checker backend dead code</title>
<updated>2026-06-05T09:21:32+00:00</updated>
<author>
<name>Claudomator Agent</name>
<email>agent@claudomator</email>
</author>
<published>2026-06-05T09:21:32+00:00</published>
<link rel='alternate' type='text/html' href='https://git.terst.org/claudomator.git/commit/?id=0eb0b79396663c4901597becc6857a4cd795c58e'/>
<id>urn:sha1:0eb0b79396663c4901597becc6857a4cd795c58e</id>
<content type='text'>
Remove the dead stories/checker backend tracked as design debt in CLAUDE.md:
- Delete internal/api/stories.go, stories_test.go, elaborate.go
- Delete internal/task/story.go, story_test.go
- Remove story/checker columns from storage schema and all CRUD methods
- Remove checkStoryCompletion, spawnCheckerTask, triggerStoryDeploy,
  createValidationTask, checkValidationResult, ShipStory, CheckStoryCompletion
  from executor; simplify handleRunResult
- Remove story/checker fields from task.Task (StoryID, AcceptanceCriteria,
  CheckerForTaskID, CheckerReport)
- Remove story routes and geminiBinPath from API server
- Move claudeJSONResult/extractJSON from elaborate.go to validate.go
- Rename ensureStoryBranch -&gt; ensureBranch in ContainerRunner
- Fix git identity in bare-repo tests; fix initial-branch to use main

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>executor: deduplicate worker slots and fix git command execution</title>
<updated>2026-06-04T07:40:46+00:00</updated>
<author>
<name>Peter Stone</name>
<email>thepeterstone@gmail.com</email>
</author>
<published>2026-06-04T07:40:46+00:00</published>
<link rel='alternate' type='text/html' href='https://git.terst.org/claudomator.git/commit/?id=fa3ed5220a28f326d443726233c37e1a7df0ced5'/>
<id>urn:sha1:fa3ed5220a28f326d443726233c37e1a7df0ced5</id>
<content type='text'>
</content>
</entry>
<entry>
<title>merge: integrate oss branch — budget gating, MCP back-channel, events, loopback-only bind</title>
<updated>2026-06-03T23:01:39+00:00</updated>
<author>
<name>Peter Stone</name>
<email>thepeterstone@gmail.com</email>
</author>
<published>2026-06-03T23:01:39+00:00</published>
<link rel='alternate' type='text/html' href='https://git.terst.org/claudomator.git/commit/?id=68cf1e24dd2ca2612b72babc4b35280cd3512f92'/>
<id>urn:sha1:68cf1e24dd2ca2612b72babc4b35280cd3512f92</id>
<content type='text'>
Key features from OSS branch:
- Budget gating: rolling per-provider spend caps with BUDGET_EXCEEDED task state
- Agent MCP back-channel: runners mint tokens; /mcp endpoint resolves them
- Chatbot MCP server at /chatbot/mcp (requires api_token in config)
- Event timeline: unified event stream replacing ad-hoc question/summary flows
- Loopback-only default bind (127.0.0.1:8484); external_bind_allowed=true to expose
- repository_url required on task creation (enforces traceability)
- Auto-checker: spawns verification task after each execution

Conflict resolutions:
- serve.go: keep cfg.Runners.XEnabled() conditional registration from main + agentRegistry from oss
- config.go: keep RunnersConfig from main + BudgetConfig/ExternalBindAllowed from oss
- server.go: handleStaticFiles (base-path rewrite) kept; deduplicated duplicate from both sides
- executor/claude.go: accepted oss deletion (ClaudeRunner replaced by ContainerRunner)
- container_test.go: added noopChannel + AgentChannel parameter to Run call

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>fix: clone from local mirror and sync from GitHub push events</title>
<updated>2026-06-03T01:23:08+00:00</updated>
<author>
<name>Peter Stone</name>
<email>thepeterstone@gmail.com</email>
</author>
<published>2026-06-03T01:23:08+00:00</published>
<link rel='alternate' type='text/html' href='https://git.terst.org/claudomator.git/commit/?id=476a3136a9f55e151ae689cd098795ec865e7850'/>
<id>urn:sha1:476a3136a9f55e151ae689cd098795ec865e7850</id>
<content type='text'>
- ContainerRunner now resolves local project path for non-story (CI)
  tasks, cloning from the local bare repo instead of the HTTPS GitHub
  URL to avoid auth failures on the host.
- CI failure tasks now use SSH URLs (git@github.com:...) instead of
  HTTPS to avoid credential prompts even when no local path is found.
- GitHub push webhook events now trigger an async git fetch into the
  local bare repo, keeping the local mirror in sync when work happens
  directly on GitHub.

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>refactor(executor): retire the file-based question/summary fallback (Phase 8)</title>
<updated>2026-05-27T05:42:31+00:00</updated>
<author>
<name>Claude</name>
<email>noreply@anthropic.com</email>
</author>
<published>2026-05-27T05:42:31+00:00</published>
<link rel='alternate' type='text/html' href='https://git.terst.org/claudomator.git/commit/?id=1deee869e5cd0895e45016192dd70c0ed6c68cf3'/>
<id>urn:sha1:1deee869e5cd0895e45016192dd70c0ed6c68cf3</id>
<content type='text'>
With the MCP agent channel validated (the spike confirmed real claude calls
ask_user/report_summary through it), the container runner no longer needs the
pre-MCP file fallback that read question.json/summary.txt after the agent
exited. Removes that block and the now-orphaned isCompletionReport/
extractQuestionText helpers and their test. The MCP path
(channelPendingQuestion) is now the sole question/summary transport.

https://claude.ai/code/session_01SESwn7kQ7oP62trWw6pc39
</content>
</entry>
<entry>
<title>fix(executor): set IS_SANDBOX=1 so claude honors bypassPermissions under root</title>
<updated>2026-05-26T09:28:57+00:00</updated>
<author>
<name>Claude</name>
<email>noreply@anthropic.com</email>
</author>
<published>2026-05-26T09:28:57+00:00</published>
<link rel='alternate' type='text/html' href='https://git.terst.org/claudomator.git/commit/?id=561915c5182c3fb39cd6a8b6613c489b35b7c1bf'/>
<id>urn:sha1:561915c5182c3fb39cd6a8b6613c489b35b7c1bf</id>
<content type='text'>
The spike found that `claude --permission-mode bypassPermissions` (emitted by
buildInnerCmd) is rejected when the process runs as root, and buildDockerArgs
maps the container --user to the host uid — which is 0 when claudomator runs as
root, breaking all claude tool execution in production.

The container is an isolated sandbox, exactly the case the claude CLI gates
behind IS_SANDBOX=1; setting it in the container env makes bypassPermissions
work regardless of the host uid. Verified empirically against claude 2.1.150
(rejected as root without it; succeeds with it). Harmless for gemini containers.

https://claude.ai/code/session_01SESwn7kQ7oP62trWw6pc39
</content>
</entry>
<entry>
<title>feat(executor): wire the agent MCP back-channel for gemini containers (Phase 4)</title>
<updated>2026-05-25T19:02:19+00:00</updated>
<author>
<name>Claude</name>
<email>noreply@anthropic.com</email>
</author>
<published>2026-05-25T19:02:19+00:00</published>
<link rel='alternate' type='text/html' href='https://git.terst.org/claudomator.git/commit/?id=65cd7ea65d9c6fe0fad39bb2c5cac70d61153444'/>
<id>urn:sha1:65cd7ea65d9c6fe0fad39bb2c5cac70d61153444</id>
<content type='text'>
ContainerRunner previously skipped the MCP back-channel for gemini agents, so
they ran tool-less. It now mints a per-task token for gemini too and registers
the agent MCP server in the gemini CLI's user settings
(agentHome/.gemini/settings.json → $HOME/.gemini in-container) using the
gemini-cli mcpServers/httpUrl schema with a bearer header. With MCP enabled,
gemini also receives the planning preamble that points at the ask_user/
report_summary/spawn_subtask/record_progress tools.

Config generation is unit-tested (TestWriteGeminiMCPSettings) and the write is
in the run setup path. CAVEAT: whether the gemini CLI actually invokes these
tools in non-interactive (-p) mode — and how it handles tool auto-approval —
is NOT verified against a live gemini binary in this environment; this lands
the plumbing for a follow-up spike. No regression risk for gemini runs: a
config issue degrades to the prior tool-less behavior.

https://claude.ai/code/session_01SESwn7kQ7oP62trWw6pc39
</content>
</entry>
<entry>
<title>feat(executor): MCP-oriented planning preamble, applied by ContainerRunner (Phase 2)</title>
<updated>2026-05-24T17:38:53+00:00</updated>
<author>
<name>Claude</name>
<email>noreply@anthropic.com</email>
</author>
<published>2026-05-24T17:38:53+00:00</published>
<link rel='alternate' type='text/html' href='https://git.terst.org/claudomator.git/commit/?id=473d80224880dd718cb2612fd49b987cd6097b2c'/>
<id>urn:sha1:473d80224880dd718cb2612fd49b987cd6097b2c</id>
<content type='text'>
Rewrites the planning preamble to point the agent at the four MCP tools
(ask_user/report_summary/spawn_subtask/record_progress) instead of the
CLAUDOMATOR_QUESTION_FILE / CLAUDOMATOR_SUMMARY_FILE conventions: ask_user ends
the turn, report_summary replaces the summary file, spawn_subtask replaces the
POST-to-/api/tasks planning step. Git discipline is retained.

ContainerRunner previously applied no preamble at all; it now prepends this
preamble (via buildAgentInstructions) when the MCP back-channel is active and
skip_planning is false, so the in-container agent is actually guided to use the
tools. Gemini agents (no MCP) are unaffected.

https://claude.ai/code/session_01SESwn7kQ7oP62trWw6pc39
</content>
</entry>
<entry>
<title>feat(executor,api): wire agent MCP into ContainerRunner + mount /mcp (Phase 2)</title>
<updated>2026-05-24T09:45:16+00:00</updated>
<author>
<name>Claude</name>
<email>noreply@anthropic.com</email>
</author>
<published>2026-05-24T09:45:16+00:00</published>
<link rel='alternate' type='text/html' href='https://git.terst.org/claudomator.git/commit/?id=952b7623ee9dceec15099043086622aa2aab4741'/>
<id>urn:sha1:952b7623ee9dceec15099043086622aa2aab4741</id>
<content type='text'>
ContainerRunner now mints a per-task MCP token (from an injected Registry),
writes a claude mcp-config into the workspace pointing at the host agent MCP
server over host.docker.internal with that bearer, and adds --mcp-config to the
in-container claude invocation. The token is revoked when the run ends. After
the run, a buffered ask_user (PendingQuestion on the channel) is converted into
a BlockedError — the MCP path to BLOCKED — with the file-based question.json
kept as a fallback for in-flight tasks started on the old wire.

The API server mounts the StreamableHTTP MCP handler at POST/GET/DELETE /mcp
when a registry is provided; serve.go constructs one Registry shared by the
runners (mint) and the server (resolve). Minting is skipped for gemini agents.

Tests: writeMCPConfig output shape, buildInnerCmd flag presence/absence, and an
api-level end-to-end MCP tool call through NewServer/Handler proving the route
is mounted (and absent without a registry).

https://claude.ai/code/session_01SESwn7kQ7oP62trWw6pc39
</content>
</entry>
<entry>
<title>feat(executor): introduce AgentChannel seam for runner signals</title>
<updated>2026-05-24T08:47:07+00:00</updated>
<author>
<name>Claude</name>
<email>noreply@anthropic.com</email>
</author>
<published>2026-05-24T08:47:07+00:00</published>
<link rel='alternate' type='text/html' href='https://git.terst.org/claudomator.git/commit/?id=c7d95f3992d24f86ff71e5f3e18260a8ef8a09f0'/>
<id>urn:sha1:c7d95f3992d24f86ff71e5f3e18260a8ef8a09f0</id>
<content type='text'>
Defines AgentChannel — the normalized interface by which a runner reports
agent-originated signals (AskUser, ReportSummary, SpawnSubtask,
RecordProgress) — plus a default storeChannel implementation backed by
storage. Runner.Run now takes an AgentChannel; the pool constructs one
per execution.

The file transport routes its post-exit summary detection through
ch.ReportSummary (buffered onto the execution so the pool still applies
its extract/synthesize fallbacks, no double-write). AskUser returns
ErrAgentBlocked since write-and-exit cannot answer in-session; question
persistence stays with the pool's BlockedError handling. SpawnSubtask
and RecordProgress are implemented and tested, ready for the MCP
transport in Phase 2 where the channel becomes fully load-bearing.

Store gains CreateEvent so the channel can emit agent_message events.

https://claude.ai/code/session_01SESwn7kQ7oP62trWw6pc39
</content>
</entry>
</feed>
