Skip to main content

The item lifecycle

A briefing item is not a static row — it moves through a lifecycle: it is born in a session, carried while open, and eventually closed, revived, or removed. Three commands drive the transitions, and all three share one contract: nothing is ever guessed on your behalf.

The never-guess contract​

resolve and forget accept either an exact item id (o-3f8a2c) or a free-text query — but the query must match exactly one item. An ambiguous match is refused with the candidates listed; you pick one by id. Both commands take --dry-run, which runs the same match and prints what would happen without writing anything — look before the write.

One caveat the contract cannot cover: a confident match on the wrong item is not ambiguous, so the refusal never fires. That is what --dry-run is for.

daimon resolve — close a loop​

daimon resolve "retry policy for the payments webhook" --dry-run
daimon resolve o-3f8a2c --note "shipped exponential backoff in #212"

Resolving records an append-only event; from then on, briefings withhold the item instead of carrying it stale. The item is not deleted — its history stays searchable, and the event trail shows when and why it closed. --status accepts a free-form lifecycle status; any status starting with reopen revives the item. A status starting with forgotten: is refused: that is a tombstone, and only daimon forget writes one (it also removes the value from the files).

daimon reverify — assert it's still true​

daimon reverify o-3f8a2c --evidence "checked the release page"

Reverify is the answer to the staleness warning: a carried item aged past the threshold, you checked the world, and it still holds. The event resets the item's last-verified stamp, so the warning clock restarts. Reverify takes exact ids only — re-asserting a claim is deliberate, so there is no fuzzy match to mis-fire.

Reverify is also the reject half of a supersession candidate (below).

daimon forget — remove, provably​

daimon forget o-3f8a2c --reason "contains client name"
daimon forget "wrong belief about retry nonce" --dry-run

Resolve closes an item but keeps its content in history. Forget is for the cases where the content itself must go — a name that should never have been captured, a project detail, a wrong belief that keeps carrying. Capture-time redaction is the first line of defense; forget is the second, for judgment calls no redaction pattern can know about.

What happens on forget:

  • The item is removed from the live checkpoint, which is rewritten through the normal store path — redaction re-runs and, with receipts on, the receipt re-mints over the post-removal bytes (see receipts).
  • An append-only tombstone event records forgotten:<12-char content hash> — the hash, never the text. Removal means the content leaves the audit trail too; the trail can still prove that something was removed, when, and why (--reason, redacted like any note).
  • The recall index deletes the item's rows across all historical checkpoint copies in your local index — including your local copies of team mirrors — so recall cannot resurrect it. (Propagating tombstones into teammates' own mirrors is a deliberate follow-up, not in v1.)
  • The serializer's chunk cache is purged wholesale. That cache keeps pre-redaction extraction output for a few days so an interrupted capture never re-pays its LLM calls — and because its entries are keyed by chunk text, not searchable by contained value, selective removal is impossible. Forget clears all of it (the cost: chunks younger than the rotation window, chunk_cache_days, default 3 days, get re-extracted next time). Entries are also age-reaped at that window independently of forget. The purge is never fatal — removal of the belief state always completes — and the command reports honestly whether the purge succeeded.
  • Briefing withhold, carry suppression, and daimon stats all inherit the tombstone through the same event stream.

Deletion-durability compliance​

The claim "a forgotten memory stays forgotten" is not asserted — it is committed as an executable compliance test that runs on every commit (source). It runs a forgotten value through every path that could quietly resurrect it and proves it stays gone at each one, while a never-forgotten twin stays retrievable so no check can pass vacuously:

#StepResult
1Write a distinctive fact through the serializerretrievable
2forget it — briefing, carry, recallremoved
3Re-feed the original source transcript and re-serializenot resurrected
4Recall index rebuildabsent
5A subsequent carryabsent
6Team dual-write mirrorabsent from the remote copy
7Rendered brief stringabsent
8Recall SQLite rowsabsent
9Signed receiptbinds the post-deletion bytes
10Audit trailrecords the deletion, holds none of its text
11Serializer chunk cache (pre-redaction)purged wholesale on forget

Result: 11 / 11 steps compliant. The tests are deterministic and use zero model quota — a canned extractor and a stubbed signer stand in for the LLM and the vitni CLI — so this is a compliance check that runs on every commit, not a benchmark. Step 3 is the one that matters most: re-ingesting the raw material a deleted item came from is how systems quietly bring it back, and the value-keyed tombstone drops it at the write boundary regardless of what the extractor re-produces.

One bound worth stating exactly: the chunk cache is pre-redaction by necessity (quote verification needs the raw text), so before this step joined the protocol a forgotten value's bytes could sit in the cache until the age reaper fired. Now forget purges the local chunk cache in the same command, and the chunk_cache_days reaper (default 3 days) remains the independent upper bound for anything written after a forget. The claim is scoped to this machine: the cache never syncs anywhere.

daimon handoff — the baton​

Checkpoints are reconstructive: extracted from the transcript, ranked, budget-trimmed, competing for slots. The moment of deliberate handoff — "next session: do THIS first, watch out for THAT" — has different semantics: intentional, small, imperative, and it must never lose rank to ambient noise.

daimon handoff "Ship the release first. Beware: the cache key rotated."
daimon handoff --clear

The baton leads the next briefing, above every section:

HANDOFF (left deliberately by previous session, 2026-08-03T03:43:58Z):
→ Ship the release first. Beware: the cache key rotated.

It is stored as an event, never as a cognitive item — so it cannot enter ranking, dedup, or carry scoring, and it cannot resolve anything. One baton per project; a new one supersedes the old (the event trail keeps history). It stays active until the session that read it ends and serializes — a crashed session never consumes it. Capped small on purpose: a baton is "do X, beware Y", not a second checkpoint.

Decisions carry their because​

A decision without its reasoning invites the next session to re-litigate it. When the transcript states the why, capture keeps one short clause of it:

- [✓ verbatim] soft-clip over hard clamp — because the clamp erased ordering in tied groups

The honesty bar matches everything else: stated reasoning only, never invented — a decision whose why was never said arrives without one.

The redaction boundary, stated exactly​

"A quoted secret never reaches disk" is easily heard as "secrets never leave the machine". Those are different claims, and only the first is made:

  • Redaction is a disk boundary. It runs where bytes are persisted or displayed from disk — checkpoint writes, the team dual-write, event notes, and the status lines read back from crash/error logs.
  • It is not a network boundary. The serialize call ships the raw session transcript to whatever LLM backend you configured — a local backend sees everything, and so does a hosted one. Pick the backend with that in mind.
  • It catches secret shapes, not sensitive meaning. The pattern list is deliberately narrow (see team sharing for the exact inventory): filesystem paths, usernames, hostnames, and emails are not secret shapes, and a stored quote is arbitrary transcript bytes that syncs verbatim to a team remote. forget is the tool for content the patterns cannot know about.
  • The one bounded exception on disk is the pre-redaction chunk cache described above: local-only, mode 0600, age-reaped, purged wholesale by forget.

Supersession candidates​

When a newer session contradicts a carried item, the briefing presents a supersession candidate: both sides, with the confirm/reject commands inline. You verify which side is true in the world, then answer with exactly those commands:

  • Confirm — daimon resolve <id>: the old item is genuinely superseded; future briefings withhold it.
  • Reject — daimon reverify <id>: the contradiction was apparent, not real; the item stands, freshly verified.

The design principle across the whole lifecycle: daimon flags, you decide. Contradiction, staleness, and removal are all surfaced with evidence and resolved by an explicit human (or explicitly-instructed agent) action — never by a silent merge.