# Incremental performance

Run `bun run bench`. The corpus contains 120 files / 1,440 callables. It measures cold discovery, a no-change poll, one changed working-tree file, and staging those same bytes. It also starts a separate engine to check persistent-fact reuse.

A local development run measured:

| Path | Elapsed | Reparsed files | Source rereads | Graph models rebuilt |
|---|---:|---:|---:|---:|
| Cold | 276ms | 120 | 120 worktree + 120 Git blobs | 1 |
| No change | 49ms | 0 | 0 | 0 |
| One-file change | 113ms | 1 | 1 | 1 |
| Stage the same bytes | 79ms | 0 | 1 new Git blob | 0 |

An independent engine reused persisted facts with zero parses. Event-loop delay p99 was 13.6ms in this run. These timings exclude loading the TypeScript module and are observations, not CI thresholds or universal guarantees. The benchmark uses Git subprocesses and results depend on OS, storage, and competing work.

The executable acceptance criteria are work counts, not brittle timing assertions: a no-change pass must perform zero parses, source/blob rereads, model rebuilds, and review/heat recomputations. A one-file edit must parse/read only that file. Staging already analyzed bytes must reuse the model. Content and configuration changes must never reuse stale reports.

## Startup is a separate budget

The v0.2.0 interface's complete static bundle graph measured **18,932 bytes**, including Fovea's lightweight workspace API but excluding Pi's supplied TypeBox and loader. Build metadata allowlists only the workspace entry, root coordination, and scheduling primitives; static parsers, graph modules, and the analysis engine remain forbidden. The 32KiB ceiling is unchanged.

An isolated package probe with Pi 0.85.1 and Node 26.5.0 measured `session_start` at **0.153–0.186ms**. The full `DefaultResourceLoader.reload()` path, including package/resource discovery and Jiti loading, took **79–125ms**. These are local observations, not a latency guarantee or a measurement of Contour alone versus a baseline Pi startup.

No scan occurs in either the factory or `session_start`. Analysis loads at the first deferred scan or explicit review; first-use loading remains synchronous in-process. `CONTOUR_BACKGROUND=0` disables background analysis, not successful-access selection. An empty coordinator never scans cwd. The observer alternates recent activity with a round-robin backstop, one root per pass; a busy root cannot permanently starve quieter projects. A 5s tick is not a 5s per-root guarantee across 32 projects. Explicit checkpoints abort speculative work. `bun run verify:package` reports fresh measurements and proves that a standalone production install does not pull in a compiler, Fovea, tsx, or another Pi host.

## Patterns transferred from Fovea

- Content-addressed facts with explicit parser/semantic versions.
- Stat manifests as a read-avoidance proof, not an mtime-only guess.
- Bounded batch I/O and shared in-flight directory metadata requests.
- Immutable generation ownership and separate source-model/report identities.
- Byte/entry LRUs; two retained graph generations, separate bounded report retention across roots.
- Default 32-root recency ring; lightweight selection/leases stay independent of heavy models.
- Coalesced bounded ancestor discovery; no sibling scans, startup Git, or project-config trust inheritance.
- Local Git analysis disables fsmonitor and remote/lazy fetching.
- Cooperative event-loop yields during file and finding sweeps.
- Shared Chebyshev recurrence vectors across diffusion scales.
- Quiet, debounced background work with cancellation and a periodic correctness backstop.

Limits are intentionally visible. An oversized or unmodeled region becomes a coverage gap, never an apparently small or clean repository. The parser is synchronous within one bounded file; very large/deep source can still consume a noticeable timeslice. Heavy batch deployments should benchmark representative repositories before increasing limits.
