screen-locker/.gitignore
Krzysztof kuhy Rudnicki 86b63108c7 Tombstone sync records durably: a ledger the PC re-pushes every tick
manual:2026-09-13T14:30 -- the synced copy of the football that this
morning's day-key rekey let back in under a second id -- made every
workout-sync tick log "Manual-workout budget exhausted -- not ingested".
Tombstoning it once did not stick: sync_log pulls only the OTHER devices'
logs and _manual_push re-derives the PC's log from log.json each tick, so
the next push overwrote the tombstone ("tombstoned", then "LIVE" five
seconds later). Deletion is monotonic only for records still in the merge.

- New _sync_tombstones: {id: {deleted_hlc, reason, tombstoned_at}} in
  screen_locker/sync_tombstones.json (gitignored with its siblings). The
  HLC is minted once and stored so re-pushing does not churn the store.
  The ledger path is resolved at call time, not as a default argument, so
  the test suite's redirect actually applies -- verified by hashing the
  real ledger before and after the run.
- _manual_push.records_from_workout_log merges the ledger over the live
  derivation, so every push carries the tombstones.
- scripts/tombstone_sync_record.py <id> [--apply --reason ...]: dry run
  reports live/tombstoned; --apply writes the ledger, runs one tick and
  reports what the store holds afterwards. Rerunnable.
- tests/_isolated_state.py redirects SYNC_TOMBSTONES_FILE (both bindings).

Verified: --apply -> "tombstoned"; a second ordinary tick -> "already
tombstoned" with the same HLC; workout-sync.service now logs "Sync record
manual:2026-09-13T14:30 is tombstoned -- skipping it" and the budget line
for that id is gone. log.json untouched (the local entry stays; it shares
the original's credit per duplicate_credits.json).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C7vgacLhb4WJjxuVj2QLEP
2026-09-13 20:20:06 +02:00

42 lines
989 B
Plaintext

__pycache__/
*.py[cod]
.Python
build/
dist/
*.egg-info/
.env
.venv/
.pytest_cache/
.mypy_cache/
.ruff_cache/
.coverage
coverage.lcov
htmlcov/
*.log
.DS_Store
# Runtime state files — personal workout/health data, never public.
screen_locker/log.json
# ...and the ledger naming which of its entries record the same workout.
screen_locker/duplicate_credits.json
# ...and the sync tombstones the PC re-pushes every tick (names a workout id).
screen_locker/sync_tombstones.json
# ...including the timestamped backups a correction script leaves behind.
screen_locker/*.json.bak-*
screen_locker/sick_history.json
screen_locker/extra_benefits_state.json
screen_locker/scheduled_skips.json
screen_locker/shutdown_base.json
screen_locker/sick_day_state.json
screen_locker/early_bird_pending.json
# ci_mirror.sh cached requirements.txt venv (rebuilt on demand)
.ci-mirror-venv/
# Web status UI (web/) build and tooling output.
web/node_modules/
web/dist/
web/coverage/
web/node_modules
web/dist