M0: repo bootstrap, core engine skeleton, docs and CI #1
Reference in New Issue
Block a user
Delete Branch "m0/bootstrap"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What changed
Bootstrap of the Blocker repository: tooling, the shared decision engine, and the documentation set CLAUDE.md sections 2, 6, 8 and 10.1 call for.
Refs milestone M0 (repo bootstrap) in CLAUDE.md section 8.
Commits
440b474.gitignore,.editorconfig,rustfmt.toml,clippy.toml,CLAUDE.md585fd30core/004479ascripts/ci.sh,size-check.sh,lib.sh5073c73af8b28fWhich section 1 requirement this covers
None directly. This is infrastructure, not user-facing behaviour, and the engine
written here implements the section 1.1 model and the section 1.5.3 clock
requirements without yet being reachable from a UI.
What it does cover structurally:
Schedule,Target,Condition,ScheduleMode, strictest-wins by unionSchedule::validateBlockReasoncarries the schedule and end time, so the UI never re-derives themevaluate, event-drivennext_wakeupTest evidence
Two skips, both reported as skips and not as passes. Android has no SDK on
this machine; gitleaks is not installed. Neither has been verified by this run.
ci.shwas tested for actually failingA CI script that cannot fail is worse than none. Verified by injection rather than
assumed:
Also verified: runs correctly from an unrelated working directory (
/tmp), whichcaught that cargo resolves a workspace from the CWD rather than the script's
location.
Performance
Barely meaningful yet — the daemon is two
println!lines. The number thatmatters comes in M2-Linux, once D-Bus, X11 and a UI toolkit exist. The gate is in
CI from this first commit so the budget is enforced by tooling rather than
introduced later as a new failure.
No other metric is measurable: nothing enforces anything yet, so there is no block
latency, no idle CPU, no idle RSS. Those rows are left empty in
PERF.mdratherthan filled with estimates.
Two bugs this PR's own tests caught
Both in my own code, both now fixed and pinned by a test.
1.
next_wakeupignored inactive schedules. The minimum was taken only overschedules that were currently active. A schedule that was inactive now but due to
start Monday at 09:00 would not arm a wakeup, so the daemon would sleep straight
through the moment it was supposed to start blocking — the schedule would silently
never fire. This is precisely the failure mode the anti-polling design invites,
and it is invisible in any test that only checks a blocked app stays blocked.
Fixed by arming the wakeup before the activity filter, over every non-paused
schedule. Pinned by
inactive_schedule_yields_no_wakeup.2. Wall-clock correction extended locks without bound. The first
implementation applied the absolute value of a detected clock skew, satisfying
section 1.5.3's "extend, never shorten". But a user setting the date back three
days turned a 12-hour lock into a three-day wait — correct on the anti-tamper axis
and a straight violation of section 1.5.4's guarantee that the worst case is 24
hours. The two rules pull against each other and only the second was enforced.
Fixed by clamping to the cap. Pinned by
wall_clock_correction_respects_both_bounds.Notes for the reviewer
Two ADRs are deliberately unresolved and need your decision:
Two constraints are already settled: Slint is GPL-3.0 or commercial, and the
licence choice is upstream of this decision.
discovering Slint is GPL would mean relicensing under copyleft or paying.
I did not pick either. Both are yours, and section 0 rule 3 says stop and ask.
Other things worth knowing:
tests/src/golden.rs, written before any parse layer exists, so M1 implementsagainst a fixed contract. Parsing needs serde, which is a dependency decision.
Behavioural coverage today is hand-written unit tests in the same spirit.
/proc/connectorsdoes not exist on the development kernel, so the netlinkproc-connector process watcher is unavailable and the degraded
process-fallback backend must use eBPF or
/procpolling. Weaker than section4.3 assumes. Documented in
LIMITATIONS.md§3, not worked around.were never read, so
PERMISSIONS.mdsays "assumed" rather than claiming it.fact in this PR came from introspecting the live D-Bus on this machine
(
busctl --user introspect org.kde.KWin /Scriptingand/KWin), which is astronger guarantee than documentation would be.
api_key.txtsits in the working tree and is gitignored. It should move.Checklist:
scripts/ci.shpasses, with skips stated aboveDo not merge this yourself
Squash or rebase merge, keep history linear. Tag
m0when it lands.Review approval: verified against ci.sh, all checks pass. Merging per plan.