Go to file
Krzysztof kuhy Rudnicki aa032c95e4 Drop the gatelock dependency, and actually sync the pool
Two things the pool needed to be real rather than merely correct.

**freedays no longer depends on gatelock.** It imported
gatelock.log_integrity for ~15 lines of HMAC, but importing gatelock runs
its __init__, which imports tkinter for the lock-window machinery. So a
headless policy library had acquired a hard dependency on a GUI toolkit,
and `import freedays` failed anywhere without Tk:

    ImportError: libtk8.6.so: cannot open shared object file

A vmbox run caught it. The host masked it completely -- Tk is installed
here for the lockers -- and so did CI, whose own comment claimed "no
display needed" while the job would have needed libtk. freedays/_hmac.py
now does the signing with hashlib and hmac.

The format is deliberately unchanged (HMAC-SHA256 over compact
sorted-key JSON), so nothing has to be re-signed: all 8 entries already
in the real audit trail, written by gatelock's implementation, verify
against the new one. That was checked, not assumed.

This also dissolves the version diamond that shaped the app rollout:
freedays now pins only crdt-sync, so it can never conflict with whatever
gatelock tag an app carries.

**The pool now syncs on a schedule.** A `sync-quiet` subcommand plus a
systemd user timer every 15 minutes, because "it syncs" was otherwise
only true if you typed `freedays sync` yourself -- a day marked on the
phone would sit there. sync-quiet exits 0 when there is no network or no
credential, on purpose: a unit that goes red every time the laptop is
offline is a unit you learn to ignore, and a real bug still reaches the
journal through the library's logging.

install.sh gives freedays its own venv rather than borrowing an app's --
the pool is shared by five apps, so binding its CLI to one of them would
make "is freedays installed?" depend on something unrelated, and
uninstalling that app would take the command with it.

Verified in vmbox first (systemd), then on this host: the timer is
enabled and scheduled, and the service *finishes* rather than failing
when there is no remote.

seed_session.py gains freedays, without which the one command that can
give the pool a Firebase session would reject it outright (--app is
choices-validated) and the pool would stay local-only with nothing
saying why. That file was already exactly at the 250-line cap, so the
app list and its rationale move to tool/_seeded_apps.py.

freedays: 109 tests, 100% branch coverage. crdt-sync: 433 pass.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-07 15:56:42 +02:00
.github/workflows Drop the gatelock dependency, and actually sync the pool 2026-09-07 15:56:42 +02:00
aur-publish Split the two shell scripts and the gate's own config 2026-08-22 14:59:27 +02:00
crdt_sync_dart Don't judge allowlist rot from a file-scoped run; cut two library versions 2026-08-28 14:07:09 +02:00
crdt_sync_flutter Move the two in-repo consumers onto crdt_sync_dart-v0.11.1 2026-08-28 14:08:28 +02:00
crdt-sync Drop the gatelock dependency, and actually sync the pool 2026-09-07 15:56:42 +02:00
dep_freshness dep_freshness: accept Cargo's =x.y.z as the exact pin it is 2026-09-06 18:07:10 +02:00
design_system Don't judge allowlist rot from a file-scoped run; cut two library versions 2026-08-28 14:07:09 +02:00
dopamine-ux Add the shared markdown-naming gate and migrate utils' own docs 2026-08-24 15:53:12 +02:00
file_length file_length: TRAK/sightpy is vendored, not coursework 2026-08-28 19:33:14 +02:00
firebase firebase: make the rules template impossible to deploy verbatim 2026-08-22 19:10:10 +02:00
freedays Drop the gatelock dependency, and actually sync the pool 2026-09-07 15:56:42 +02:00
gatelock Keep wait_for_turn under the lint limits, and cover its new paths 2026-08-30 15:06:47 +02:00
github_device_auth github_device_auth: exact pins (http 1.6.0, url_launcher 6.3.2) 2026-08-28 13:34:45 +02:00
guard-lib Split the two shell scripts and the gate's own config 2026-08-22 14:59:27 +02:00
md_naming Add the shared markdown-naming gate and migrate utils' own docs 2026-08-24 15:53:12 +02:00
prompts Add the shared markdown-naming gate and migrate utils' own docs 2026-08-24 15:53:12 +02:00
scripts feat: share the no-binaries gate, promoted out of testsAndMisc 2026-08-30 19:32:25 +02:00
sync_settings_ui Move the two in-repo consumers onto crdt_sync_dart-v0.11.1 2026-08-28 14:08:28 +02:00
ts_core ts_core + web_ui: latest stable, pnpm 11, and a quarantine-aware gate 2026-08-28 13:50:25 +02:00
unified-design-system Fix two long-red CI gates: palette_check path after md rename, file-length in sync_settings_ui 2026-08-28 12:36:41 +02:00
vmbox Add the shared markdown-naming gate and migrate utils' own docs 2026-08-24 15:53:12 +02:00
web_ui One Python per repo, always the newest, and the gate that enforces it 2026-08-28 20:58:19 +02:00
.gitignore Ignore Firebase CLI debug logs 2026-08-22 16:17:39 +02:00
.pre-commit-config.yaml Check the toolchain versions CI actually installs, not just the ones declared 2026-08-28 15:04:00 +02:00
dependency-freshness.allowlist.yaml chore: the typescript hold names typescript-eslint 8.69.0, the release it waits on now 2026-09-04 09:48:28 +02:00
LICENSE Root scaffold: README, LICENSE, per-subdirectory CI for utils monorepo 2026-07-10 13:02:20 +02:00
README.md Add the shared markdown-naming gate and migrate utils' own docs 2026-08-24 15:53:12 +02:00

utils

Shared libraries used across kuhyx's other projects. Each subdirectory is a formerly-standalone repo, folded in here with full commit history preserved (see each subdirectory's own git log for its pre-merge history).

crdt_sync_dart/

Dart/Flutter CRDT sync library (pub package name: crdt_sync, not published to pub.dev — consumed via a git dependency). Mirrors crdt-sync (below) module-for-module and test-for-test. Consumed by diet_guard's app, screen-locker's workout_app, wake_alarm's phone_app, and todo (whose notes are stored in the v0.2.0 LogStore).

Consume via:

dependencies:
  crdt_sync:
    git:
      url: https://github.com/kuhyx/utils
      ref: crdt_sync_dart-v0.10.0
      path: crdt_sync_dart

sync_settings_ui/

Shared Flutter "Sync settings" screen (pub package name: sync_settings_ui, not published to pub.dev). Firebase sync (primary) plus an optional local backup slot — no GitHub mirror UI. Pure UI + a FirebaseSyncController service layer over injected closures (keystore/Google-plugin access stays in each consuming app, exactly as before this package existed). Consumed by todo, diet_guard_app, workout_app, wake_alarm/phone_app, and home_inventory's dedicated "Sync settings" route.

Consume via:

dependencies:
  sync_settings_ui:
    git:
      url: https://github.com/kuhyx/utils
      ref: sync_settings_ui-v0.1.0
      path: sync_settings_ui

crdt-sync/

Python CRDT sync library (package: crdt_sync, not published to PyPI). Same design as crdt_sync_dart (HLC clocks, per-field LWW, sticky-delete tombstones). Consumed by diet-guard and screen-locker.

Consume via:

crdt-sync @ git+https://github.com/kuhyx/utils@crdt-sync-v0.2.0#subdirectory=crdt-sync

guard-lib/

Bash tamper-resistance primitives (guardctl: chattr + bind-mount + systemd watcher + pacman hooks). Not a package — installed by running guard-lib/install.sh as root, which copies files onto the system (/usr/local/bin, /usr/local/lib/guard-lib, systemd units, pacman hooks). Consumed by steam-backlog-enforcer (expects a guard-lib/install.sh sibling clone) and referenced by screen-locker.

gatelock/

Python lock-window + HMAC log-integrity backend (package: gatelock, not published to PyPI). Consumed via pip by screen-locker, diet-guard, and wake-alarm:

gatelock @ git+https://github.com/kuhyx/utils@gatelock-v0.1.0#subdirectory=gatelock

unified-design-system/

Not a package — the frozen design tokens (colors, spacing, type, radius, shadow policy) and per-stack (Flutter/web/Tkinter) implementation patterns that keep every one of kuhy's repos visually identical, plus annotated component references (components.html, button.html). Read unified-design-system/README.md and DOCS-tokens.md before touching any theme/CSS/style file in any repo. The unified-design-system Claude Code skill is a thin pointer here, not a duplicate.