symfonic.agent.cutover.memory_fold¶
memory_fold ¶
When a folded bundle gets a memory capability, and which ports it gets.
TA8.71. One call site held two defects, and each produced a store that stayed
empty while :meth:RetrievalBundle.serves_consolidation answered True:
- the capability was built only
if hydrator is not None, so a deployment that consolidates without hydrating got none at all -- no write stage was declared, the producer was never called, and the turn recorded nothing. Measured as zero records produced, which reads like "nothing worth keeping" rather than like a wiring gap; lifecyclewas never passed, and the capability declares its finalize stage only when it has one. So even a hydrating deployment staged its records and never published them --writeonce,flushnever -- and pending rows are not retrievable by contract.
The second is the sharper lesson. serves_consolidation() asks whether the
ports can flush, and they could. What nobody asked is whether anything calls
them. Capability is not occurrence, and that predicate's licence now rests on
tests/agent/test_turn_publishes_to_the_store.py, which takes a turn through
a real agent and reads the store back, rather than on the ports being present.
memory_capability ¶
memory_capability(hydrator: Any, *, scope: Any, limit: int, writes: Any, records_from: Any, lifecycle: Any, consolidating: bool) -> MemoryCapability | None
The capability this bundle should fold, or None for neither half.
Folded when the deployment hydrates or consolidates: the two halves are independent, and a deployment asking for one must not be silently given neither. Which stages it then declares is the capability's own decision, made per port -- it declares retrieval only with a hydrator, the write stage only with a writer and a producer, and finalize only with a lifecycle.