Files
willtools-demo/docs/snapshot-tool.md
T
will 52d94303bc
ci / test (push) Has been cancelled
WillTools: precast shop-ticket QC and panel handling tools
Public demo snapshot of an in-house pyRevit extension for precast concrete
shop-ticket QC (37 checks / 46 checklist rows) and a standalone panel
handling solver (PCI Chapter 8).

- No client, job, plant or product data: knowledge layers ship as
  structural templates only.
- Ticket QC's model-read escalation targets a LAN model server endpoint
  (configurable), not a cloud provider.
- Built from the private development repo via tools/make_dist.py.
2026-09-03 16:33:47 -05:00

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:

  1. SnapshotClose pushbutton (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.
  2. 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 SnapshotClose once 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 SnapshotClose once 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.