History-free snapshot of the private development repository at cbe45c5 (2026-09-09). Code, docs and public catalogue only; no plant or job knowledge layers, no client or job names (tools/scrub.py clean). The intro deck is left out of this snapshot because its slide images could not be checked for job drawings.
4.8 KiB
Snapshot tool — how it works, and how to run it
The snapshot tool makes a timestamped, detached copy of the model, opens a Revit onto that copy on its own (nobody in front of it), runs a batch inside it, and closes — so the engineer's own model and session are never tied up.
It is two halves:
SnapshotClosepushbutton (Tools panel, runs inside the live Revit). Its one irreplaceable job is Phase A: hand over the model's IDENTITY. Only the open document can cheaply report a cloud model's region + GUIDs, and without those nothing else can find the model again. Phase A also indexes the model as it stands (this is where the reinforce feature registry is refreshed) and journals what it did. It then writes a request file (the cached identity) and spawns the detached host cycle — it does not make the copy itself.tools/snapshot_cycle.py(plain host CPython, detached — Claude can start it, no Revit needs to be open in front of anyone). Five steps:DETACH → close-sandbox → open-sandbox → run batch → CLOSE, each journalled.
Why a copy is made by SaveAs, not "Detach from Central"
A cloud model cannot be opened detached: any DetachFromCentralOption on a
cloud ModelPath raises "Detach option is not valid for cloud model," Autodesk
says SaveAs is the way, and the UI greys the checkbox out. So the cycle's
"detach" is a SaveAs to a timestamped copy under snapshot.detached_dir.
The one rule that makes it usable: identity is captured once, from a live press
A cloud model is only identifiable from a session that has it open — the region and GUIDs live in the open document. So:
- You must press
SnapshotCloseonce from a live session that has the model open. That press captures the cloud GUIDs and caches them (the request file). - After that, the cycle can run with NO live session — it reopens the model from the cached GUIDs. This is the path to auto-running snapshots with nobody in front of Revit: identity cached once → every later cycle is headless.
If the identity was never cached (e.g. the press was interrupted), the cycle
cannot start and says so — a cloud model with only a display path and no
GUIDs can't be located. Fix: open the model and press SnapshotClose once more.
Running the cycle by hand (after the identity is cached)
python tools/snapshot_cycle.py \
--fresh-detach \ # write a new timestamped copy first
--job "<job folder under WILLTOOLS_JOBS>" \
--request <the request file the button cached> \ # OR --source <path>, OR
# snapshot.source_cloud in job knowledge
--revit 2024 \ # PIN the year — the machine has several Revits;
# omitting this is what silently no-fired before
--revit-exe "C:/Program Files/Autodesk/Revit 2024/Revit.exe" \
--pyrevit "C:/Users/<you>/AppData/Roaming/pyRevit-Master/bin/pyrevit.exe" \
--dry-run # print the whole plan and do NOTHING — always dry-run first
Drop --dry-run to actually run. Useful flags: --run "<host cmd>" (the batch,
default snapshot.batch), --keep-open, --wait-minutes, --use <file> (skip
the detach and cycle onto an existing copy).
Job-knowledge keys the cycle reads (WILLTOOLS_JOBS/<job>/knowledge.yaml)
snapshot:
detached_dir: <where timestamped copies are written> # REQUIRED, or --detached-dir
source_cloud: {region: ..., project_guid: ..., model_guid: ...} # optional: lets the
# cycle run with no live press ever, once you have the GUIDs
Journal — every run is recorded, silence is never success
<job>/snapshots.jsonl gets a line on every exit path (this was a real
bug once: a day the cycle never fired looked exactly like a day it worked, so a
missing run is now reported in capitals at the top of the report). Phase A also
journals phase-a-snapshot (piece count, timing, provenance) and
phase-a-update-stats (the reinforce feature-ID diff).
Known failure modes
snapshot.detached_dir is not set→ set it in job knowledge, or--detached-dir.- "a fresh detach needs to know WHICH model to copy" → identity not cached;
press
SnapshotCloseonce from the live model (see the identity rule above). - Silent no-fire in ~16 s → historically a missing
--revit=<year>with several Revit versions installed; always pin--revit. The cycle now resolves the year from the exe and journals on every exit, so this is loud now.
Toward fully automatic
Once snapshot.source_cloud (the GUIDs) is stored in the job knowledge — captured
once from a live press — the cycle needs no Revit open in front of anyone and no
request file, so it can be scheduled/auto-run headlessly. That is the intended
end state.