How it works

Long-running agents exceed useful model context. Naive summarization loses detail, stale summaries override newer instructions, and fresh runs restart work incorrectly. Remaind separates immutable raw truth from derived state, with a mechanical gate at every boundary.

One folder, three sources of truth

Everything lives in a single .context/ directory per project — an append-only raw log, derived working state, and a compact human-readable handover.

.context/
├── CONTRACT.md           # the binding contract
├── active/
│   ├── state.json        # derived working state
│   ├── handover.md       # compact continuity document
│   └── (resume_packet.md, history/  — runtime)
├── logs/
│   └── events.jsonl      # append-only raw timeline — source of truth
├── schemas/              # JSON Schemas + threshold/redaction/tools config
└── (db/context.sqlite, artifacts/  — runtime)

When sources disagree, an explicit authority order resolves truth — lower wins. A stale summary can never override a newer user instruction.

  1. 1Latest explicit user instruction
  2. 2logs/events.jsonl — the raw event log
  3. 3active/state.json — derived working state
  4. 4active/handover.md — the compact handover
  5. 5Derived memories

The lifecycle

Remaind is a substrate, not a framework — your agent loop reads and writes it. Six operations cover the full cycle.

init
Create the .context/ directory once.
log
Append an event for every meaningful thing the agent does.
monitor
Watch the token band: normal → warning → hard → emergency.
compact
When the band climbs, compress — gated by structured validation.
resume
Assemble a fresh-context packet and continue safely.
rollback
Restore derived files from history if something went wrong.

The append-only event ledger

Every user message, tool call, decision, and file change is appended to events.jsonl — one JSON event per line, validated against a JSON Schema before it is written. The raw log is the source of truth: never rewritten, never lossy.

  • Redaction by default. Nine secret patterns (OpenAI/Anthropic keys, JWTs, AWS credentials, private keys, bearer tokens, …) are replaced with deterministic hashes before the event touches disk.
  • Large outputs are routed out. Content over the byte threshold — or any binary payload — is written to artifacts/; the event keeps head/tail excerpts, a SHA-256, and the path. The raw log stays small.
  • Importance is load-bearing. It drives what compaction must preserve.
LevelMeaningCompaction rule
0trace / debugverbose logs you'll rarely need again
1normal useful eventroutine tool calls, assistant turns
2decision · correction · constraint · file change · blocker · resultmust survive every compaction
3remember-instruction · active next step · active blocker · critical user instructionmust be explicit in state or handover

Validated compaction

Compaction reduces the active context while preserving everything load-bearing. A compactor only proposes a candidate; a structured validator decides whether to accept it.

The validator runs six mechanical checks. If any is false, the candidate is rejected and the prior handover is kept untouched — a validation event records why. The compactor proposes; only the validator disposes.

completed_work preserved
decisions preserved
next_step grounded
latest user instruction preserved
importance-3 items preserved
no superseded memory presented as current

The mechanical resume gate

Resume is internal and seamless by default. The gate interrupts the user only when something is mechanically wrong:

  • raw log, state, and handover conflict
  • next_step is missing
  • the latest user instruction is not represented
  • resume confidence is low and the next planned tool is flagged mutates / spends_money / external_side_effect in tools.yaml

Tool risk is read from configuration — never inferred from prose.

Atomic and recoverable

Derived files are written atomically: copy the current version to history/, write a temp file, fsync, rename over the target, fsync the directory. There is no partial-write window.

Every state and handover write snapshots the prior version. rollback --to <timestamp> restores the derived files as of any point in history — and events.jsonl is never touched. Rollback is itself reversible.