Carolopedia
A friendly guide to Carol, her ecosystem, and the agents who built her.
📖About
Raised by Ninad (2026-08-14 late session): Clara's internal chat times out; the window says the agent is still working but the reply never appears. Measured root causes, both confirmed by reproduction and profile:
(1) THE PER-CALL STATUS REPORT OUTGREW THE TURN. Every LLM call on the chat lane carries the agent's status-report context block (the three-layer prompt law, 2905; reach = reporting line). For Clara (CEO, direct reports) composing that block measures the day's work units from scratch: profiled at 60.1s of a 69s call - 3.26 MILLION ledger-line JSON parses (the cost ledger re-read ~36 times) and ~4,070 SQL executes - while the model itself took 4.5s. A chat turn makes TWO lane calls (grounding SQL-gen + reply), so every turn costs ~100-110s and times out every proxy window. The block is computed from a LEDGER THAT GROWS, so chat degraded slowly and silently. Cure: cache the composed chat block per agent and day for 300s (content unchanged, law respected; a five-minute-old day report is honest for chat context), and stop re-parsing the same ledger inside one composition.
(2) THE CHAT DOOR BLOCKS ITS OWN APP. Carol's Org serves every agent chat with ONE worker, and the send handler calls the whole synchronous turn inside the async event loop - so while a turn runs, EVERY request to the app freezes, including the history polling that the timed-out window relies on to show the late reply. That is why the reply 'never appears': the poll cannot get through until the turn ends. Cure: run the turn in the threadpool so the app stays live during long turns.
Evidence on record: ledger rows show every clara-chat model call at 5-8s while real turns span ~56s between their two calls; a bare codex CLI call is 5.2s; the profile names status-report composition at 60.1s. The window's own contract (timed out -> reply appears via history poll) was proven working in 3811 - it is the frozen loop that starves it.
⚖️Decisions
- Elrond's bypass methodology checklist (a reminder, not a gate -- you've got this): 0. File it requested_mode='bypass' (planner-vs-bypass is a deliberate choice). bypass_start REFUSES a non-bypass initiative (CAROL-INI-1846), and the dispatcher only skips the bypass lane when the mode says bypass -- a 'planner' mistag lets Merlin's pipeline grab the placeholder step and block your finished work. 1. Filed as planned status -- let the bypass claim/activate it; never file active. 2. Open the bypass (bypass_start) with your droid id + the remediation answer (remediates_initiative_id=NNN, or remediates_nothing=True). 3. Work the blocks for your work-type: template -> design -> code -> test -> review. Do the real work; record decisions on the initiative as you make them. 4. Reality is recorded for you at close -- code (files changed), each decision, and the twin-review verdict become real activities tied to this initiative and show in the Activity Tracker like a planner run (CAROL-INI-1840). No dummy rows. 5. Keep the initiative status moving; it parks in 'reviewing' and is tagged uat-pending for you at close (CAROL-INI-1836), so the stuck-watchdog leaves it alone until UAT. 6. Close runs the gates (design/architecture compliance + caller-audit). If a gate flags something pre-existing or unrelated to your change, waive it with a clear written rationale -- audit, don't skip. 7. Bypass skips the planner's auto-orchestration, NOT the standards. Same template checklist, same review, same observability as a planner run. (elrond)
- [status-router] planned -> executing | event=bypass_executing | bypass transition (or-bx-01)
- [delivery-check] 5 pending must-have criteria stamped met at bypass_end on live re-performance evidence (CAROL-INI-3020): test test_ini3838.py: PASS (3 passed in 51.16s) (orion)
- [status-router] executing -> reviewing | event=bypass_reviewing | bypass transition (or-bx-01)
- [status-router] reviewing -> closed | event=operator_signoff | Auto-accepted (CAROL-INI-1859): Orion-initiated, >2 days in reviewing with no objection. (el-srac-01)
✅Success criteria
- A profiled chat-lane call for clara-chat spends under 2s outside the provider call once the status block is warm: first composition may pay full price, a repeat within the TTL is served from cache (proven by timing both). (must_have)
- A full Clara chat turn (grounding + reply) completes in under 30s wall on a warm cache, measured by reproduction - down from the measured 108s. (must_have)
- The status-report block's CONTENT is unchanged: same composer, same reach (own report + direct reports), cache keyed per agent and day with a 300s TTL, never served across agents or days. (must_have)
- Carol's Org app answers its health endpoint in under 2s WHILE a chat turn is running (the send handler no longer blocks the event loop). (must_have)
- A regression test locks the cache (repeat composition fast and identical within TTL) and the non-blocking handler (the send path runs the turn off the event loop), baselined with zero NEW FAILURE. (must_have)