Commit Graph

644 Commits

Author SHA1 Message Date
Eyejoker
f30b25d2b4 fix: use English role labels (owner/reviewer) for paired room sender names 2026-03-30 19:31:31 +09:00
Eyejoker
c17edd8773 feat: label bot messages with role names in paired rooms
In paired rooms, bot messages now show sender as "오너" or "리뷰어"
instead of the Discord nickname. Uses channel.isOwnMessage() to
identify which bot sent each message, then maps via the channel
lease to determine the role. This ensures agents correctly identify
who is the owner and who is the reviewer regardless of bot nicknames.
2026-03-30 19:30:59 +09:00
Eyejoker
7ec86433ad feat: add comprehensive verification tools to reviewer container
Media: ffmpeg, sox, mediainfo, imagemagick
Build: make, gcc, g++, python3, pip
Utils: jq, file, sqlite3, rsync, zip/unzip, strace
2026-03-30 19:20:39 +09:00
Eyejoker
b1d9b4cd5b feat: add common verification tools to reviewer container
Add ffmpeg, sox, imagemagick, jq, python3 so the reviewer can verify
audio encoding, image assets, and data without claiming tools are
missing.
2026-03-30 19:16:17 +09:00
Eyejoker
0bcfa72b6b fix: include original filename in attachment prompt text
Agents receive `[Audio: original.wav → /path/to/saved.wav]` instead
of just the path, so they know what file it is and where to find it.
2026-03-30 18:41:36 +09:00
Eyejoker
ad34062dbc feat: mount attachments directory in reviewer container
Discord file attachments are downloaded to data/attachments/ on the
host. Mount this directory read-only in the reviewer container at the
same absolute path so both owner and reviewer can access uploaded
files (WAV, images, etc.) using the same path.
2026-03-30 18:40:36 +09:00
Eyejoker
fcd180434d feat: download audio file attachments instead of transcribing them
Voice messages (Discord IsVoiceMessage flag or attachment with duration)
are still transcribed via Whisper. Regular audio file attachments (WAV,
MP3, etc.) are now downloaded to disk and the path is passed to the
agent, matching image attachment behavior.
2026-03-30 18:37:10 +09:00
Eyejoker
e51afc27f0 feat: failover reviewer to codex when Claude reviewer is unavailable
When the reviewer is Claude and hits auth/429/overloaded errors,
hand off the review turn to codex-review instead of swapping
owner/reviewer roles (which is the owner failover path).
2026-03-30 18:15:17 +09:00
Eyejoker
fa8ca476d8 fix: reset task status to active on new human message
When a user sends a new message while the task is in merge_ready,
review_ready, or in_review status, the owner's turn was incorrectly
treated as a finalize turn. This caused premature task completion
(DONE → completed) even when the user wanted to continue working.

Now resets status to active alongside round_trip_count, ensuring
the owner gets a fresh working turn instead of a finalize turn.
2026-03-30 17:59:27 +09:00
Eyejoker
d5d0ee5332 Merge pull request #4 from phj1081/codex/fix-stale-final-leak
fix: isolate stale finals from next runs
2026-03-30 08:09:03 +09:00
Eyejoker
17e92d4c3d fix: isolate stale finals from next runs 2026-03-30 05:23:29 +09:00
Eyejoker
008154b57d fix: inject real OAuth token to reviewer container instead of proxy
The credential proxy cached the OAuth token at startup, but Anthropic
no longer supports raw OAuth Bearer tokens on the API. The Claude Code
SDK handles OAuth internally, so the proxy was breaking auth.

Now injects the real token both at container creation and at each
docker exec, so token rotation is picked up without recreating the
container.
2026-03-30 05:14:03 +09:00
Eyejoker
3281736390 feat: inject Sentry read-only token into reviewer container 2026-03-30 04:21:18 +09:00
Eyejoker
e13c1df520 feat: skip auto-review when active CI watcher exists
When the owner registers a CI watcher and completes the turn, the
review loop no longer triggers. The watcher result will be posted
via the reviewer bot, which the owner picks up and acts on, then
the normal review loop resumes.
2026-03-30 04:11:30 +09:00
Eyejoker
0ae937c4e2 feat: add gh CLI to reviewer container image 2026-03-30 04:03:17 +09:00
Eyejoker
41dc7969ae fix: route CI watcher completion via reviewer bot in paired rooms 2026-03-30 04:01:44 +09:00
Eyejoker
760e222b54 fix: explicitly declare owner role in paired room prompt 2026-03-30 03:58:39 +09:00
Eyejoker
bc5eb506ba Merge pull request #3 from phj1081/codex/fix-remaining-test-debt
test: align prompt and scheduler expectations
2026-03-30 03:56:55 +09:00
Eyejoker
54fc67e283 test: align prompt and scheduler expectations 2026-03-30 03:55:58 +09:00
Eyejoker
f0f665edb8 Merge pull request #2 from phj1081/codex/fix-format-after-pr1
style: fix prettier drift after merge
2026-03-30 03:49:33 +09:00
Eyejoker
5221fb8b33 style: fix prettier drift after merge 2026-03-30 03:44:58 +09:00
Eyejoker
5e4f1fa8da Merge pull request #1 from phj1081/codex/remove-explicit-paired-review-command-path
refactor: remove dead paired review and output suppression paths
2026-03-30 03:35:34 +09:00
Eyejoker
3015c3ea9a feat: mount parent .git for worktree resolution in reviewer container
Git worktrees reference the parent repo's .git directory via absolute
path. Without mounting it, all git commands fail inside the container.
Now reads the .git file, resolves the parent .git path, and mounts it
read-only at the same host path so references resolve naturally.
2026-03-30 03:28:09 +09:00
Eyejoker
8e9975aa2b fix: add log for container CLAUDE.md injection verification 2026-03-30 03:24:07 +09:00
Eyejoker
e863db61a8 refactor: remove dead output suppression path 2026-03-30 03:22:08 +09:00
Eyejoker
e78f0b1968 fix: remove .claude nesting from reviewer session dir path
CLAUDE_CONFIG_DIR included .claude suffix, but the container mounts
the parent directory at /home/node/.claude. This caused double nesting:
/home/node/.claude/.claude/CLAUDE.md — SDK never found the prompts.
2026-03-30 03:20:29 +09:00
Eyejoker
5b8c198e6b fix: remove agent_type filter from getDueTasks for unified service 2026-03-30 03:01:36 +09:00
Eyejoker
96ca9c0655 fix: use in-process Codex usage cache for unified service dashboard 2026-03-30 02:58:28 +09:00
Eyejoker
debcbfccc2 docs: add fallback provider settings to .env.example 2026-03-30 02:56:33 +09:00
Eyejoker
5b8931f94e docs: set recommended model/effort defaults in .env.example 2026-03-30 02:55:48 +09:00
Eyejoker
c7725b1cb4 fix: run Codex usage collection in unified service mode 2026-03-30 02:55:18 +09:00
Eyejoker
c04b1d9a6f docs: update .env.example for unified service architecture 2026-03-30 02:53:55 +09:00
Eyejoker
4b4863330b fix: add debug log for dashboard channel discovery failure 2026-03-30 02:50:37 +09:00
Eyejoker
1031cd44dd refactor: SSOT for paired room prompts, remove 4 duplicate files
All reviewers (claude, codex-review, codex-review-failover) now use
claude-paired-room.md. All owners use owner-common-paired-room.md.

Removed: codex-paired-room.md, codex-review-paired-room.md,
codex-review-failover-paired-room.md, codex-review-platform.md

10 prompt files → 6.
2026-03-30 02:39:04 +09:00
Eyejoker
0c6167f5dc fix: remove hardcoded finalize instructions from turn prompt 2026-03-30 02:35:44 +09:00
Eyejoker
17b60cb10f fix: restore communication discipline details and stagnation pattern names
The anti-pattern guardrails ("It should work now" means run it, etc.)
and stagnation pattern names (Spinning/Oscillation/Diminishing/No progress)
are too useful to compress out — they prevent common LLM failure modes.
2026-03-30 02:33:41 +09:00
Eyejoker
691be0dc86 refactor: streamline paired room prompts and fix role separation
Prompts:
- Remove model-specific names (클코, Codex) — use owner/reviewer only
- Compress duplicated sections (communication, stagnation, consensus)
  while preserving 4 ontological questions and verdict protocol intact
- Remove verdict examples (redundant with status descriptions)
- claude-platform.md: strip SDK defaults, keep only send_message rules

Code:
- Remove reviewer paired room prompt from owner CLAUDE.md
  (was causing role confusion — owner got "You are the reviewer")
- Remove "Provide feedback or approve" from review turn prompt
  (conflicted with CLAUDE.md verdict protocol)

187 lines → 100 lines across 4 prompt files.
2026-03-30 02:31:04 +09:00
Eyejoker
484c0d7316 fix: mount reviewer session dir matching CLAUDE_CONFIG_DIR path
Container mounted data/sessions/{folder}/ but CLAUDE.md was written
to data/sessions/{folder}-reviewer/.claude/ by paired-execution-context.
The reviewer never saw its prompts (verdict protocol, paired room rules).

Now mounts {folder}-reviewer/ to match, so the CLAUDE.md with platform
and paired room prompts is visible inside the container.
2026-03-30 01:50:29 +09:00
Eyejoker
6edf5aebbd refactor: remove explicit paired review command path 2026-03-30 01:43:48 +09:00
Eyejoker
1e9e69ed23 fix: remove duplicate suppression that swallowed final output
The alreadyVisible check compared progress text with final text and
skipped deliverFinalText when they matched. This caused legitimate
final outputs to vanish when the progress message happened to
accumulate the same text through edits.
2026-03-30 01:39:02 +09:00
Eyejoker
aa6477cf2b fix: respect owner verdict during finalize turn
When the reviewer approves (merge_ready) and the owner finalizes,
the system previously only checked for code changes. If the owner
raised concerns (DONE_WITH_CONCERNS, BLOCKED, NEEDS_CONTEXT) during
finalize — e.g. push failed due to detached HEAD — the system
ignored it and auto-completed the task.

Now the owner's verdict is checked first. If the owner raises
concerns, the task goes back to active and re-triggers the reviewer
so the issue can be addressed collaboratively.
2026-03-30 01:37:30 +09:00
Eyejoker
ab2680ba11 feat: route cron output via reviewer bot in paired rooms
In paired rooms, cron output was posted by the owner bot. Since the
owner can't respond to its own messages, the cron report just sat
there with no follow-up action.

Now cron output in paired rooms is posted via the reviewer bot. The
owner picks it up as a peer request, analyzes the report, and acts
on it (e.g., fixing Sentry errors). The normal paired review loop
then kicks in to verify the fix.
2026-03-30 01:32:06 +09:00
Eyejoker
d024b763f0 fix: prepare CLAUDE.md and roomRoleContext for container reviewer
Container reviewer was running without prompts because the container
path in agent-runner.ts skipped prepareGroupEnvironment() entirely.
This meant no CLAUDE.md (platform + paired room prompts + memory
briefing) and no roomRoleContext were passed to the container.

- Add prepareContainerSessionEnvironment() to write CLAUDE.md, sync
  skills, and ensure settings.json for the reviewer session directory
- Pass roomRoleContext through ReviewerContainerInput so the runner
  can prepend the [ROOM_ROLE] header
- Add roomRoleContext field to ReviewerContainerInput interface
2026-03-30 01:12:47 +09:00
Eyejoker
cb66510378 docs: update README with container isolation architecture
- Add container-isolated reviewer, post-approval change detection, credential proxy features
- Update architecture diagram: owner (host process) vs reviewer (Docker container, :ro mount)
- Add Docker to prerequisites
- Update session persistence description (separate sessions per role)
2026-03-30 01:01:10 +09:00
Eyejoker
a215b2471a chore: formatter cleanup and test updates from bot cherry-pick 2026-03-30 00:57:03 +09:00
Eyejoker
5865dea558 fix: route reviewer output to reviewer channel in queued message path
When reviewer was triggered via the normal message dispatch path (not
the review_ready check path), output was sent through the owner channel.
Now checks paired task status to determine the correct output channel.
2026-03-30 00:54:51 +09:00
Eyejoker
13dbf21025 fix: remove snapshot copy from prepareReviewerWorkspaceForExecution
This was the second code path that still called
refreshReviewerSnapshotForPairedTask (file copy). Now returns owner
workspace directly like markPairedTaskReviewReady does.
2026-03-30 00:51:24 +09:00
Eyejoker
6cb0b38ba3 refactor: persistent reviewer containers with docker exec per turn
Instead of docker run --rm per turn (~300ms overhead), containers are
now created once per channel with docker run -d and reused across turns.
Each turn runs via docker exec inside the warm container.

- ensurePersistentContainer: creates or reuses container per channel
- stopReviewerContainer: explicit stop for /clear or shutdown
- Container stays alive with sleep infinity, turns exec node runner
- cleanupOrphans handles stale containers on restart
2026-03-30 00:45:42 +09:00
Eyejoker
42079d5796 refactor: remove host-mode reviewer, container-only
Reviewer always runs in Docker container. No more snapshot file copy —
reviewer mounts the owner workspace directly as read-only. Removes
REVIEWER_CONTAINER_ENABLED toggle and host-mode fallback code.
2026-03-30 00:39:50 +09:00
Eyejoker
53ed437034 fix: handle directory-to-non-directory conflict in copySnapshotPaths
When git ls-files returns directory entries (nested git repos),
cpSync fails trying to overwrite a file placeholder with a directory.
Now removes the conflicting target file before copying.
2026-03-30 00:36:36 +09:00