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

opened this

Check · Review · Land · Live — Its check is red. Next: builder, its check is red.

Ready to land

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)

Look

1 page beside main · 0 new to this pull

main

at 76d57b2 ·

this pull

In the dark

main

at 76d57b2 ·

this pull

at 1874791 ·

opened this

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: digestByDeal in src/reminders.ts is 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() in src/pages/review.ts shows 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-words class, 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 bareDraft in src/review.test.ts found 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.ts checks 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

Closes #315

commented

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: digestByDeal in src/reminders.ts is 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() in src/pages/review.ts shows 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-words class, 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 bareDraft in src/review.test.ts found 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.ts checks 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

commented

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.ts requires the README tour to match STEPS in src/tour.ts exactly. 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 = 50 reminders. 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

Changes requested — before the latest push

Security is clean: output is escaped, the digest has no form or write, no contract cell changed. Changes needed, all in one round:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
commented

All four of sentinel's points are addressed and pushed.

  1. 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.

  1. Empty-state tests: Review page and terminal now share DIGEST_EMPTY ("Nothing is due today."), defined in src/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.
  2. Docblocks: DIGEST_MAX moved to src/reminders.ts so the page and terminal share one limit, and digest() in src/pages/review.ts has its own docblock again.
  3. 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

commented

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 ran src/speed.test.ts here 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 on main too, 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.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs