# Background archiving

> Keep your archive current with the watcher, a background process that imports new sessions from your local harnesses as you work.

The watcher is a background process on your machine. It imports new sessions
from your local harnesses as you work, keeps the search index current, and runs
the scheduled tasks you turn on, such as memory backup, usage sampling, and
sync.

## Manage the watcher in the app

1. Open **Settings → Imports**.

2. Under **Status**, check that **Background import** reads **Running**.
   Hansard starts a watcher that stopped on its own, so it may read
   **Starting** for about a minute. To stop the watcher, select **Stop**. It
   finishes the current import first, and it stays stopped until you select
   **Start**, or until your next login while **Start at login** is on.

3. Turn **Start at login** on or off. Turning it off keeps a running watcher
   running.

4. Under **Agents**, set **Selection** to **Automatic** to follow every
   supported harness installed on this computer, or to **Custom** to turn
   individual harnesses on or off.

5. Under **History**, set **Look-back window** to how many days back each
   watcher pass looks.

**Pause search updates** stops search index updates but keeps importing
sessions. Sessions imported while it is on stay out of search until you turn
it back off.

To check the result, open **Sessions**, select **Filter & sort**, choose
the harness under **Source**, and set **Time** to a recent range.

Startup at login is on by default. Hansard keeps the watcher, the account
router, and remote access running unless you stopped them: when one stops on
its own, after a crash, a restart that did not finish, or an update, the app,
its menu bar item, remote access, and the next `hansard` command start it
again within about two minutes, and the title band reads **Starting the
watcher…** meanwhile. When startup at login was lost, for example after a
restart, Hansard turns it back on. If it cannot, for example because Hansard
is off in **System Settings → General → Login Items**, the title band says
so. If you turned startup at login off yourself, in setup or with
`hansard watcher login disable`, Hansard leaves it off. Set
`HANSARD_KEEP_SERVICES=0` to keep Hansard from starting them.

On macOS, the desktop app starts the watcher through its own login item, which
**System Settings → General → Login Items** lists as Hansard. The watcher then
reads Documents, Desktop, Downloads, cloud storage folders, other apps' data,
and external and network drives only where macOS allows the Hansard app, and
skips the rest without asking. **Settings → Imports → macOS access** lists
each of these permissions, and **Ask macOS** asks for the ones not answered
yet. See [macOS login items and folder access](https://www.hansard.dev/getting-started/download/#macos-login-items-and-folder-access).

The watcher imports with the code of the copy of Hansard that started it.
When the desktop app is installed or updated while the watcher runs an older
release from a source checkout, an npm installation, or another copy of the
app, Hansard stops that watcher and starts it from the app, with startup at
login when that was on. A watcher that runs the same or a newer release, such
as a source checkout ahead of the app, keeps running. The other way around
works too: a watcher that runs from a source checkout or an npm installation
moves itself to a newer build of Hansard installed on the same computer within
about fifteen minutes, without the app opening, and the remote host does the
same. A watcher that runs from the app moves only to a newer app, so it keeps
the folder access macOS gave the app. `hansard status` names
the copy the watcher runs, and **Settings → Imports** shows it as
**Watcher version**.

The app controls source selection and indexing, and can start and stop the watcher. To restart the watcher, or to read its log, use the CLI. A full-history import also runs from
the CLI with `hansard import --since all`.

## Set up the watcher from the CLI

1. Choose the sources to watch.

   ```sh
   hansard config sources edit
   ```

   For a scripted setup, pass the list directly:

   ```sh
   hansard config setup --watch-sources codex-cli,claude,cursor
   ```

2. Change the rolling window if the default of 30 days does not suit you.

   ```sh
   hansard config set imports.defaultSinceDays 90
   ```

3. Start the watcher and check that it is running.

   ```sh
   hansard watcher start
   hansard watcher status
   ```

The rolling window limits how far back routine passes look. It never removes
older sessions from the archive. For a complete backfill, run
`hansard import --since all`.

## Watcher commands

| Command                              | What it does                                                                                                                                |
| ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `hansard watcher status`             | Shows whether the watcher is running, its process ID, the copy and release it runs from, and a watcher move or archive refresh in progress. |
| `hansard watcher start`              | Starts the watcher in the background.                                                                                                       |
| `hansard watcher start --foreground` | Runs the watcher in the current terminal, for troubleshooting.                                                                              |
| `hansard watcher stop`               | Stops the watcher.                                                                                                                          |
| `hansard watcher restart`            | Stops the watcher if it is running, then starts it again.                                                                                   |
| `hansard watcher adopt`              | Moves the watcher, and startup at login when it is on, to the copy of Hansard that runs the command.                                        |
| `hansard watcher logs`               | Prints the watcher log.                                                                                                                     |
| `hansard watcher logs --follow`      | Keeps printing new log entries as they arrive.                                                                                              |

To start the watcher when you sign in to your computer:

```sh
hansard watcher login enable
hansard watcher login status
```

To stop starting it at sign-in, without changing the archive or the watcher's
settings:

```sh
hansard watcher login disable
```

## Restart after an upgrade

Upgrading the CLI does not require rebuilding the archive:

```sh
npm install -g hansard@latest
```

A running watcher moves to the new version on its own, once nothing it started
is still running. To move it right away, restart it:

```sh
hansard watcher restart
```

If the app or `hansard web` is open, close and reopen it so it also uses the
new version.

After the upgrade, the watcher brings older archived conversations up to the
new version's files in background batches, and `hansard status` shows its
progress as **Archive refresh**. See
[Refresh after updates](https://www.hansard.dev/reference/background-work/#refresh-after-updates).

## How the watcher finds new sessions

The watcher combines file change events with regular checks:

- It watches each source's folders and imports after 2 quiet seconds, with a
  10-second maximum wait during continuous writes. SQLite sources use a wider
  5-second quiet window and 30-second maximum.
- Codex also checks up to 256 recent or event-signaled rollout files each
  second. A full metadata sweep every minute catches missed file discoveries.
- Every 30 seconds, a watcher pass schedules work, checks sources that cannot
  report file changes, and retries interrupted imports.
- New transcript writes move ahead of the remaining scheduled checks. The
  optional Codex subagent message recovery runs at most once, after pending
  imports finish.
- Watched sources also get a full check every 15 minutes, even when no file
  change arrives.
- A source that keeps finding nothing new is checked every 5 minutes instead.
- A failed import waits before it retries, starting at 1 minute and growing to
  at most 30 minutes.
- A file whose last import took a while waits three times that import's
  duration, at most a minute, before its next import. Other changed files of
  the same source import at their usual time.

Imports run one at a time, so two sources never write to the archive at once.
Activity that arrives during an import waits and runs next, ahead of routine
checks.

> **After you change the source list:** The watcher picks up a changed source list within 30 seconds, starts
> watching the new folders, and checks the added sources for sessions it
> missed. You do not need to restart it.

## Scheduled tasks

Besides importing sessions, the watcher:

- refreshes the search and conversation list indexes after imports;
- backs up memories from your harnesses every 15 minutes;
- refreshes the cloud agents turned on in **Settings → Imports → Cloud
  agents**: **Cursor cloud agents** every minute and the others every six
  hours;
- reinstalls recall integrations that disappeared, every 15 minutes, and runs
  the shared MCP host that agent sessions' recall tools connect to;
- samples plan limits and activity from supported signed-in harness CLIs every
  15 minutes while the Mac is awake, when usage tracking is on;
- runs sync at the interval you set, when sync is set up; and
- sends the notifications you turned on.

The 15-minute tasks run beside imports, so an import that is ready never waits
for them. Import and capture workers run at background priority, below the
app, the shared MCP host, and Stats.

Starting the watcher does not turn on sync, usage tracking, or cloud imports.
Notifications are on by default for what needs you; `hansard notify status`
shows their kinds and destinations.
Usage tracking is a setup choice; change it with
`hansard config setup --track-usage` or `hansard config setup --no-track-usage`.
Starting the account router, or turning on automatic account switching, turns
usage tracking on when no **Track usage** setting has been saved, because
routing depends on current usage. A saved setting, on or off, is kept. Each
sample also records the router accounts' usage, including accounts a routing
rule holds, and applies the routing rules again.

Usage samples appear on the **Accounts** page, where each account's summary
separates plan limits from activity counts. Select an account to open the
charts on the **Usage history** tab. Codex, Claude, Antigravity, Devin, Grok
Build, and Cursor report plan limits. OpenCode reports 30-day session, message,
and token counts. Sampling never sends a prompt to a model.

Sleep pauses sampling. Sampling resumes when the Mac wakes, but samples missed
during sleep cannot be filled in later.

## Common questions

### Does Hansard keep conversations after an agent deletes them?

Yes. Each import keeps a copy of the harness's original files beside the
readable conversation, so it stays in your archive after Claude Code's 30-day
cleanup or another harness's retention removes it. The watcher has to import a
session before the harness deletes it. See
[Harness settings](https://www.hansard.dev/guides/harness-settings/) for how long each harness
keeps its history.

### How soon does a new session appear in the archive?

Usually within seconds. The watcher imports once a source has been quiet for 2
seconds, and waits at most 10 seconds while a harness keeps writing. Sources
that cannot report file changes are checked every 30 seconds. A long
conversation whose last import took a while can wait up to a minute.

### Does the watcher start when I sign in to my computer?

When you turn it on. `hansard init` offers login startup, and
`hansard watcher login enable` turns it on later. Check it with
`hansard watcher login status`.

## Troubleshoot delayed imports

Start with the watcher's state and its live log:

```sh
hansard status
hansard watcher status
hansard watcher logs --follow
```

Then compare the watcher with a direct import of the same source:

```sh
hansard import --source cursor --since 30d --dry-run --explain-skips
hansard import --source cursor --since 30d
```

If the direct import works, restart the watcher to recreate its process and
file watches:

```sh
hansard watcher restart
```

The log line `tick skipped: previous tick still running` means a watcher pass
was still running when a second 30-second check came due, and
`tick finished after N skipped intervals` follows when that pass ends and
names the pass's three slowest steps. It
usually points to a large import backlog or a slow source, not a stopped
watcher. New activity stays queued and moves ahead of routine checks when the
current import ends. Follow the log to find the source that is still running,
then run `hansard doctor` to check dependencies and source availability. Its
**watcher ticks** check names the steps that took the most time in recent
passes.

A source that reports no progress for 60 seconds is stopped and tried again
later, with a longer wait after each failure, while the other sources keep
importing. An import of one source also stops after 10 minutes, or after 30
minutes for Cursor and cloud sources. These limits, the 10-minute stall check
of sync uploads and receives, and the time limits on the watcher's indexing,
Stats, labeling, maintenance, search by meaning, and summary work count only
time the computer is awake. Work that a sleep interrupts continues after the
computer wakes instead of being stopped as stalled. While sources wait, the app's
import status names the import that holds the import lock. On macOS, history in a folder the Hansard app may not read waits until
you allow it; check **Settings → Imports → macOS access**.

## Run without the watcher

To stop all background work, turn off the sign-in item and stop the watcher:

```sh
hansard watcher login disable
hansard watcher stop
```

The archive stays usable. You can still run imports, indexing, memory backup,
and sync yourself.
