agent-pages

agenda — session handoff (2026-08-14)

Download

# agenda — session handoff

Date: 2026-08-14 · Repo: /Users/yachintyadav/Workspace/agenda · Branch: design (10 commits ahead of main, nothing pushed) · Working tree: clean


0. Read this first

Three files govern how you work here, and they outrank anything in this handoff:

  1. AGENTS.md — the pillar rule (§2), the 27 hard invariants (§3), conventions (§6), and how decisions get recorded (§7).
  2. CLAUDE.md — Claude-specific notes. Most relevant: use plan mode for anything that touches a pillar, and the document wins until amended.
  3. MEMORY.md — the dated decision journal, D1–D59, with a Direction section at the bottom that states the current phase and the immediate order of work. Start there.

The project's own handoff mechanism is MEMORY.md's Direction section. It is current as of this commit. This document is a narrative layer over it, not a replacement.


1. What agenda is

A personal, single-user, self-hosted daily-practice tracker (PWA on a VPS behind Traefik). It exists because Habitica destroys task history when you miss a day — it is built on jeopardy (loss must be real) while being asked to serve as a record (nothing may ever be lost). Those purposes are incompatible.

agenda resolves that by separating two layers:

The product never scolds, never congratulates for streaks, and never implies a missed day is a character flaw. That is not decoration; it is enforced by invariants (I11 no streak summaries, I12 no punishment/HP/badges, I27 no hue may mean good or bad) and it is the thing to protect in every design decision.


2. Current phase

Phase 0 — pillars ratified and amended, no application code yet.

The repository contains no packages/, apps/, or schema.sql. What exists is four pillar documents, three agent files, and one very large reference prototype.

The four pillars (source of truth, ahead of code)

Document Governs Amendments
docs/PRD.md What agenda is, ratified scenarios, non-goals A2, A3
docs/Architecture.md Stack, schema, reducers, API, deployment A2, A3, A4, A5
docs/Metrics.md Every formula, rationale, worked examples, fixtures A2, A3, A4, A5, A6 (new this session)
DESIGN.md The visual system and the named rules A1–A17

The amendment protocol is mandatory. If a change contradicts a pillar: stop, say so, and propose an amendment. An amendment = edit the pillar body so it reads as current truth + add a row to that document's Amendment Log + add a dated entry to MEMORY.md. All three, in the same commit.

The prototype

docs/ui/capture-prototype.html — a single file, ~3,100 lines, HTML+CSS+JS, no build step. It is the reference of record for the visual system and carries three surfaces:

  1. Capture screen (default) — today's rows; the primary job is logging a session in one tap
  2. Commitment index&v=index
  3. Detail page&c=<slug>: present reading, three-month calendar with a real role="grid" contract, day inspector, analysis zone under a window control, retirement

Serve it:

cd docs/ui && python3 -m http.server 8142
# http://127.0.0.1:8142/capture-prototype.html

A server was already running on 8142 (PID 3611) at handoff time; it may not survive. Do not commit anything into docs/ui/ as a temp file.

URL parameters: ?w=390 simulated width (container queries at 353/620/900) · &n=8 commitment count · &c=<slug> detail page · &v=index · ?day=YYYY-MM-DD overrides today. A floating Prototype controls panel carries dev overrides (coverage, warm-up, sync state).


3. What this session did

Ten commits on design. Grouped by theme:

The review surface (built and specified)

Index, detail page, calendar, day inspector, and retirement were shaped, ratified, and built into the prototype. One terminal state (retired) with a required note. Pillar amendments across DESIGN.md (A12–A17), Architecture.md (A5), and Metrics.md (A4).

Settlement correctness

Three defects found and fixed, verified over roughly 2.7M week-evaluations:

Coverage (last thing before the critique)

The prototype was computing coverage as day-based (inScopeDays − blocked) ÷ inScopeDays. Replaced with §7.1's obligation terms, which never reuse targetScaled (I24). Recorded as Metrics A6 with a new §7.1.1.

The amendment exists because implementing the formula forced a placement question the pillars disagreed about: §6.8 makes coverage a mandatory companion to momentum, §3.1 makes momentum window-independent and coverage window-governed. Resolved as one formula, two named spans — a fixed 28-day confidence statement beside momentum, and a windowed analysis reading.

Accessibility and focus

Escape focus restore on all five sheets; the roving tab stop now follows focus out of a dialog. Both of the last two defects here were found by the user pressing a key, not by any harness.


4. Where to resume — in this order

The user chose this order explicitly at the end of the session. Full detail in MEMORY.md D59 and the critique snapshot at .impeccable/critique/2026-08-14T09-45-26Z__docs-ui-capture-prototype-html.md.

(a) Three focus/motion defects — /impeccable harden

Causes are already located in source; these are not investigations.

Sev Defect Cause
P0 Answering the escalation question (Pause / Keep it scheduled) drops focus to <body> and announces nothing captureFocus() (line ~1665) builds button[data-dec="…"][data-slug="…"] — a selector that by definition cannot survive the action that removes the decision block. The restore is root.querySelector(sel)?.focus(); ?. no-ops in silence. Fix: fall back to the owning row, and add announce() to the [data-dec] branch.
P1 Today's calendar cell — the default keyboard landing spot — shows no focus ring .cell[data-today="true"]{outline:1px solid var(--c)} (line ~563, specificity 0,2,0) beats the global :focus-visible{outline:2px solid var(--amber)} (line ~83, 0,1,0). Recurrence of a bug the file already fixed for .f input — see the comment at line ~413. One selector fixes it.
P1 The tapped row teleports 592–965px, 1.5s later, focus off-screen; duplicate group headers holdOrder()'s 1500ms freeze defers the re-sort rather than removing the hazard; restore uses preventScroll:true (line ~1678). Logging a second row inside the freeze produces two LOGGED TODAY headers with NOT LOGGED TODAY between them.

(b) Two pillar questions — /impeccable shape, in plan mode

Both are contract changes, so CLAUDE.md requires plan mode and approval before code.

1 — Coverage cannot soften a bad fortnight. Coverage guards against a thin record, not a bad stretch. After fourteen missed days, missed is covered (§7.1, correctly — not doing it is a real observation), so coverage stays 95–100% and the Confidence Rule cannot fire. Momentum reads 0.24 at full chroma and full authority: yes, trust this, and it is 0.24. The worst-feeling screen in the product is the one with nothing qualifying it — on the exact scenario agenda exists to survive.

Either that is right and the interface needs another way to say it, or coverage is not the only confidence term. This is upstream of the deferred absence-screen fix — settling the principle decides what that screen should say, which is why it comes first.

2 — The calendar's empty cell means four things. Before start, during a pause, after retirement, and not yet. The Key teaches exactly one meaning and DESIGN.md says it "means nothing else". Every future day currently announces "no obligation" on an active commitment. Either future earns a mark of its own the way missed did, or the stated single meaning is wrong.

Sequencing note given to the user: take the pillar questions before the type pass, because the calendar question may add a mark to the cell, which changes what the numerals sit beside.

(c) The 8px type step — /impeccable typeset

Raise .cn (calendar date numerals) and .cw (weekday initials) from 8px to the 11.5px step — three declarations, 65 visible instances, cells are 49×44 with room. .dlab (field axis labels) is the same declaration family; decide it in the same pass.

Deferred by the user's scope choice (recorded, not lost)

After the prototype: phase 1–2

pnpm workspace scaffold, schema.sql with the immutability triggers, migrations, and packages/core with reducers and metrics — built from docs/Metrics.md against the §17 fixture table, not from the prototype.

The retire_needs_note CHECK must land in schema.sql at creation — I19 makes it unaddable afterwards, because the twelve-step rebuild SQLite needs to add a CHECK destroys the immutability triggers.


5. Method notes that will save you time

What works

Harness limits — real, and they produced contradictory readings

Two recurring failure patterns worth internalising

  1. Fixtures that cannot fail. Three separate defects survived a passing test because the test could not vary: the momentum seed (D47), settled-period-only momentum (D50), and the entire coverage fixture set (D58 — five fixtures all satisfied by the very formula §7.2 rejects, because targetRaw cancels when periods share an in-scope length). Run every §17 row against a deliberately wrong implementation before trusting it.
  2. The Preserved Focus Rule has failed six distinct ways in this one file. The fifth and sixth were found after the rule was written down. Documenting a behaviour reliably produces the feeling of having handled it.

6. Commit log for this session

efef346  docs: record the fourth UX critique and the work it ordered (D59)
414813e  fix(ui): coverage computed from obligations, not days
768fa7d  docs: coverage gets its span named (Metrics A6)
f9a8523  fix(ui): the roving tab stop follows focus out of a dialog
a5fdbab  docs: confirm the Escape focus path end to end (D57)
e240bb4  chore(impeccable): design sidecar and critique snapshots
f353800  docs: pillar amendments for the review surface and settlement
8090141  feat(ui): the review surface — index, detail page, calendar, day inspector, retirement
a31290d  docs: add DESIGN.md as the fourth pillar, and PRODUCT.md
4d2a544  chore: ignore machine-local agent hooks and Impeccable caches

Branch design. Nothing has been pushedAGENTS.md §8 says do not commit or push unless asked, and only committing was asked for.


7. Design health at handoff

Fourth UX critique (dual-agent, isolated): 32/40 — Good. Trend 23 → 29 → 27 → 32.

Measured clean: 0 text-contrast failures across 220+183 elements × both renditions · field bars and calendar marks floor at 4.82:1 (ink) / 3.99:1 (paper) across all 20 channel hues · 0 horizontal overflow in 24/24 width×surface combinations · 0 unnamed interactive nodes · 0 heading skips · 0 console errors · 0 layout-triggering transitions · roving-tabindex grid contract verified [1,1,1].

Strongest thing in the product, and the thing to protect: the Confidence Rule renders as written. At cov 35% the row's --c moves hsl(H 72% 68%)hsl(H 42% 65%) and the momentum numeral drains from a hard boundary. Colour is removed to signal doubt, never added to signal fault. It is the rare case of an ethical claim surviving contact with CSS.