ADR-0016: The branch level is never dropped¶
Status: accepted (2026-08-16)
Decision¶
Run output is always
{logs}/{node}-{HHMM}/{branch}/{lane}-{backend}/-- the branch level is never omitted. When--branchis not passed it defaults to the node repo's checked-out git branch (detached HEAD -> short SHA; not a git repo ->local), flattened to one path segment. Consumers (publish, the dashboard, externalshow/cdstooling) may assume the three-level shape unconditionally.
Context¶
The output tree is namespaced this way because a run is a matrix: one pack,
tested across {branch} x {lane}-{backend} cells that the publish step
aggregates into one gh-pages dashboard
(ADR-0015). publish.py walks
(branch, lane, results_dir) tuples and the dashboard has a per-branch
index -- the branch level is part of the contract.
The defect this fixes: run.py wrote run/branch/lane only when
--branch was passed, and run/lane otherwise -- and git branch was never
auto-detected. So a run without --branch produced CADabra-1424/windows-cpu/,
which publish, the dashboard, and the external cds show tool all reject
with "No branch folders found -- expected
{run}/{branch}/{lane}/results.json". A shape with a level that can
silently vanish is not a shape. The branch the run tested is already
knowable -- one git rev-parse --abbrev-ref HEAD on the node dir -- so the
level can always be filled without a required flag.
Alternatives rejected¶
- Keep the branch level optional (status quo). Every downstream consumer
already assumes it is present; the common local invocation
(
comfy-test runwith no--branch) then produces output no tool can read. A bug, not a design. - Require
--branchon every run. Pushes a mandatory flag onto every local invocation for a value the machine can compute from the checkout. A default that is knowable should not be required human input.
Consequences¶
run.pydetects the branch and always emits the level;--branchbecomes an override of the detected default, not the toggle for the level's existence. For a local-dir run--branchis only a label -- it does not check out or fetch that branch, so the honest default is the branch actually checked out.publish, the dashboard, andcds showcan assume{run}/{branch}/{lane}unconditionally.- The run-id stamp is
{node}-{YYYYMMDD-HHMM}-- a date plus hour:minute, no seconds (by request: readable, not a wall of digits). The date kills the cross-day collision (a plainHHMMreused a previous day's folder, leaving a stale mtime thatcds, sorting by recency, silently skipped). Same-minute collisions remain possible but are accepted as rare -- adding seconds was explicitly declined.