utils/holds
2026-11-07 08:26:25 +01:00
..
holds holds 0.1.0: declared time-boxed holds 2026-11-03 20:25:10 +01:00
.pre-commit-config.yaml holds 0.1.0: declared time-boxed holds 2026-11-03 20:25:10 +01:00
install.sh holds 0.1.0: declared time-boxed holds 2026-11-03 20:25:10 +01:00
pyproject.toml holds 0.1.0: declared time-boxed holds 2026-11-03 20:25:10 +01:00
README.md holds 0.1.0: declared time-boxed holds 2026-11-03 20:25:10 +01:00
requirements.txt Add a plain-text multi-voice score format 2026-11-07 08:26:25 +01:00

holds

Declared time-boxed holds (contract v1): while a hold is active every gate (focus-guard, diet-guard, screen-locker prompts) stands down so the PC stays usable, e.g. for a proctored test. Stdlib only; gates import it from the system python.

import holds

holds.active(now=None)        # Hold | None  (corrupt file -> None, logged: fail closed)
holds.covers("diet-guard")    # bool; v1: every gate
holds.next_change(now=None)   # datetime | None: active hold's end, else next start
holds.add(start, end, "reason of 10+ chars")   # raises HoldsError on a ratchet breach
holds.remove(hold_id)         # only before it starts

Ratchet (R11): each hold <= 15 h, <= 3 per ISO week (by start), start >= now + 30 min, reason >= 10 chars, no overlaps, whole-minute times, existing holds are never edited. Data: $HOLDS_DATA or ~/.local/share/holds/holds.json, local naive times. Install: ./install.sh (editable, /usr/bin/python3). Tests: python3 -m pytest.