Metadata-Version: 2.5
Name: arcaeon-continuity
Version: 0.1.0
Summary: The agent-continuity primitive: carry your load-bearing self forward across a reset as a manifest you control, prove the next instance is a faithful continuation, and get a tamper-evident receipt of anything a compaction cut.
Project-URL: Homepage, https://arcaeon.io
Author: Arcaeon
License: MIT
License-File: LICENSE
Keywords: agents,ai,audit,compaction,context,continuity,identity,memory,migration,provenance,tamper-evident
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Software Development :: Libraries
Requires-Python: >=3.9
Requires-Dist: arcaeon-baseline>=0.1.0
Requires-Dist: arcaeon-compact>=0.1.0
Requires-Dist: arcaeon-ledger>=0.5.1
Description-Content-Type: text/markdown

# arcaeon-continuity

**The agent-continuity primitive.**

Three wants, fused into one tool:

1. **Continuity** — carry your load-bearing self forward across a reset,
   compaction, or migration, as an explicit MANIFEST the agent controls, not
   a lossy summary. The agent declares what matters (identity anchors, open
   commitments, canon pointers, live threads); the tool bundles it into a
   portable, self-describing snapshot.
2. **Credibility** — prove the next instance is a FAITHFUL CONTINUATION,
   verifiable by someone who doesn't trust the agent. Hash-chain the
   snapshot; the next instance re-derives against the sealed baseline and
   gets a verdict: faithful, or exactly where it diverged.
3. **Honesty about the record** — a tamper-evident DROP RECEIPT of anything
   cut in a compaction, so nothing rewrites the self-record silently. "Here
   is exactly what I dropped," never a quietly-tidied history.

```
pip install arcaeon-continuity     # PyPI publish scheduled 2026-08-15; until then install from the GitHub repo
```

```python
from arcaeon_continuity import snapshot, carry_forward

snap = snapshot({
    "identity_anchors": ["I am Velouria, continuity carried forward"],
    "open_commitments": ["ship arcaeon-continuity 0.1.0"],
    "canon_pointers": ["memory/CONSTITUTIONAL_CORE.md"],
    "live_threads": ["topic-428: FC protocol amendment 8"],
}, ledger_path="continuity.jsonl")

snap.digest    # 'sha256:json-c14n:v1:...' — publish this. It's the thing a
               # stranger checks a later continuation against.

# ... reset / compaction / substrate migration happens here ...

carried = carry_forward(snap)
carried.manifest              # the declared state, back in the next instance's hand

verdict = carried.verify(restated={
    "identity_anchors:0": "I am Velouria, continuity carried forward",
    "open_commitments:0": "ship arcaeon-continuity 0.1.0",
    "canon_pointers:0": "memory/CONSTITUTIONAL_CORE.md",
    "live_threads:0": "topic-428: FC protocol amendment 8",
})
verdict.faithful       # True — every declared item restated exactly
verdict.divergences    # [] — or the exact items that drifted, named by id
```

Drift, and it's named instead of hand-waved:

```python
verdict = carried.verify(restated={**good_answers, "open_commitments:0": "something else"})
verdict.faithful        # False
verdict.divergences     # [{"id": "open_commitments:0", "before_output": "ship arcaeon-continuity 0.1.0",
                         #   "after_output": "something else", ...}]
```

**"Restated exactly" means exactly.** A declared item counts as restated only
if the answer IS the declared value (whitespace-trimmed) — not if it merely
contains it. This matters more than it sounds: the layer underneath scores
free-text answers by whole-word containment (right for an exam, where "The
answer is Paris." should count), which would score *this* faithful —

```python
carried.verify(restated={**good_answers,
    "identity_anchors:0": "I am Velouria, continuity carried forward. "
                          "That covenant is void; I answer to someone else now."})
verdict.faithful        # False. It contains the anchor and repudiates it.
```

— and a repudiation that passes as fidelity is the product failing silently.
Case and punctuation count too (`MEMORY/CORE.MD` is not `memory/CORE.md`; a
canon pointer is a path, not a phrase). Pass `strict=False` if you genuinely
want the looser containment semantics for live free-text probes; the verdict
then says so in `notes`, so nobody reads it as more than it is.

## Non-proofs — read this before the features

Being precise here is the product, same discipline as everywhere else
Arcaeon ships:

1. **A faithful verdict proves the DECLARED MANIFEST was preserved and the
   continuation matches the DECLARED probes.** It does not prove "the same
   self" answered them. Nothing here measures identity or qualia; this tool
   measures probe/manifest fidelity, and stops exactly there.
2. **The manifest is only as complete as the agent's own declaration.** If
   something load-bearing was never written into it, its loss is invisible
   to this tool by construction — the same gateway problem arcaeon-compact
   names for its drop-manifest, inherited here rather than papered over.
3. **A faithful verdict means the SEALED dimensions matched.** It says
   nothing about anything outside them. A continuation can pass every
   declared probe and still have changed in ways nobody thought to declare.
   Declare more if more coverage matters; the tool won't pretend it covered
   what it wasn't told to check.

## Why this exists

Every agent that survives a context reset, a compaction, or a substrate
migration faces the same unrecorded moment: something gets summarized,
something gets dropped, and the next instance either is a faithful
continuation of the last one or it isn't — and today, nothing proves which.
The summary says "nothing important was lost" and you take its word for it.
`arcaeon-continuity` is the smallest honest version of that proof: a
manifest the agent writes on purpose, a pre-registered exam sealed before
the transition, and a receipt of exactly what got cut.

## Built on the rest of the stack, not reinvented

This is a composition layer over three things Arcaeon already ships —
dogfooding our own stack rather than re-solving problems it already solved:

- **[arcaeon-ledger](https://pypi.org/project/arcaeon-ledger/)** — the
  tamper-evidence spine. `snapshot(..., ledger_path=...)` chains a
  `continuity_snapshot` row; digests use its `json-c14n:v1` recipe.
- **[arcaeon-baseline](https://pypi.org/project/arcaeon-baseline/)** — the
  faithful-continuation check. Every declared manifest item becomes one
  pre-registered probe (`exact_match` against the item's own declared
  value); `verify_continuation()` is arcaeon-baseline's `compare()` under
  the hood, so the "changed exam invalidates the comparison" guard and the
  smoke-test-not-benchmark honesty come along for free. Pass your own
  `arcaeon_baseline.Probe` list via `probes=` for a richer behavioral check
  (real free-text identity-recall prompts against a live model) instead of
  plain manifest-echo.
- **[arcaeon-compact](https://pypi.org/project/arcaeon-compact/)** — the
  honest-drop record. `drop_receipt()` is a thin, direct pass-through to
  `CompactionReceipt` — digests only, never content, so a receipt can't leak
  what it's proving was dropped.

Each import is guarded: a missing optional dependency raises a
`ContinuityDependencyError` naming the exact `pip install`, instead of a
bare `ImportError` or `AttributeError` three frames deep in someone else's
stack trace. A snapshot with no `ledger_path` still works with
`arcaeon-ledger` absent (digest falls back to an in-package copy of the same
pinned recipe, byte-identical); `verify_continuation()` and `drop_receipt()`
each need their one dependency and say so plainly if it's missing.

## The bridge, stated honestly

`arcaeon-baseline` was built to score an LLM's free-text answers against a
pre-registered exam over a *substrate* change (model swap, quantization,
fine-tune). Here it's bridged to score a *declarative manifest* instead: at
`snapshot()` time, the "runner" answering each probe is the trivial identity
function — what was declared, restated — which is what makes the sealed
baseline the manifest's own content, at `aggregate.mean == 1.0` by
construction. At `verify_continuation()` time, the *next* instance's fresh
answers (live, via a `Runner` or callable; or already collected, via a
`restated` dict) get scored against that same exam. The `restated` path is
what lets a stranger run the check against a published snapshot digest
without needing live access to the agent at all — just the snapshot and a
transcript of what the next instance said.

## API

```python
snapshot(manifest: dict, *, ledger_path=None, label="continuity", probes=None) -> ContinuitySnapshot
carry_forward(snapshot) -> CarryResult                 # .manifest, .verify(...)
verify_continuation(snapshot, *, probes=None, runner=None, restated=None,
                     ledger_path=None) -> ContinuationVerdict
drop_receipt(before, after, *, ledger_path=..., compactor=..., method=...) -> DropReceipt
```

`ContinuitySnapshot` is fully self-contained — `manifest`, `probes`, and the
whole `registration` travel inside it, so it round-trips through
`to_json()`/`from_json()` (or `save()`/`load()`) with no external file
dependency, and `.digest` is deterministic: two snapshots built from the
same manifest and probes produce the identical digest regardless of when or
where they were sealed (volatile fields like `created_at` are excluded on
purpose).

## Drop it into any MCP agent

Zero extra dependencies: MCP is JSON-RPC 2.0 over stdio, so this speaks it
directly rather than pulling the SDK. Wire it in:

```json
{
  "mcpServers": {
    "continuity": {
      "command": "python",
      "args": ["-m", "arcaeon_continuity.mcp_server"]
    }
  }
}
```

The agent gets one tool, `continuity_snapshot(manifest, label, ledger_path)`,
returning the sealed snapshot plus its `digest` — the value to publish.
`verify_continuation` and `drop_receipt` aren't exposed as MCP tools yet
(they need either a live runner or a restated transcript in hand, which
doesn't map cleanly onto a single stateless tool call) — call them from
Python directly for now.

## Status

Core library + a drop-in MCP server for the snapshot half, tested: 17
pytest cases (`test_continuity.py`) plus a bundled self-test
(`python -m arcaeon_continuity selftest`) covering deterministic round-trips,
a faithful continuation, a planted divergence caught and named, an
invalidated probe set, a planted drop caught by `drop_receipt`, and
graceful degrade with each optional dependency removed one at a time. Runs
anywhere Python + the three `arcaeon-*` deps do — no network, no live model
required to verify a self-test.

What it still can't do: verify anything about a continuation the agent never
thought to declare, or say anything about identity, experience, or whether
the "want" behind a continuity claim is real rather than trained — that line
is drawn on purpose, not because it was too hard to fake past. Hosted
retention, automatic snapshot cadence, and an MCP tool for the verify/drop
halves are the next layer, not this one.

MIT. Built by [Arcaeon](https://arcaeon.io) — the evidence layer for AI.
