- Status: proposed
- Date: 2026-02-21
Recurgent currently provides three continuity layers:
- state continuity (
context[...]), - event continuity (
context[:conversation_history]summary records), - executable continuity (persisted method/tool artifacts).
This leaves a known gap: continuity of response substance. A follow-up like "format that algorithm in markdown" often needs the prior response payload (text/code/object), not only call metadata.
Today, conversation_history is intentionally compact (ADR 0019 + ADR 0021): method, args, outcome summary, minimal provenance references. Full response payloads are not persisted there by default. This keeps context slim but prevents reliable content-level follow-up across turns.
This gap is not unique to assistant flows:
- assistant follow-ups (reformat, summarize, compare prior answer),
- debate/philosophy follow-ups (quote or refine prior argument text),
- calculator or other roles when user asks to transform prior explanatory output.
The content(ref) helper is therefore a runtime retrieval primitive, not a shortcut memory hack. Generated code must still reason through follow-up intent:
- identify a content-follow-up request,
- locate the relevant history record,
- resolve
content_ref, - retrieve payload via
content(ref), - transform retrieved payload.
Introduce a dedicated, bounded Response Content Continuity substrate as a fourth continuity layer.
Design rules:
- Keep
contextas working memory, not archival content storage. - Keep
conversation_historycompact and metadata-first. - Store full response content in a separate bounded content store.
- Link history records to content via stable
content_refidentifiers. - Retrieve content on demand; do not preload full payloads into prompts.
Current (metadata continuity only):
# history record (simplified)
{
call_id: "...",
method_name: "ask",
outcome_summary: { status: "ok", value_class: "Hash" }
}Post-ADR (metadata + content reference):
# history record (simplified)
{
call_id: "...",
method_name: "ask",
outcome_summary: {
status: "ok",
value_class: "Hash",
content_ref: "content:01J...",
content_kind: "object",
content_bytes: 1840,
content_digest: "sha256:..."
}
}Content retrieval is explicit:
entry = context[:conversation_history].last
ref = entry.dig(:outcome_summary, :content_ref)
content = content(ref) # bounded content-store lookup
result = format_as_markdown(content)Add a bounded runtime content store (session-scoped by default) with configurable retention:
- max entries,
- max bytes,
- optional TTL,
- LRU/oldest-first eviction.
Store only successful outcomes by default; configurable opt-in for selected error payload classes.
Stored content boundary (explicit):
- Store body is the JSON-safe serialized snapshot of resolved
Outcome.value. - Do not store the full
Outcomeenvelope by default. - Preserve
outcome_summaryin history as compact metadata + reference (content_ref), not payload body. - If serialization fails, store a typed normalized fallback representation and mark serialization mode in metadata.
Depth-aware retention default:
- depth
0: store successful outcomes by default, - depth
>= 1: store only when explicitly opted in or when parent orchestration references child content, - retention pressure should prioritize depth-0 continuity over internal child chatter.
Prompt guidance should:
- advertise
content_refsemantics and helper availability, - teach explicit follow-up sequence: detect follow-up intent -> find relevant history record -> resolve
content_ref-> evaluatecontent_kind/content_bytes-> callcontent(ref)when needed, - prefer summary-only responses when requested intent does not require full body retrieval,
- avoid fabricating content when no reference exists.
content_ref is read-only from generated code.
- generated code can fetch content by ref,
- generated code cannot mutate existing content entries,
- runtime owns creation/retention/eviction policy.
Retention policy governance:
- runtime defaults are code-owned,
- policy mutations (limits, TTL, eviction strategy) should flow through explicit proposal/authority lanes consistent with ADR 0025,
- strict governance enforcement can be phased in during hardening (not required for initial substrate MVP).
conversation_historystores compact summaries and does not persist full payloads by default.- Follow-up transforms that require prior payload content intermittently fail with "not found" style outcomes.
- Some generated flows duplicate content ad hoc into
context, causing inconsistent behavior and memory pressure.
- Content follow-up success rate (reformat/rewrite/summarize previous answer) improves from unstable baseline to
>= 95%when prior turn produced storable content. - "No prior content found" false negatives drop by
>= 80%in validated follow-up scenarios. - Prompt token pressure remains bounded because full content is not preloaded; only refs are embedded in history summaries.
- Content-follow-up behavior becomes explainable in traces because ref resolution is explicit and observable.
- Existing state continuity semantics (
context[:value]/role profile continuity) remain unchanged. - Artifact promotion/lifecycle policy (ADR 0023) remains unchanged.
- Conversation-history record compactness goals from ADR 0019/0021 remain intact.
- This ADR does not auto-promote content retention policy mutations without explicit governance.
- Tests:
- unit: content-store insert/retrieve/evict semantics,
- integration: history record includes
content_reffor successful outcomes, - acceptance: multi-turn follow-up transforms succeed using references.
- Traces/logs:
content_refpresence inoutcome_summary,- content-store hit/miss counters,
- follow-up success/failure by intent class.
- Thresholds:
- follow-up content retrieval hit rate
>= 95%for valid refs, - no unbounded growth: store obeys configured limits in stress tests.
- follow-up content retrieval hit rate
- Observation window:
- minimum
>= 30follow-up calls across>= 3sessions before final retention tuning.
- minimum
- If prompt/context size materially regresses (
>15%median prompt growth), reduce inline ref payload and keep heavy details out of prompt. - If content-store misses remain high (
>10%) for short-window follow-ups, adjust retention policy and ref selection heuristics. - If memory usage exceeds configured envelope under normal workload, tighten eviction policy and default limits.
In scope:
- bounded response content store,
- history-to-content reference linkage,
- runtime read helper for content retrieval,
- prompt guidance and observability fields for content-ref flows.
Out of scope:
- durable long-term archival/search system,
- semantic embedding/vector retrieval,
- autonomous summarization pipelines over all historical content.
- Enables reliable "work with what you just produced" follow-ups.
- Preserves compact history design while adding payload retrievability.
- Reduces ad hoc content copying into generic context keys.
- Adds a new storage subsystem and retention policy surface.
- Requires careful eviction tuning for different roles/use patterns.
- Adds new failure mode (
content_ref_not_found) that must be handled explicitly.
- Expand layer 1 (
context[:last_result]/rolling payload memory).- Rejected: mixes working memory and archival payloads; poor boundedness semantics.
- Expand layer 2 (store full payloads directly in
conversation_history).- Rejected: history bloat for mostly-unused follow-up cases.
- Reuse tool artifact store for response payloads.
- Rejected: artifacts are executable-code lifecycle objects, not turn-content objects.
- Phase 0: schema and retention policy definition + baseline capture.
- Phase 1: runtime content store + history reference linking.
- Phase 2: prompt/runtime retrieval integration for follow-up flows.
- Phase 3: observability, tuning, and policy hardening.
- Keep content continuity separate from state continuity and artifact continuity.
- Never preload full content bodies into system/user prompts by default.
- Enforce bounded retention with deterministic eviction.
- Return typed
content_ref_not_found(orlow_utilitywhere appropriate) instead of fabricated memory.
Add these terms to docs/ubiquitous-language.md:
Response Content ContinuityContent StoreContent RefContent Ref ResolutionContent Retention PolicyContent Eviction