Manual 0.8.0

Adopting a project with the history it already has

Who this is for: whoever is pointing Revetly at a project that already has years behind it. You need: an instance whose ordinary pass already works, and a decision-maker for the bill — reading history is the one step here that can cost real money, and on an instance declaring no provider it costs none. Not here: how a connector serves history (writing-a-connector.md §7c) and what each source declares (connector-contract.md).

An ordinary pass reads the current state of every item in scope. What it never reads is the record of how any item got that way — the state transitions, the field changes, the comment thread where the decision was actually argued. So a five-year backlog arrives as three thousand items that all appear to have been decided the morning of the first ingest, and that is the impression that then persists.

Your sources may hold that record. This page is how you find out, what it costs, and what a corpus that was read back only so far will and will not answer.

Nothing on this page starts by itself. Not init, not the first ingest, not watch, not any MCP tool. A backfill is the largest spend and the largest provider exposure an instance will ever authorise, so it is named, priced, and left to you — the same shape revetly migrate and the update endpoint have, and for the same reason.

1. What each source declares — free, offline, no provider call

revetly doctor
[PASS] connector history   todoist: serves state-transitions, comments; windowed over
                           source time; watched for change: comment; horizon: completed
                           work back to the project's creation date …
                           → todoist can serve a backfill — `revetly backfill
                             --dry-run` prices what that would cost, per window, without
                             sending anything. Nothing starts one unasked

Read off each connector's own declaration. No source is called and nothing is spent — an instance deciding whether adopting a decade is worth it must not have to run the pass to find out what is on offer.

A connector that declares no history is not defective; it is the honest answer for most sources, and revetly backfill then refuses it by name rather than returning an empty result you would read as "this tracker had no history".

revetly backfill with no other argument says the same per source, and revetly connectors list carries it beside the rest of the inventory.

The declaration has four parts worth reading rather than skimming:

part why it is not one bit
depths state-transitions, field-revisions, comments — sources differ, and a tracker with no per-field change log can serve two of the three and never the third
windowed whether the source can be asked for a bounded slice at all. windowed=False means narrowing costs the same as the whole archive, and you are entitled to know that before you pay for it
horizon how far back the source can see. Sometimes the account's plan decides it, in which case the plan is read during the pass and said in the window's notes
beyond it what falls outside that horizon, so the silence is legible

The one you already have: git

Every repo-backed source — pm, docs, conversations, deliveries — serves field-revisions out of the repository its roots sit in. There is no API, no token, no rate limit and no vendor: five years of specs in docs/ is five years of how those specs changed, in a local checkout. For a prose tree it is the only history there is.

What that buys, and what it does not:

Free to read is not free to extract: prose is dense, and §2 and §3 below are what bound it. A root that is not inside a git repository serves no history, and the declaration names that root rather than letting you read the silence as "there was nothing".

The one that serves all three: Azure DevOps

Azure DevOps answers every depth the declaration knows about, and it is the source most enterprise backlogs actually live in. What that means in practice:

GitHub Issues is read the same way, in the shape the read connector states:

2. What it would cost — still free

revetly backfill --dry-run

Every source asked for, tiled into windows over source time, each window read from the source and priced against this instance's own measured history — and nothing sent.

todoist: serves state-transitions, comments; windowed over source time; …
  2019-01-01 → 2019-04-01: read 84, would send 84 (12 episode(s), ~$0.34)
  …
across 1 of 4 source(s) — todoist — the history on offer is 148 episode(s) in 12 window(s)
  roughly $4.02 in total, as the sum of 1 separate budgets — an estimate, not a bill
nothing was sent, and nothing here starts unattended. Reading it is one source at a
time, under a ceiling you declare:
  revetly backfill --connector todoist --run --max-episodes 148

Notes on that output:

3. Reading it — the part that spends

revetly backfill --connector todoist --run --max-episodes 148

One source at a time, under a ceiling you declare, checkpointing at every window boundary. docs/failure-and-staleness.md §"When a decade is still loading" has the whole of what stopping, resuming and failing mean; the short version:

4. Afterwards: what a bounded read leaves behind

An instance that ran a bounded backfill holds part of a history, and every read of it is a read of a partial past. Two questions look identical from a result set and only one of them misleads:

CONTEXT has nothing before 2023. Nobody has paid to read before 2023.

So the floor somebody actually paid to reach is reported wherever staleness is reported, and it outlives the command that set it:

This is deliberately not the context_health staleness key. An unfinished or bounded backfill is not a failure and does not make the corpus stale: the last pass succeeded, and what CONTEXT holds is exactly what was paid for. Reporting one as the other would earn a stale warning nobody can act on.

5. A source that is floored before you ever backfill it

Almost every source has a current state an ordinary pass reads whole. A git repository does not — its history is its snapshot — so the commits connector reads each repository forward from the moment that repository was connected to this instance, and no further. That moment is recorded in .revetly/connections.json, per repository, and is never re-derived from the current pass: a repository connected last month still reads from last month.

What that means in practice:

What is not here