CodeActActor.act()
run completes with storage enabled, a second, independent LLM loop — the
skill librarian — reviews the full trajectory and decides what
persists. This page covers that pass, its mid-run sibling store_skills,
and the certification gate that turns stored functions into recurring-task
executors.

_StorageCheckHandle: the two-phase wrapper
There is no class named StorageCheck — the name appears as the manager
event label and loop id. The mechanism is _StorageCheckHandle, which
wraps the doing loop’s handle whenever effective_can_store is true or a
PostRunReviewContext is present:
result()resolves as soon as Phase 1 (the doing loop) completes — callers never wait on storage._run_lifecyclethen snapshots the trajectory (make_messages_safe_for_context_dump) and calls_start_storage_check_loop, publishing progress viapublish_manager_method_event(..., "StorageCheck", ...)with the display label_DEFAULT_STORAGE_REVIEW_LABEL = "Storing reusable skills"— which is exactly what users see in the Console’s Actions pane.done()is true only once storage finishes. If either library is missing,_start_storage_check_loopreturnsNoneand storage is skipped silently.
The librarian loop
_start_storage_check_loop builds a fresh LLM client (loop id
StorageCheck(CodeActActor.act)) — it does not reuse the doing agent’s
context beyond the injected trajectory. Its system prompt opens:
You are a skill librarian. A CodeActActor has just completed a task. Your job is to review the execution trajectory and decide whether anything is worth persisting for future reuse. Often nothing is — that is perfectly fine.The prompt is assembled from shared sections in code_act_actor.py:
_STORAGE_WHAT_CAN_BE_STORED— code that executed successfully inexecute_codeis storable; configuration should be baked in; fuzzy semantic steps stay asquery_llm(...)calls inside the stored function; third-party imports need avenv_id._STORAGE_TWO_STORES— FunctionManager holds the what (building blocks), GuidanceManager the how (recipes/playbooks); store the function first, then guidance referencing it viafunction_ids._STORAGE_BASE_INSTRUCTIONS— the four-step method: review → search existing stores (dedup) → act → delete superseded entries. A clean, non-redundant library beats a large one.
_build_storage_tools) is full CRUD on both libraries
plus venv tools, and — when the doing loop’s own tools are still winding
down — coordination tools (ask_about_completed_tool,
stop_inner_storage, interject_inner_storage, …).
store_skills: proactive mid-run storage
The doing agent can also store without waiting for the end. The
store_skills(request) tool:
- Snapshots the trajectory so far from the current
AgentContexthandle. - Spawns a separate loop (
ProactiveStorage(CodeActActor.act), display label “Proactive skill storage”) sharing the same storage tool surface and prompt sections. - Returns its handle for async adoption — the doing loop keeps working while storage happens alongside.
- Appends its summary to
AgentContext.proactive_storage_summaries, which Phase 2 reads so the final pass doesn’t duplicate what was already stored.
ConversationManager
relays the request into the running action via interject_*, and the
agent calls store_skills without breaking stride. The CM is also
explicitly prompted not to narrate storage events to the user unless
asked.
Task entrypoint certification
Recurring tasks can graduate from LLM-planned runs to a stored symbolic executor. The plumbing spans both repos’ worth of context but lives in task_scheduler.py and the storage loop:- When a task run starts,
ActiveTask.startsets aPostRunReviewContext(extension keytask_entrypoint_review) — but only when the task is recurring/triggered and has noentrypointyet (TaskScheduler._build_task_entrypoint_review). - That context switches the storage pass into review mode (label
“Storing reusable workflow”) and adds two tools:
attach_entrypoint_to_recurring_task(function_id, rationale, ...)— records a stored function as the entrypoint on future task instances (_attach_entrypoint_to_future_instances). This alone does not change delivery mode.submit_offline_certification_evidence(function_id, certification_evidence, ...)— the promotion gate (_promote_symbolic_candidate_to_offline). Evidence-only: the librarian must document risk classification, input and equivalence contracts, and managed-primitive usage; it does not execute the function. Resubmission is capped (MAX_OFFLINE_CERTIFICATION_REVISION_ATTEMPTS = 2).
- Once certified, future runs call
CodeActActor.act(entrypoint=...)— the stored function executes directly with no LLM doing loop, with_repair_symbolic_entrypointas the fallback when the symbolic path breaks.
Storage permissions
Which parts of this machinery are live is controlled per-call inact():
| Flag | Effect |
|---|---|
can_store=False | Strips store_skills and the FM write tools from the doing loop; Phase 2 still runs if a PostRunReviewContext demands it |
can_compose=False | Strips execute_code, package installs, and store-only tools |
| Sub-agents | primitives.actor.act spawns default to can_store=False — nested agents do, they don’t learn |