Skip to content

Memory and continuity

foxctl stores session history, named memory, and task-continuity artifacts so agents can resume work with evidence instead of guessing from stale chat context. The core invariant is simple: retrieved memory is evidence by default. It becomes instruction only when it is an active policy or validated skill.

This page covers the three continuity surfaces — sessions, task history, and named memory — and the safety model that governs how they interact.

Sessions capture agent and user interaction history with lineage edges, context windows, chunk summaries, and restore metadata. They persist across compaction boundaries so work can continue where it left off.

  1. Create or resume an active session (new / resume / fork).
  2. Persist turns, chunks, and lineage edges as work progresses.
  3. Summarize on compaction boundaries (session/summarize).
  4. Set pending_restore_at for post-compact restore workflows.
  5. Restore and continue with session/restore on next start.
  6. Close with terminal status (ok / error / canceled).

Session ID fallback chain (highest priority first):

  1. Explicit ID input
  2. FOXCTL_SESSION_ID
  3. CLAUDE_SESSION_ID
  4. OPENCODE_SESSION_ID
  5. CURSOR_SESSION_ID
  6. Identity file under ~/.foxctl/sessions/active/<workspace_hash>-<agent>.json
  7. TERM_SESSION_ID (last resort)
CommandPurpose
foxctl sessions list --limit 20List recent sessions
foxctl sessions show <id>Show session details
foxctl sessions search --query ...Search session metadata
foxctl sessions chain --session <id> --depth 10Traverse lineage edges
foxctl sessions close --status okClose with terminal status
foxctl sessions statsSession statistics
foxctl sessions resynthesize-v2Rebuild v2 turn/artifact state from source logs
SkillRole
session/restoreRebuild context after resume or compaction
session/summarizeGenerate window and session summaries with extracted learnings
session/recallRetrieve historical sessions and related context

Restore after compaction:

Terminal window
foxctl run session/restore --input '{"session_id":"<id>","trigger":"session_start"}'

Recall past sessions by topic:

Terminal window
foxctl run session/recall --input '{"query":"oauth callback failure","limit":10}'
TablePurpose
sessionsSession header, lineage pointers, agent/LLM context, status
session_turnsPer-turn previews, tool/error metadata
session_chunksChunked archive metadata with optional embeddings
session_chunk_summariesPersisted chunk-window summaries
session_context_windowsCompaction window tracking with token/chunk bounds
session_edgesExplicit lineage edges (continues, forked_from, related)

Task continuity reconstitutes a bounded, hierarchical view of active work from ACA task state, handoffs, sessions, touched files, recent git history, and repoindex anchors. The output is deterministic first and model-assisted second.

Use for Codex, scripts, agents, and other programmatic callers:

Terminal window
foxctl context task-history-summary --workspace .

Returns a structured envelope with:

FieldContent
data.renderedHuman-readable rendered summary
data.summaryMachine-readable summary object
data.artifactCAS digest for the full continuity pack
data.task_idActive task identifier
data.task_titleActive task title

For the complete collected bundle:

Terminal window
foxctl context task-history --workspace .

Returns data.pack, data.summary, and data.artifact.

For a repo-family or lane-specific view across persisted transcript-history records:

Terminal window
foxctl context family-history-summary --workspace .

With filters:

Terminal window
foxctl context family-history-summary --workspace . \
--focus-query "recursive memory consolidation" \
--date-from 2026-03-25 --date-to 2026-03-25

Returns per-item support_metadata with owner_count, latest_updated_at, latest_age_days, and source_owners for trust debugging.

Precondition: Transcript history must be persisted first:

Terminal window
foxctl sessions derive-memory --memory-lane insight --persist-history

Summary modes are deterministic, llm, or llm_cleanup.

For prompt-ready JSON injection in Claude hook flows:

Terminal window
configs/hooks/task-continuity-summary.sh

This thin wrapper emits hookSpecificOutput.additionalContext and hookSpecificOutput.metadata.task_continuity_artifact.

CallerUse
Codex, Jido, scripts, agentsStructured foxctl context task-history-summary command
Claude hooks, prompt injectionconfigs/hooks/task-continuity-summary.sh wrapper

Large continuity packs are persisted to CAS and returned as an artifact digest. This keeps prompt-sized surfaces small while preserving a stable pointer to the full pack for later expansion.

Named memory is a typed evidence layer stored in memory.db. It provides workspace-scoped persistence with optional embeddings, multiple retrieval modes, and a lifecycle model that distinguishes evidence from instructions.

CommandPurpose
foxctl memory list --limit 20List named entries (workspace-scoped)
foxctl memory search --query ...Lexical search over names and summaries
foxctl memory get <name>Fetch a named entry envelope
foxctl memory put --name <n> --type <t> --summary <s>Store a named memory
foxctl memory save <job-id>Save job result into memory
foxctl memory update <name>Update metadata or content
foxctl memory delete <name>Delete named memory
foxctl memory relevant --query ...Retrieve likely relevant entries
foxctl memory recentRecent memory access log
foxctl memory statsMemory store statistics

The canonical retrieval surface returns typed records with lifecycle, trust, provenance, and usage labels:

Terminal window
foxctl run memory/query --input '{"query":"repoindex graph gotchas","limit":10}'

With memory decay ranking enabled:

Terminal window
foxctl run memory/query --input '{
"query":"oauth gotcha",
"memory_decay_enabled":true,
"limit":5
}'

Use the semantic retrieval pipeline for meaning-based search:

Terminal window
foxctl run code/semantic_search --input '{
"query":"oauth gotcha",
"scope":["memories"],
"limit":5
}'

With decay:

Terminal window
foxctl run code/semantic_search --input '{
"query":"oauth gotcha",
"scope":["memories"],
"memory_decay_enabled":true,
"limit":5
}'

Each memory record has a kind that determines its default authority:

KindMeaningDefault authority
working_contextCurrent task/session contextEvidence unless active and current
episodic_traceSomething that happenedEvidence only
semantic_factA factual claim or lessonEvidence until current and non-superseded
decisionProject or runtime decision with rationaleHigher authority when provenance is trusted
procedural_skillA reusable procedureInstruction only after validation
policy_ruleBehavior constraint or routing ruleInstruction only when active and trusted
reflectionAgent-generated lesson or hypothesisLow-authority evidence
eval_resultEvidence that behavior passed or regressedTrusted when produced by eval/runtime
adapter_exampleTraining or consolidation exampleEvidence for future synthesis

Lifecycle determines whether a memory should still affect future behavior:

candidate -> active -> stale -> archived
active -> deprecated
any suspicious record -> quarantined
StateBehavior
candidateStructured but not yet trusted
activeEligible for ordinary retrieval and context selection
staleStill searchable, but suspect unless strongly relevant
archivedRetained for history, excluded from normal retrieval
deprecatedSuperseded by another record, retained for audit
quarantinedNever instruction, evidence only with warning

Pinned is a protection flag, not a lifecycle state. Pinned records are not auto-archived, silently superseded, or model-patched.

Memory decay is a search-time ranking adjustment. It is a soft rerank, not pruning, lifecycle mutation, or deletion. A stale-but-strong match can still surface when lifecycle policy allows it and the base relevance score is high enough.

Decay runs after base query eligibility and lifecycle/trust/provenance filtering. The reranker widens the candidate pool, applies a bounded recency/access factor, then truncates to the requested result window.

Surfacing a memory updates last_accessed and access_count — a retrieval signal only. It does not update use_count, success/failure telemetry, or lifecycle state.

The curator answers: which memories still deserve to affect future behavior?

Terminal window
foxctl run memory/curator_report --input '{"workspace":"."}'

Curator proposals:

ProposalMeaning
demote_staleActive record should move to stale
archiveStale record should move to archived
deprecateRecord is superseded by another
revalidateRecord should be checked before trusted use
skip_pinnedPinned record needs manual review
review_quarantinedQuarantined record remains evidence-only

Dry-run reports are the default. Apply mode requires explicit confirmation and only mutates supported lifecycle-backed lanes.

The evidence model governs how all three continuity surfaces interact safely.

Retrieved memory is evidence by default.
It becomes instruction only when it is an active policy or validated skill.

When memories conflict, authority is ordered by source and lifecycle:

system/pinned policy
> current human instruction
> current repo truth
> validated eval result
> validated skill
> current semantic fact with trusted provenance
> decision evidence
> episodic trace
> agent reflection
> untrusted external content

If memory conflicts with current repo evidence, current repo evidence wins. If memory conflicts with the current user instruction, the current instruction wins unless it violates a higher system/runtime policy.

  • Treat recalled memory as evidence unless it is explicitly promoted by policy. Lane labels and usage labels must stay visible in agent prompts.
  • Keep provenance and timestamps visible. Every record carries source type, session, agent, tool call, commit, file refs, and parent memory IDs.
  • Re-check drift-prone facts before acting on them. Use gather_context or direct repo inspection for current code truth. Pair memory/query with current repo evidence rather than relying on memory alone.
  • Do not route behavior using substring heuristics. Behavior should be driven by structured inputs, typed signals, scoring, or learned policies — not ad hoc keyword matching.
  • Environment-dependent negative claims require revalidation. Claims like “tests cannot run locally” or “API does not support tool calls” should be checked against current state before shaping behavior.
QuestionPreferred surface
What does the repo currently contain?gather_context / repoindex
What have we learned or decided before?memory/query
Is an old claim still safe to use?Load and check current repo evidence, then update lifecycle
Which records should stop shaping behavior?memory/curator_report
What happened in this session or task?session/recall or task-history-summary

Memory embeddings use the shared embedding provider path:

SettingPurpose
FOXCTL_EMBEDDING_BASE_URLOpenAI-compatible embedding endpoint
FOXCTL_EMBEDDING_API_KEYOptional API key
FOXCTL_EMBEDDING_MODEL_<SCOPE>Per-scope model override (e.g., FOXCTL_EMBEDDING_MODEL_MEMORY)
FOXCTL_EMBEDDING_MODEL_TEXTText-scope fallback override
FOXCTL_EMBEDDING_RATE_LIMITProvider-side request rate control
SystemRole
ACAWorkspace control plane — top-of-mind, handoffs, observations
Context engineTyped evidence substrate — evidence packs, retrieval episodes
Obsidian bridgeKnowledge plane — durable vault notes and docs reconciliation
Memory and continuityEvidence layer — named memory, sessions, task history