Commit Graph

179 Commits

Author SHA1 Message Date
89e6eed105 Bump sync_settings_ui to 0.6.1
Some checks are pending
dependency freshness / dependencies on newest stable (push) Waiting to run
md-naming / markdown naming convention (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (mypy, mypy, ) (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (pylint, pylint, ) (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (rest, , mypy,pylint,free-days-interop) (push) Waiting to run
Tests / test (push) Waiting to run
Tests / free-days-interop (push) Waiting to run
release-apk / release (APK) (push) Waiting to run
repo-contract / repo contract (push) Waiting to run
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-11-08 18:28:23 +01:00
06b70ab312 Bump crdt_sync to v0.12.0
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-11-08 14:24:46 +01:00
10938ed012 Align pre-commit sickdays pin to 0.4.0
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WzxdWZd3smuxDGmEgXkYP8
2026-11-07 08:38:22 +01:00
f182453567 Add morning-session corner strip
Top-right always-on-top strip while the signed morning session is
in_progress: title, "Next: <step>", "Locks return at HH:MM".
wake-alarm-strip.path starts it on every file rewrite; it re-reads
the file each second, asks for a refresh every 30 s, exits 0 when
the session ends. No display/output: warning, exit 1.
Bump gatelock pin to 0.12.0 (corner_strip).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WzxdWZd3smuxDGmEgXkYP8
2026-11-07 08:19:42 +01:00
537a3a79e4 Retry session refresh; sign next_step
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WzxdWZd3smuxDGmEgXkYP8
2026-11-07 08:12:01 +01:00
672eaf8aba Add todo app git hooks
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-11-02 13:56:22 +01:00
13f6e3f5d2 Use google_account_token for sign-in
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WzxdWY1k4muZfdVJfb7YGJ
2026-11-02 11:27:35 +01:00
5525ca6f95 Move TODOs to todo app
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-11-02 11:14:40 +01:00
58c4260b6e Pin focus-project 0.3.0, sickdays 0.4.0
Conflicting git-tag pins in the shared user site let the last install downgrade focus_project/sickdays (no harvest, no focus locker).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 10:02:56 +01:00
6033e3815f Home: fit one screen, details behind tiles
Stakes and history move behind two tiles that open bottom sheets;
the page no longer scrolls at Pixel 6a geometry (home_fit_test).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WzxdWWcbzoov1KFZJSFcSs
2026-11-01 22:06:43 +01:00
18a304de55 Trim hardening TODO to real residue
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-11-01 22:02:50 +01:00
a51a67e2fe Remove done file-length TODO
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-11-01 22:02:11 +01:00
fd65c454e3 chore: bump deps to newest stable
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WzxdWXTUM9dpnCS2wtFkx4
2026-11-01 20:13:43 +01:00
05738db15a feat: JSON export/import on device
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WzxdWXTUM9dpnCS2wtFkx4
2026-11-01 19:55:04 +01:00
69be24d4c0 Session: tag catch-up + pre-deadline buzz
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-11-01 18:25:15 +01:00
1c2197a3cd deps: flutter 3.47.7 (workflows), gradle 9.8.2, coverage 7.17.0, ruff 0.17.2 (newest stable)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017k9j5dbjenpfZj7dh2faPN
2026-10-23 18:09:14 +02:00
2defe09e6a Launcher: label WakeAlarm, icon fitted to the shared 340px ink circle
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012kQ5PCKqBHAkAVkPSvp6dk
2026-10-23 14:36:09 +02:00
4b72899e5b Pin gatelock-v0.11.0 (Claim.grab_held + held_grabs)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dsh4Znwh2KnC7q6vbGpX1N
2026-10-19 11:47:24 +02:00
14b6dac605 deps: gatelock 0.9.0 -> 0.10.0 (pin only)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-17 18:49:51 +02:00
0060b48b10 deps: sickdays 0.3.0
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PAhbNszs5JKdtnD4uBi3xp
2026-10-17 13:53:14 +02:00
597901dc08 phone: sick-day interop both ways with keep; docs
check.sh now runs Dart->Python (keep, unsorted/duplicate input, a cleared
keep day, a keep-only edit that must not re-stamp state) and
Python->Dart (0.2.0 keep sets plus a 0.1.0 record with no keep, a stale
keep and a malformed one), Python 0.2.0 as the oracle with explicit
paths and HOME pointed at a scratch dir. DOCS-sick-days.md and the
SickDays.kt contract describe the alarm-only native cache.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PAhbNszs5JKdtnD4uBi3xp
2026-10-16 15:31:11 +02:00
ee7e380278 phone: per-locker sheet on the sick-day calendar
Tapping today or a later normal day opens a sheet with one switch per
locker (Workout lock, LeetCode, Book, Diet, Wake alarm), all off, and
"Mark sick"; a sick day reopens with its switches, "Save" (keep-only
edit, nothing written when unchanged) and "Clear sick day". Past days
stay inert. A sick day keeping any locker carries a dot in the calendar
and a "Kept: ..." line in the list. DayCell moves to day_cell.dart for
the 250-line cap.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PAhbNszs5JKdtnD4uBi3xp
2026-10-16 15:30:11 +02:00
7fe6108df3 phone: sick-day keep set (sickdays 0.2.0) in the Dart pool; alarm cache filtered
SickDayPool gains keep: mark/clear write state+actor+keep on one tick,
setKept re-stamps only keep+actor, read rules 1-5 in sick_day_keep.dart.
The native SickDays cache now holds only days on which the alarm stands
down, so a sick day that keeps the alarm rings like a normal day.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PAhbNszs5JKdtnD4uBi3xp
2026-10-16 15:30:11 +02:00
5d0f06b19e PC: sick days stand the alarm down only when it is not kept
All PC enforcement (fallback ring, RTC self-wake, trigger, workday penalty
write/retract, audit) now asks sickdays.stands_down(LOCKER_ALARM, day) via
_sick.alarm_stands_down instead of is_sick_day, so a sick day that keeps the
alarm behaves exactly as a normal stick day. Bump sickdays pin to v0.2.0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PAhbNszs5JKdtnD4uBi3xp
2026-10-16 15:13:23 +02:00
2e594f041d phone: pin the clock in the stageLocalSettings enforcement test
The test staged a 2026-10-01 event through stageLocalSettings, which called
stageEnforcementData on the real clock; on 2026-10-16 the event aged past
boundEvents' 14-day window and the test went red for everyone.
stageLocalSettings now forwards an optional `now` to stageEnforcementData
(callers unchanged), and the test passes its fixed clock. phone_app suite:
402 passed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Xfj1sxKH9VBPqpcAni8Jry
2026-10-16 14:55:26 +02:00
7e40bb138c ci_mirror: build the clean venv with uv (18.3 s -> 2.1 s cold)
The venv rebuild after a requirements.txt change was the largest cold-path
cost of `scripts/check_gate_stamp.sh full`. uv is also what CI installs
with, so the mirror gets closer to CI, not further. The interpreter is
passed as a path: `--python python3` let uv pick an active ~/.venv (3.13)
that crdt-sync 0.9.2 (>=3.14) cannot install into. pip stays as fallback.

Measured under capped.sh (4G, 20 %): `full` warm 10.9 s; fully cold
(no venv, empty PRE_COMMIT_HOME, empty mypy cache) 45.9 s, floor = the
pylint hook env install (~24 s, only after .pre-commit-config.yaml changes).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Xfj1sxKH9VBPqpcAni8Jry
2026-10-16 14:55:18 +02:00
4f149e67a4 phone: read the native sick-day cache back on the Sick days screen
A release build gives no way to see the SharedPreferences cache that
AlarmReceiver reads at ring time (no run-as, no log of its contents), so
"the Dart UI shows it" could not prove "the alarm will stay silent".

- SickDays.store/dates log the sorted set under WakeAlarmSickDays.
- AlarmChannel getSickDays returns the cached set (null if unreadable).
- The Sick days screen reads it on open (before the sync rewrites it) and
  after every sync: "Alarm cache: <dates>" / "none" / "unreadable".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Xfj1sxKH9VBPqpcAni8Jry
2026-10-16 14:38:25 +02:00
29e64fb7fa Merge branch 'sickdays-phone' into sickdays-pc
# Conflicts:
#	AGENTS.md
2026-10-16 13:26:09 +02:00
e0ef3e1217 docs: sick_day in the phone event contract; portable gradle test note
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Xfj1sxKH9VBPqpcAni8Jry
2026-10-16 13:25:31 +02:00
34037e55c1 phone: sick days — picker, silent ring, stick stand-down, pre-alarm sync
- Sick days screen (own name, sick icon, cat-2 fill): tap today or a later
  day to mark it sick, tap again to clear; past days inert. Writes the
  sickdays wire format (state sick/cleared + actor, one HLC per write) to
  sickdays-sync/devices via crdt_sync syncLog.
- Mutual exclusion in both pickers: each syncs the other pool on open and
  refuses a date it holds, naming the pool; an unreadable pool refuses all.
- Native SickDays cache (fail closed via DayCache); AlarmReceiver skips the
  ring with reason "sick_day" (no markFired, no ring_started); StickCheck
  verdict sick_day, streak skips sick days; stakes card says so.
- Pre-alarm pool sync: allow-while-idle alarm at 21:00 and A-30 (request
  code 1006) runs a headless engine (poolSyncMain) that pulls both pools
  from RTDB and rewrites both native caches, so a PC mark arrives with the
  app closed. The ring decision stays a cache read.
- JVM unit tests (JUnit 4.13.2) for DayCache, RingDecision,
  PoolSyncSchedule, StickCheck; Dart tests; Dart->Python interop check.

pylint hook skipped: verify.py imports sickdays, not in the hook env until
the sickdays-v0.1.0 tag exists; run by hand in a sickdays venv (10.00/10).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Xfj1sxKH9VBPqpcAni8Jry
2026-10-16 13:22:40 +02:00
8696f2d0bf wake_alarm: sick days stand the PC down (fallback ring, RTC wake, trigger, workday penalty)
A date in the new shared sickdays pool (not a free day) now means, on the PC:
no fallback ring (a ring in progress stops, reason sick_day), no RTC
self-wake for that morning (ours is disarmed), no morning-routine trigger,
and no workday_penalty.json; a penalty issued on a day later marked sick is
retracted (penalty_cancelled, cause sick_day) by the next session refresh or
RTC tick. The audit treats the day as one where nothing is expected.

All pool access goes through wake_alarm/_sick.py: fail closed (unreadable
pool or missing package = not sick), and act modes pull the pool from
Firebase first (RTC --arm on a stick-day target, in-window fallback ticks
and ring polls, the day's first penalty write) because the sickdays timer
pauses through hibernate. Dry runs never pull.

Pins: sickdays-v0.1.0, freedays-v0.4.0, crdt-sync-v0.9.2 (needed by both);
pre-commit 4.7.0, pylint 4.1.3, ruff 0.17.1 (freshness gate).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Xfj1sxKH9VBPqpcAni8Jry
2026-10-16 08:45:29 +02:00
3b8cd21969 chore: add MIT LICENSE
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-11 18:14:11 +02:00
ffe7666f49 deps: Flutter 3.47.7, shared_preferences 2.5.6
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018RHwVPyiiQMPh4M3JQwQku
2026-10-09 19:27:56 +02:00
a0731c496c Sync: stop reading screen-locker's sync_token (screen-locker is Firebase-only now)
screen-locker's PC sync went Firebase-only on 2026-10-09 and nothing
maintains ~/.config/screen_locker/sync_token any more. The GitHub-fallback
token list now holds only diet_guard's repo-scoped PAT. Drop the stale
note about shutdown-wrapper.sh mirroring the list (the wrapper was removed
on 2026-08-30).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018RHwVPyiiQMPh4M3JQwQku
2026-10-09 19:11:50 +02:00
57a6c6ba0e dependency freshness: bump pylint 4.1.2, url_launcher 6.3.3, github_device_auth v0.3.2 (CI red fix)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-04 17:39:28 +02:00
8e254dbef6 repo contract: CLAUDE.md commands, test_changed, CI gate, AGENTS.md update
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-04 16:58:12 +02:00
a6d5688eb7 CI: slim Flutter SDK for the interop job; APK only on app changes, Gradle cached
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-02 15:08:47 +02:00
83b9d5c4c7 CI: Flutter 3.47.6 in the workflow pins too
The .fvmrc moved in the previous commit; CI's freshness gate also reads the
flutter-version pins in python-tests.yml and release-apk.yml.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FBbkN4ZB4aUPJPzR2prRan
2026-10-02 14:40:58 +02:00
9325103f5d Flutter 3.47.6; dismiss re-arm test no longer passes only on Tue-Thu
The expectation resolved the next alarm without the earned ramp set, while
the app (correctly) re-arms with the minute the dismiss just earned. On a
non-workday that is one minute apart, so the test failed Fri-Mon on any
Flutter version. It now loads the policy exactly as the app does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FBbkN4ZB4aUPJPzR2prRan
2026-10-02 14:28:55 +02:00
f95cf826d2 gatelock 0.8.2 -> 0.9.0; mypy 2.4.0, pylint 4.1.1, ruff 0.16.10
gatelock 0.9.0 adds gatelock.morning_session (the shared reader of
wake-alarm's morning carrot, now used by screen-locker, leetcode-guard and
book-guard); nothing here changes behaviour. The tag moved the freshness
gate, so the pin moves with it, together with today's lint-tool releases.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FBbkN4ZB4aUPJPzR2prRan
2026-10-02 14:19:53 +02:00
012673aa99 TODO: v2 follow-ups for the next session
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-01 19:39:58 +02:00
9b3c3ba26b Docs: v2 verification status; vmbox can emulate RTC wake now
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-01 12:30:32 +02:00
4527834b45 Take pylint 4.1.1 (newest stable)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-01 12:27:37 +02:00
728e00cde7 Wake enforcement v2: PC fallback ring + RTC self-wake, stacking Tue-Thu phone lockdown, escape hatch until 2026-10-15, stakes in the app, daily incident audit
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-01 12:17:06 +02:00
19f23f35a6 Free days: a month calendar of the shared pool; tap a future date to book it, tap a booked one to release it
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-27 20:53:46 +02:00
7f7fd916f7 Earned ramp: a dismissed Mon/Fri/Sat/Sun morning earns the minute; workdays hold, misses and free days earn nothing; workdays from freedays 0.3.0
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-27 20:13:22 +02:00
a4876d84ec Speed up CI: uv installs, split pre-commit into mypy/pylint/rest
- pre-commit: drop the 28 s requirements.txt install (only
  dependency-freshness among the system hooks needs third-party code:
  pyyaml, packaging), run pre-commit directly instead of
  pre-commit/action, and split mypy and pylint into their own matrix
  jobs with per-group hook-env caches. Same hook set, same
  SKIP=free-days-interop (the rest group).
- Tests: uv with a cached wheel store for requirements.txt (pip took
  22 s), -q and -p no:sugar. No -n auto: the suite runs in ~0.5 s and
  measured ~1.2 s under pytest-xdist.
- free-days-interop (the critical path): build the freedays venv with
  uv instead of venv + pip (12 s).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0188kZdx3bb56QM8JFUnbHuM
2026-09-26 17:45:00 +02:00
16f9ddeb13 Keep the test suite's JSONL log out of the live events.jsonl
_logging_setup attaches its JSONL sink the first time an entry point's
main() runs, and the conftest never redirected LOG_JSONL_FILE or
LOG_DEDUPE_FILE. Every suite run appended ~25 fixture warnings ("Synced
alarm out of range: 24:0") to ~/.local/state/wake_alarm/events.jsonl, the
log a failed wake-up is reconstructed from. Patch _logging_setup's names
(it imported them by value) in the autouse _hermetic fixture.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0188kZdx3bb56QM8JFUnbHuM
2026-09-26 17:44:52 +02:00
702f37a7ba Bump ruff 0.16.8 -> 0.16.9 and Gradle 9.7.1 -> 9.8.0: newest stable dependency-freshness gate
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-25 13:27:37 +02:00
d8b07b2be4 Cook the frog: lower the wake baseline a minute a day from 08:00 to 07:00
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-25 13:15:44 +02:00