Architecture
Architecture
retro is a layered local artifact pipeline.
raw/ -> normalized/ -> catalog/ -> signals/ -> mined/ -> memories/ -> dashboard/
Layers
| Layer | Purpose |
|---|---|
raw/ |
Immutable or revision-preserved source copies from registered hosts. |
normalized/ |
Common NormalizedEvent JSONL stream. |
catalog/ |
Session identity, client context, consolidated project, tags, and exclusion decisions. |
signals/ |
Registered signal definitions plus one evidence-linked line per evaluated session. |
mined/ |
Prompt-time memory candidates per method. |
memories/ |
Canonical memory records, lifecycle events, and derived SQLite index. |
rendered/ |
Human-readable markdown transcripts. |
dashboard/ |
Static HTML dashboard and generated data JSON. |
Source Of Truth
Flat files are canonical:
- raw source captures are immutable;
- normalized events are replayable;
catalog/annotations.jsonlowns user tags, project overrides, and notes;- mined artifacts remain inspectable;
memories/items.jsonlandmemories/events.jsonlown memory state.
Derived artifacts can be rebuilt:
catalog/sessions.jsonl;catalog/state.json;memories/index.sqlite;catalog/sessions.jsonlandsignals/;- the published dashboard generations (
index.html,assets/,data/*.js).
Source Discovery
Built-in and installed source providers register through the retro.sources
Python entry-point group. Retro discovers entry points without importing their
modules, checks extension API compatibility when loaded, and routes list,
import, sync, analysis, and derived rebuilds through validated host IDs.
Imports execute against a staging Layout. Retro validates that a provider
wrote the expected raw directory and normalized JSONL, then replaces both
published artifacts atomically while holding the archive lock. Providers
cannot select arbitrary publication paths through their returned
ImportResult.
Built-in providers exclude explicitly marked synthetic Ghostlab evaluation
traffic before it enters the archive. Codex sessions are identified by
session_meta.originator: ghostlab; Copilot CLI sessions use Ghostlab’s
reserved UUID prefix. This pre-capture filter prevents archive growth. The
catalog separately classifies already-archived and unmarked automation using
metadata, .retroignore, rules, markers, and annotations. Catalog exclusion
never deletes raw or normalized evidence.
Catalog Boundary
retro.catalog.update_catalog gives each record a content-only fingerprint of
normalized files, archived host metadata, and the extractor version. Rules,
project config, annotations, .retroignore, and local Git context use separate
digests in catalog/state.json. A policy-only change re-evaluates the stored
record without reading raw metadata or normalized events and does not invalidate
content-keyed signals. Unchanged sessions require stat checks only; changed
records are republished as one sorted atomic catalog/sessions.jsonl.
Git resolution reads .git directories, linked-worktree gitdir: and
commondir files, refs, and remote config directly. No Git process or network
lookup is involved. Remotes are normalized to host/owner/repo; cwd symlinks
and worktree paths converge on the same main repository. Temp cwd values and
Copilot session-state sandboxes without Git evidence collapse into stable
synthetic scratch projects instead of one project per ephemeral directory.
Tags retain exact sources (rule:<id>, dotfile:<path>, marker, manual).
Rules apply first, then .retroignore, markers, and append-only user
annotations. A session is excluded only when one of its tags appears in
exclude_tags. Mining, memory reindex, signals, task selection, and dashboard
aggregation consume included records by default.
Key Modules
| Module | Role |
|---|---|
src/retro/schema.py |
Canonical event dataclasses and readers. |
src/retro/storage.py |
Filesystem layout conventions. |
src/retro/sdk/ |
Stable extension API, source contracts, and lazy entry-point registry. |
src/retro/extensions.py |
Built-in adapters, diagnostics, staging, validation, and publication. |
src/retro/importers/ |
Host-specific importers. |
src/retro/catalog/ |
Metadata extraction, rules, markers, Git/project resolution, annotations, persistence, and CLI groups. |
src/retro/signals/ |
Session profile builder, signal registry, incremental store, token/cost accounting. |
src/retro/mining/ |
Mining method and filter registries. |
src/retro/memory_store.py |
SQLite schema, reindex, retrieval, authored import, utility updates, weave. |
src/retro/renderer.py |
Markdown transcript rendering. |
src/retro/cli.py |
Typer command surface. |
Plugin Pattern
Source packages expose one adapter class through retro.sources. The class
accepts a Layout, returns SessionDescriptor objects from discover(), and
returns an ImportResult from import_session(). Extension packages declare
API version 1 and import public types from retro.sdk.
Signals and mining methods self-register with decorators.
Signals use @register(...) in src/retro/signals/definitions.py and read a SessionProfile.
Mining methods use @register_method(...) in src/retro/mining/methods/ and must be imported in src/retro/mining/methods/__init__.py.
Mining filters use @register_filter(...) in src/retro/mining/filters/ and must be imported in src/retro/mining/filters/__init__.py.