VAR remembers what it has done. Each invocation resumes from the last completed stage unless the working tree has changed.
When vary var runs, it writes a session file (.vary-var-session.json) in the project root. The session tracks:
| Field | Purpose |
|---|---|
| Session ID | Unique identifier for this validation cycle |
| Current stage | Where the pipeline is (e.g., check, test, complete) |
| Stage results | Pass/fail for each completed stage with summaries |
| Blockers | Active blocking issues that need fixing |
| Change fingerprint | Hash of the current change set |
| History | Timestamped entries for no-progress detection |
On the next invocation, VAR loads the session and checks whether the working tree still matches. If it does, the pipeline resumes from the first incomplete stage. If not, it resets to discovery.
The fingerprint is a SHA-256 hash of the sorted list of changed file paths and their modification times. Two runs with the same changed files and mtimes produce the same fingerprint.
When you edit a file and re-run vary var, the fingerprint changes. VAR detects this drift and resets the session, because the prior stage results may no longer hold.
When you fix a blocker and re-run without touching other files, the fingerprint also changes (the fixed file has a new mtime). VAR resets and re-runs discovery, but this time check should pass.
A typical session lifecycle:
| Step | What happens |
|---|---|
| First run | No session exists. VAR creates one, runs discovery, then proceeds through stages until something blocks or everything completes. |
| Re-run (same files) | Session loads, fingerprint matches. Resumes from the first incomplete stage. |
| Re-run (files changed) | Session loads, fingerprint differs. Resets to discovery and starts fresh. |
| Reset | vary var --reset deletes the session and starts from scratch. |
VAR tracks consecutive runs in the session history. If the same blockers appear across multiple runs with no improvement, it flags a no-progress warning:
Warning: no progress detected across 3 consecutive runs.
Stuck at: check (2 errors)
Consider: reviewing the blockers below or running with --reset
This catches silent thrashing where you run vary var repeatedly without addressing the actual problem.
--no-state disables session persistence. VAR neither reads nor writes the session file. Every invocation starts from discovery.
| Use case | Why stateless |
|---|---|
| CI pipelines | Each run should be independent |
| One-off checks | Avoid affecting saved state |
| Debugging | Suspect session corruption |
The session file is JSON. Its structure is internal and may change between compiler versions. Use vary var --json for machine-readable output instead of parsing this file.
Key fields for reference:
{
"sessionId": "...",
"currentStage": "test",
"stageResults": {
"discovery": { "success": true, "summary": "9 files" },
"check": { "success": true, "summary": "0 errors" }
},
"blockers": [],
"changeSet": [
{ "path": "src/app.vary", "fingerprint": "a1b2c3..." }
],
"lastUpdated": "2026-04-09T10:30:00Z"
}