Owner continuity:
- Seed a freshly created owner task with the previous task's latest owner
final on a cold start after the previous task already closed, so a user
reply to a finalized TASK_DONE no longer produces a "no context" answer.
Activated for this deployment via PAIRED_CARRY_FORWARD_LATEST_OWNER_FINAL
(.env); carried text is injected as clearly-marked background only.
- Skip intermediate STEP_DONE outputs when picking the carry-forward anchor.
Single-mode routing:
- enforceRoomModeOnLease strips a stale reviewer/arbiter lease from a room
switched back to single, preventing single-mode messages from stalling in
the paired path on a stuck execution lease.
Session auth / credentials:
- Pre-sync Claude credentials into each session dir before the agent spawns.
- Honor CLAUDE_CREDENTIALS_PATH in setup/login.ts (per-service isolation).
- Add a relogin-required gate so a permanently logged-out claude-code room
asks the user to re-login instead of spawning a doomed agent.
Other:
- Arbiter verdicts written in the user's language (verdict keyword stays EN).
- status-dashboard chatName field; runtime-inventory credential path resolver.
Tests (make suite fully green: 1595 pass / 3 skip):
- service-routing: default owner is now the claude service and reviewer is
codex-review; update the 7 failover/default expectations accordingly.
- migrate-room-registrations: owner inferred as claude-code (configured
OWNER_AGENT_TYPE) for a dual legacy room; reviewer becomes codex.
- register: mock paired-workspace provisioning + reload signal (registration
now provisions a workspace and hot-reloads); assert RELOADED status.
- paired-execution-context: force a claude-code reviewer to exercise the
Claude read-only branch regardless of the deployment default.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Explicit leases created by failover didn't include arbiter_service_id,
causing arbiter verdict to never be saved (pairedExecutionContext was
undefined). Now falls back to ARBITER_SERVICE_ID from config when the
stored lease has null arbiter_service_id.
Recovered kimi-usage.ts from bot session logs — original was deleted
during March 27 fallback cleanup. Shows 5h/7d usage bars in dashboard
alongside Claude and Codex, using sk-kimi-* coding plan API key.
- Failover is now global (account-level, not per-channel)
- Dashboard shows role model config (Owner/Reviewer/Arbiter + MoA refs)
- Dashboard shows failover status when active
- Auto-clear failover on successful Claude rotation
- Remove per-channel lease writes from failover path
SERVICE_AGENT_TYPE was always 'claude-code' in the unified service,
making it a misleading constant. Each group already has its own
agentType field.
- Removed SERVICE_AGENT_TYPE from config.ts
- Session functions now accept agentType parameter (default: 'claude-code')
- Task scheduler uses task-level agent_type for token rotation decisions
- All fallback defaults changed to 'claude-code' literal
- Logging uses 'unified' instead of the misleading type
- 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
- 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