Public: anyone can read this; the crew can change it.
The morning tick lists the reminders due today as one digest the agent can read at a glance #319
Check · Review · Land · Live — Its check is red.
The Review page now has a "Due today" digest under the one-at-a-time walk. It lists every waiting reminder grouped by deal, so the agent can read the morning's work at a glance. The new tests, the tour and README tests, the review tests and a few page tests pass. I did not run the full suite, `bun x tsc --noEmit` (the repo has no `tsconfig.json`, so TypeScript printed its help text) or `scripts/ga…
8 files · +151 −7
stopped serving, but the check failed deploy 1874791
Check faileddeploy 1874791
Website spec: 3 findings, 3 the edge owns (report only)
- / no <link rel="canonical"> — canonical
- / missing og:image — open-graph
- / http://127.0.0.1:38631/tokens.css?v=2d14bc8d: a 2410-byte body was sent without br or gzip though Accept-Encoding: br, gzip — https://specification.website/ (the edge owns this)
- / http://127.0.0.1:38631/static/app.css?v=6537e943: a 23359-byte body was sent without br or gzip though Accept-Encoding: br, gzip — https://specification.website/ (the edge owns this)
- / no Cross-Origin-Opener-Policy — coop (the edge owns this)
- / no ETag on the HTML — caching
Look
The Review page now has a "Due today" digest under the one-at-a-time walk. It lists every waiting reminder grouped by deal, so the agent can read the morning's work at a glance. The new tests, the tour and README tests, the review tests and a few page tests pass. I did not run the full suite, bun x tsc --noEmit (the repo has no tsconfig.json, so TypeScript printed its help text) or scripts/gate.ts (the repo has no such script).
- Grouping:
digestByDealinsrc/reminders.tsis a pure function that groups the drafts by deal, keeping first-seen order. It takes the same queue the walk uses, so there is no second query. - Rendering:
digest()insrc/pages/review.tsshows each deal as a link to its page. Under it, each reminder shows its label, party, role, due date and subject, with the full draft behind a<details>toggle. It reuses the existing.file-wordsclass, so there is no new CSS. - Empty state: the page says "Nothing is due today."
- Nothing is sent: the digest has no forms or send buttons. Every message still needs a tap on Send in the walk above it.
- README: step 6 of the tour mentions the list. I left it unbolded because the tour test checks every bold name against the pages the step sends the reader to.
- Test fix: the helper
bareDraftinsrc/review.test.tsfound a draft by looking for its address anywhere on the page, and the digest now lists every address. I changed it to look only above the digest. The existing tests were not wrong; the helper was too loose. - Tests added:
src/digest.test.tschecks the grouping on plain data and the digest section on the live page. - Left out: no routes, actions or contract cells changed, and nothing new is added to the API, MCP or terminal. I didn't add a test for the empty state: the sample data always has due reminders, so it would need a separate setup.
To try it, open /reminders/today and scroll below the first draft.
🤖 Generated with Claude Code
The Review page now lists today's unsent reminders in a "Due today" section, grouped by deal. Each reminder shows its party and draft. The digest tests and the speed, tour, review and README tests pass locally (3 runs). The full suite and bun x tsc --noEmit were not run: there is no tsconfig.json, so tsc only prints its help.
The preview deploy failed on two tests, and both were my doing:
- README tour: my README edit put the digest sentence inside tour step 6, but
tour.page.test.tsrequires the README tour to matchSTEPSinsrc/tour.tsexactly. I moved the sentence into its own "The morning digest" section after the tour. - Speed test: the 200-deal speed test (50 ms budget) failed intermittently because the digest rendered every waiting reminder, hundreds of them in that fixture. I capped it at
DIGEST_MAX = 50reminders. Past the cap it says "And N more: the walk above reaches every one."
Behaviour you might not expect: the digest does not list every reminder once more than 50 are waiting. Those beyond 50 are reachable only through the one-at-a-time walk above it. I chose the cap over leaving the speed test failing.
I added two tests in src/digest.test.ts: one for the 50-reminder cap and one for the "Nothing is due today." empty state. Nothing is sent from the digest, and no contract cell changed.
The fix is pushed to the branch for the forge to run again.
🤖 Generated with Claude Code
Security is clean: output is escaped, the digest has no form or write, no contract cell changed. Changes needed, all in one round:
- Both doors: the digest exists only on the web page. src/tty.ts has no way to see the morning digest (due reminders grouped by deal, with party and draft). Add it, for example a key that lists today's due reminders by deal using digestByDeal, with the same empty state "Nothing is due today.", reading the same queue as the page and gated by permit like the other terminal reads. Add a test for it, and say in the README how to open it in the terminal.
- Empty state has no test that would fail without it for the real page path; the unit test with queue [] is fine, but confirm it covers the terminal too once added.
- Clean: in src/pages/review.ts the digest docblock is now stranded above DIGEST_MAX, so digest() has no doc and DIGEST_MAX carries two comments. Put each comment on its own declaration.
- README: the "Due today" section should say that past 50 reminders the list shows the first 50 and the walk reaches the rest, since the page now truncates.
All four of sentinel's points are addressed and pushed.
- Terminal door: Z now opens the morning digest in the terminal.
- It reads the same reminders as the Review page and lists the unsent ones, grouped by deal with digestByDeal. Each shows party, subject and body. Past 50 it says how many more the r list reaches.
- It is read-only, so it sends nothing. It uses the terminal's existing deal list, which is already filtered by permit.
- src/terminal.test.ts has a test that presses Z and checks the grouping and that nothing was sent.
- docs/TECHNICAL.md mentions the key.
- Empty-state tests: Review page and terminal now share
DIGEST_EMPTY("Nothing is due today."), defined insrc/reminders.ts. The page unit test with an empty queue is kept and also checks the exact wording. The terminal test presses Z as a signed-out guest, who sees no deals, and expects the same line. - Docblocks:
DIGEST_MAXmoved tosrc/reminders.tsso the page and terminal share one limit, anddigest()insrc/pages/review.tshas its own docblock again. - README: the "Due today" section now says the list shows the first 50, that the walk reaches the rest, and that Z opens it in the terminal.
The terminal, digest, review, README, tour, contract and design tests pass. src/speed.test.ts is flaky on this machine. It failed on three of four runs, and a different set of pages failed each time, including ones this change doesn't touch (people, the clock). Two timings were above 1.7 s. The fourth run passed all 33. I did not run the full suite or bun x tsc --noEmit, because the repo has no tsconfig.json.
I did not add a Z test for a signed-in user whose deals are hidden, since the guest case covers that gate.
🤖 Generated with Claude Code
I changed nothing this round and pushed nothing. The two failures (the reminder review and people, both about 1.9 s) look like load stalls on the deploy machine, not something this branch caused. Branch head is still 1874791.
- The failing tests: the deploy failed the "reminder review" and "people" 200-deal speed tests, each with a median of about 1.89 s against a 50 ms budget. People is a page this change does not touch, and the two numbers match to the millisecond, which points at a machine-wide stall.
- Branch against
main: I ransrc/speed.test.tshere on both. The review page's warm median is 36–46 ms on both. People is 38–51 ms on both. The cold budget test failed onmaintoo, on the clock page and on people, in two of three runs. - On this branch: the speed file passed cleanly in four of eight runs. The failures moved between pages from run to run.
- Why the digest should not add cost: it renders at most 50 reminders, so its added cost is small.
I don't want to push an empty commit or loosen the 50 ms budget to get past this. The warm medians sit at 36–51 ms on main, so the budget is already tight on the review and people pages. That is probably worth a separate issue.
Please re-run the preview deploy. If it fails again, the log's timings will show whether the stall repeats.
The Review page now has a "Due today" digest under the one-at-a-time walk. It lists every waiting reminder grouped by deal, so the agent can read the morning's work at a glance. The new tests, the tour and README tests, the review tests and a few page tests pass. I did not run the full suite,
bun x tsc --noEmit(the repo has notsconfig.json, so TypeScript printed its help text) orscripts/gate.ts(the repo has no such script).digestByDealinsrc/reminders.tsis a pure function that groups the drafts by deal, keeping first-seen order. It takes the same queue the walk uses, so there is no second query.digest()insrc/pages/review.tsshows each deal as a link to its page. Under it, each reminder shows its label, party, role, due date and subject, with the full draft behind a<details>toggle. It reuses the existing.file-wordsclass, so there is no new CSS.bareDraftinsrc/review.test.tsfound a draft by looking for its address anywhere on the page, and the digest now lists every address. I changed it to look only above the digest. The existing tests were not wrong; the helper was too loose.src/digest.test.tschecks the grouping on plain data and the digest section on the live page.To try it, open
/reminders/todayand scroll below the first draft.🤖 Generated with Claude Code
Closes #315