# Startup performance

## Workload and method

Measured on macOS, Node v26.10.0, with 500 synthetic session JSONL files and a prepopulated JSON inventory marking them completed, uncompressed, and not beneficial to compress. Weekly maintenance is not due. One warmup is discarded, followed by five measured runs of state loading and startup work. Fixture creation, lifecycle locking, and active-session path resolution are outside this measurement.

Stub mode returns synthetic info if a tool call occurs; `--real-tool` is capable of running real Applesauce. The current completed-record workload makes zero calls in either mode, so this is not a measurement of Applesauce speed or Pi's entire startup time. Both baseline and result use warm filesystem caches and the same sample count and instrumentation.

The benchmark tracks JSON serialization, persistence I/O, tool calls, directory enumeration, and session-path filesystem operations (`realpath`, `stat`, `open`). Instrumentation is installed after fixture creation. Assertions are outside the timed region.

## Attempt ledger

Changes were measured separately; each subsequent baseline includes the previous change.

| Change | Mode | Baseline median (range) | Result median (range) | Verdict |
| --- | --- | --- | --- | --- |
| 1. Batch detection-only state saves | Stub info | 251.5 ms (245.0–265.2) | 45.9 ms (44.0–47.6) | Kept: 81.7% lower; disjoint ranges |
| 1. Same change | Real Applesauce info | 1254.1 ms (1224.4–1534.3) | 1009.2 ms (1002.4–1013.8) | Kept: 19.5% lower; disjoint ranges |
| 2. Trust unchanged settled JSON records | Stub info | 46.5 ms (43.9–47.4) | 42.0 ms (40.5–45.8) | Overlapping delta; not the justification for keeping change 2 |
| 2. Same change | Real-tool capable | 1095.2 ms (1082.3–1102.4) | 38.5 ms (38.3–44.8) | Kept: 96.5% lower; zero info calls |
| 3. Separate inventory recovery from weekly discovery | Real-tool capable | 41.8 ms (41.7–42.4) | 1.56 ms (1.33–1.70) | Kept: 96.3% lower; zero historical-file I/O |

Follow-up checks measured 40.3 ms (38.6–46.5) after change 2 and 1.44 ms (1.41–1.65) after change 3. The latter passed the new 10 ms local reference budget. Subprocess and filesystem costs vary across runs; these are workload-specific observations, not portable guarantees.

For the completed-record workload:

| Resource | Original | After change 2 | Current |
| --- | --- | --- | --- |
| Per-file Applesauce calls | 500 | 0 | 0 |
| Session-path filesystem calls | Not instrumented | 2000 | 0 |
| Directory enumerations | 1 | 1 | 0 |
| Full inventory writes | 501 | 1 | 1 |

The original repeated inventory writes totaled approximately 133 MB; the single current write is approximately 0.266 MB (decimal units). Change 3 also reduced production source from 1026 to 920 lines, primarily by consolidating lifecycle handling and removing per-file startup cache validation and repeated state-update branches.

### Current elapsed-time breakdown

From the first change-3 median sample (1.556 ms):

| Stage | Time | Share |
| --- | --- | --- |
| Per-file Applesauce calls | 0 ms | 0% |
| State JSON serialization | 0.244 ms | 15.7% |
| State persistence I/O | 0.372 ms | 23.9% |
| Remaining state loading / inventory work | 0.941 ms | 60.4% |

Remaining work is a residual, not a separately attributed profile. It includes JSON loading/parsing/normalization, root-path resolution, inventory classification, and orchestration; it no longer includes historical-file inspection or directory discovery in an ordinary startup.

## Current task division

- **Ordinary startup:** load the JSON inventory and retry unfinished, failed, unverified, or incompatible records. Completed records are not opened, statted, or resolved on disk. No directory discovery occurs.
- **Session activation:** register the current session as unknown/unverified using Pi's session identity, without reading its content or fingerprint. Resolve only the active path for alias safety. Save the marker even if the session file has not yet been written, so an interrupted run can be recovered.
- **Shutdown / switching out:** read and process only the outgoing session, then save its settled status and fingerprint. Tool version checking occurs here, not on an idle startup.
- **Weekly maintenance:** at startup when seven days have elapsed (or the maintenance timestamp is missing/invalid), enumerate filenames, queue untracked files, and prune missing records in successfully enumerated roots. Completed files are not opened or rechecked. Failed roots retain their records and prevent advancing the maintenance timestamp.

Completed means verified target ZLIB compression satisfying the known storage-ratio requirement, or an uncompressed not-beneficial result, without a recorded error. Active sessions are excluded from recovery and discovery processing. Missing unfinished files are removed from the inventory when retried; completed missing files are removed during maintenance. Missing/corrupt inventory triggers initial discovery.

This is an explicit trust contract: external edits to completed historical files are not detected automatically, even if their fingerprint changes. New external files are discovered during weekly maintenance. The inventory is not a live filesystem monitor.

## Durability and correctness

Only task selection changed. Pending checkpoints before file mutation, settled processing results, and errors remain saved immediately. Required compression verification, pre-mutation fingerprint checks, timestamp restoration, and physical-benefit checks remain in place. Recovery compares old fingerprints before updating records. An unknown resumed record that still appears compressed is fully recompressed before it is marked settled.

Tests protect zero historical-file I/O and zero directory enumeration on ordinary startup, weekly-only discovery/pruning, failed-root preservation, incomplete-record retries, active markers and interrupted-run recovery, active-path alias safety, malformed-inventory rebuild, changed outgoing files, pending/completed checkpoints, and save-error propagation.

A native integration smoke test used real Applesauce on an isolated synthetic JSONL, reloaded its settled inventory, and performed an ordinary startup without tool calls. SHA-256 of logical content remained unchanged. Tests and benchmarks use isolated home-filesystem directories and move fixtures to `~/.Trash`; real Pi sessions and state are not used.

## Reproduce and guard

```bash
pnpm test
pnpm bench:startup
pnpm bench:startup --real-tool
BENCH_SESSIONS=500 BENCH_RUNS=5 BENCH_MAX_MS=10 pnpm bench:startup --real-tool
```

The benchmark enforces **zero tool calls, zero session-path filesystem operations, zero directory enumeration, and one inventory write** on the ordinary completed-record workload. Timing assertions are separate from normal tests. `BENCH_MAX_MS` optionally enforces the median timing budget with a nonzero exit status on regression. The 10 ms budget is local to this machine/workload; establish a fresh baseline before choosing a stable CI runner's budget.
