Commit Graph

571 Commits

Author SHA1 Message Date
Eyejoker
16d20fe627 feat: paired review system overhaul — unified service, configurable agents, silent output removal
- Remove UNIFIED_MODE legacy: single service manages all 3 Discord bots
- Add OWNER_AGENT_TYPE / REVIEWER_AGENT_TYPE env vars for configurable agent selection
- Fix Discord channel routing: reviewer output goes through correct bot (discord/discord-review)
- Fix channel name assignment: explicit names prevent agentTypeFilter collision
- Remove silent output suppression system: harness-level protections replace prompt workarounds
- Add reviewer approval detection: DONE marker on first line stops ping-pong
- Include user's original message in reviewer prompt for context
- Fix round_trip_count auto-reset on new user message
- Fix session ID conflict: reviewer doesn't reuse owner's session
- Fix pending progress text flush in runner on close sentinel
- Promote buffered intermediate text to final result when result event has no text
- Remove legacy files: .env.codex.example, .env.codex-review.example, migrate-unify.cjs
- Update CLAUDE.md: server-side build deployment, unified architecture docs
2026-03-29 20:50:32 +09:00
Eyejoker
8a4d83e2c1 fix: let both bots see each other's messages in paired rooms for natural ping-pong 2026-03-29 19:22:01 +09:00
Eyejoker
a8bf6b806d fix: run reviewer turn on review_ready status even without new messages 2026-03-29 19:19:47 +09:00
Eyejoker
4ec7b55105 fix: reset task to active on failed execution to prevent stuck state 2026-03-29 19:17:19 +09:00
Eyejoker
fcb854e9de fix: move tmpfs to /tmp instead of inside read-only mount 2026-03-29 19:16:23 +09:00
Eyejoker
c78c97cff7 refactor: use host runners/agent-runner/ in container instead of duplicate code 2026-03-29 19:15:03 +09:00
Eyejoker
aae7714062 fix: align container SDK version with host runner 2026-03-29 19:13:27 +09:00
Eyejoker
a8a21045dd fix: use claude-agent-sdk query() API in container runner 2026-03-29 19:12:20 +09:00
Eyejoker
9a365854c5 fix: add @types/node to container agent-runner 2026-03-29 19:11:06 +09:00
Eyejoker
c36ef36940 fix: slim down Dockerfile apt packages for compatibility 2026-03-29 19:10:13 +09:00
Eyejoker
3e607d7344 fix: enqueue next turn after paired execution so reviewer runs without new message 2026-03-29 19:08:07 +09:00
Eyejoker
4dc4b3bc01 fix: route paired room turns by task status instead of SERVICE_ID
In unified mode, SERVICE_SESSION_SCOPE doesn't match the lease's
owner/reviewer service IDs. Determine the effective role from the
paired task status: review_ready/in_review → reviewer, otherwise → owner.
This restores the owner↔reviewer ping-pong in unified single-process mode.
2026-03-29 19:04:51 +09:00
Eyejoker
9e0de1297c fix: /clear now resets both owner and reviewer sessions in paired rooms 2026-03-29 19:00:42 +09:00
Eyejoker
a1e5418a2f feat: auto-trigger reviewer after owner completion with round trip limit
- Owner finishes → auto mark review_ready → reviewer executes
- Reviewer finishes → task back to active → owner can respond
- Automatic ping-pong until consensus or round trip limit
- PAIRED_MAX_ROUND_TRIPS env var (default 10, 0 = unlimited)
- round_trip_count tracked per task in DB
2026-03-29 18:57:16 +09:00
Eyejoker
338c1f6a1d fix: restrict stop command to /stop only 2026-03-29 18:48:06 +09:00
Eyejoker
05c06fc467 feat: graceful agent abort on SIGTERM via AbortController
When /stop sends SIGTERM, the runner now calls AbortController.abort()
on the Claude SDK query, allowing graceful cleanup of in-flight API
requests before the process exits. Falls back to SIGKILL after 5s.
2026-03-29 18:47:26 +09:00
Eyejoker
2ec90fe086 feat: add /stop command to kill running agent process
- /stop, /cancel, /kill aliases all supported
- SIGTERM first (allows graceful AbortController cleanup), SIGKILL after 5s
- Wired through session-commands → GroupQueue.killProcess()
2026-03-29 18:44:37 +09:00
Eyejoker
d01f98bd61 feat: unify 3 bot services into single process
- Add UNIFIED_MODE flag (default on, disable with UNIFIED_MODE=0)
- Register all 3 Discord bots in one process (claude, codex, review)
- Load all registered groups regardless of agent_type (codex/owner priority)
- Start credential proxy and container cleanup at unified startup
- shouldServiceProcessChat returns true in unified mode
- Add findChannelByName for role-based response routing
- Backward compatible: UNIFIED_MODE=0 restores per-service behavior
2026-03-29 18:37:17 +09:00
Eyejoker
fc9f2867b9 refactor: simplify paired review system and add reviewer container isolation
Phase 1 — Strip over-engineering (-3,665 lines):
- DB tables: 7 → 3 (remove executions, approvals, artifacts, events)
- Task statuses: 11 → 5 (active, review_ready, in_review, merge_ready, completed)
- Remove plan governance, event sourcing, gate/verdict, freshness guards
- paired-execution-context: 980 → 299 lines
- Session commands: remove /risk, /plan, /approve-plan, /request-plan-changes

Phase 2 — Container isolation for reviewers:
- Add container-runtime.ts (Docker abstraction)
- Add credential-proxy.ts (API key injection without container exposure)
- Add container-runner.ts (reviewer-specific read-only mount + tmpfs)
- Add container/Dockerfile + agent-runner (Chromium, Claude Code, Codex)
- agent-runner.ts: auto-route reviewer execution to container mode
2026-03-29 18:24:56 +09:00
Eyejoker
3dd41f749e fix: harden stack restart migration 2026-03-29 07:33:13 +09:00
Eyejoker
ca578d1627 feat: add stack restart orchestration 2026-03-29 07:08:01 +09:00
Eyejoker
0e12a560a4 feat: finalize paired tasks on deploy completion 2026-03-29 06:42:03 +09:00
Eyejoker
dad6f50937 feat: enforce paired reviewer gate verdicts 2026-03-29 06:03:45 +09:00
Eyejoker
29310ce67f feat: recover paired executions after restart 2026-03-29 05:06:25 +09:00
Eyejoker
bb30330c66 feat: add paired execution freshness guard 2026-03-29 04:37:42 +09:00
Eyejoker
03ff69fdd0 fix: tighten auto review checkpoints 2026-03-29 03:58:14 +09:00
Eyejoker
d460933229 feat: add paired intent checkpoints 2026-03-29 03:34:55 +09:00
Eyejoker
2d8f8151dd style: sync high-risk plan gate formatting 2026-03-29 02:14:44 +09:00
Eyejoker
b536c90716 feat: add high-risk paired plan gate 2026-03-29 02:13:57 +09:00
Eyejoker
c76ed1d10a fix: reconcile governance scaffold follow-up 2026-03-29 01:38:30 +09:00
Eyejoker
dc8dd98e84 feat: scaffold paired governance state 2026-03-29 01:35:57 +09:00
Eyejoker
b0c833fd70 fix: keep review requests pending without owner workspace 2026-03-29 00:21:29 +09:00
Eyejoker
29053d3273 feat: formalize paired review command flow 2026-03-28 23:36:46 +09:00
Eyejoker
9006b92648 style: sync paired workspace sparse formatting 2026-03-28 21:34:25 +09:00
Eyejoker
eee09e8b7c fix: clean reviewer snapshots and scope git guard 2026-03-28 21:34:06 +09:00
Eyejoker
06b6326a9d style: sync paired workspace formatting fallout 2026-03-28 21:15:16 +09:00
Eyejoker
e7f49d77da feat: add paired review workspace flow 2026-03-28 21:14:25 +09:00
Eyejoker
79a8a2639e feat: add structured room role metadata 2026-03-28 19:30:32 +09:00
Eyejoker
806e5e4ff1 fix: keep codex approval wording role-based 2026-03-28 17:02:50 +09:00
Eyejoker
772fea45df refactor: share owner prompts and tighten silent output guidance 2026-03-28 07:46:13 +09:00
Eyejoker
b97d1a6260 refactor: unify typing policy across services 2026-03-28 06:52:57 +09:00
Eyejoker
de913985ba fix: promote visible progress after silent final 2026-03-28 06:27:36 +09:00
Eyejoker
38d96578a4 refactor: move retry and recovery paths to structured output helpers 2026-03-28 06:17:52 +09:00
Eyejoker
47dda19ded fix: block malformed structured silent envelope leaks 2026-03-28 06:04:26 +09:00
Eyejoker
0eb2270030 style: sync structured output formatting fallout 2026-03-28 05:57:50 +09:00
Eyejoker
fe6314108c feat: add structured silent output contract 2026-03-28 05:56:58 +09:00
Eyejoker
e1fdc47552 style: sync pre-commit formatting fallout 2026-03-28 05:41:16 +09:00
Eyejoker
ba9f6871b6 feat: add codex review failover and suppress output hardening 2026-03-28 05:40:38 +09:00
Eyejoker
d1c693fb17 fix: treat signal-killed agents as success when output was delivered
Two bugs fixed:

1. agent-runner: process close handler only checked `code !== 0`,
   but signal kills (SIGTERM/SIGKILL from post-close cleanup) set
   code=null which was misclassified as error even after successful
   output delivery. Now checks `code === null && signal` and resolves
   as success when hadStreamingOutput is true.

2. message-agent-executor: wrappedOnOutput persisted newSessionId
   before checking for poisoned session, allowing a stale session to
   be re-saved after clearSession. Reordered to check poison first
   and guard persist with !resetSessionRequested.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 21:25:30 +09:00
Eyejoker
c4744177e9 style: format extractWatchCiTarget line wrap
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 20:59:25 +09:00