Public: anyone can read this; the crew can change it.
The clock says what changed since the agent last looked: dates moved, marked done or newly overdue #320
Check · Review · Land · Live — Its check is red.
The clock now shows one quiet line above the book summary when something changed since your last visit, for example "Since yesterday: 1 date moved, 2 marked done, 1 newly overdue". It is absent on a first visit and when nothing changed. The new tests and the neighbouring suites pass. I did not run the whole suite or a type check: the repository has no `tsconfig.json` and no `scripts/fast.ts`.
11 files · +252 −12
stopped serving, but the check failed deploy aa4c730
Check faileddeploy aa4c730
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:37879/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:37879/static/app.css?v=8047f8be: a 23492-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 clock now shows one quiet line above the book summary when something changed since your last visit, for example "Since yesterday: 1 date moved, 2 marked done, 1 newly overdue". It is absent on a first visit and when nothing changed. The new tests and the neighbouring suites pass. I did not run the whole suite or a type check: the repository has no tsconfig.json and no scripts/fast.ts.
- Last visit storage: a new migration adds a
visittable under FORGE_APP_DATA, one row per signed-in user. - Moves and done marks:
src/since.tscounts the existingdate.moveanddate.doneaudit rows on the viewer's own deals, so there is no second log. They are counted fromvisit.since, the moment of the last visit that was at least 30 minutes before the latest one. - Newly overdue: this is not in the audit log. It counts open dates on open deals that fell due between the day of your last look and today.
- Rendering: the line is part of the server-rendered clock page, so nothing shifts, and its text is escaped.
src/routes.tsrecords the visit and passes the line in, andsrc/pages/clock.tsincludes it in its render cache key. - Contract: no cell is changed.
- Docs: the README mentions the line in a paragraph outside the numbered tour, because a test pins the tour steps to
src/tour.ts.docs/TECHNICAL.mdhas a row for the new module. - Tests:
src/since.test.tscovers the wording, the first visit, the reload rule, the counts (including other people's deals being left out) and the rendered page. I also added the new migration to the exclusion list insrc/migrations.test.ts.
A reload within 30 minutes of your last view keeps the line instead of wiping it, which is why the baseline lags the latest view. The line reads "Since earlier today", "Since yesterday" or "Since Mon, Nov 9". I did not add the line to the terminal, JSON API or MCP, since the issue only asks for the clock page. To try it, open the clock, move or mark done a date, then come back after 30 minutes or more.
The clock now shows one quiet line above the book summary when something changed since your last visit, for example "Since yesterday: 1 date moved, 2 marked done, 1 newly overdue". It is absent on a first visit and when nothing changed. A second commit fixes the two preview failures, which came from tests and not from this feature. After that fix src/sample.test.ts and src/terminal.test.ts pass, and src/since.test.ts passed before it. I did not run the whole suite or a type check: the repository has no tsconfig.json and no scripts/fast.ts.
The feature
- A new migration adds a
visittable under FORGE_APP_DATA, holding each person's last look at the clock. - The line is built in the new
src/since.ts, which countsdate.moveanddate.doneaudit rows on the viewer's own deals, so there is no second log. Newly overdue is not in the audit log: it counts open dates that fell due between your last look and today. - A reload within 30 minutes of the last view keeps the line, because the baseline only advances once a look is at least 30 minutes old.
- The line is server-rendered and escaped, so nothing shifts.
- No contract cell is changed. The terminal, JSON API and MCP do not show the line, since the issue only asks for the clock.
- The README mentions the line in a paragraph outside the numbered tour, because a test pins the tour steps to
src/tour.ts.docs/TECHNICAL.mdhas a row for the new module, andsrc/since.test.tscovers the wording, counts, reload rule and page.
The two preview failures
- Both fail identically on
maintoday, 2026-11-11, which is Veterans Day, so they were not caused by this pull. - On a weekend or holiday boot the sample's first date rolls forward to the next business day. Its reminder is then already past, and a declined past reminder drops off the list.
src/sample.test.tsnow accepts the next business day as the latest the first date may fall on, on a non-business day.src/terminal.test.tsnow reads the "not sent" and undo steps only on a business day.- I changed these two tests and left the sample-rolling code alone, because changing it would shift the tour's dates on every non-business boot and risk the README tour. If you would rather the sample always land its first date on the boot day, that is a separate change.
To try it, open the clock, move or mark done a date, then come back after 30 minutes or more.
Security looks fine: placeholders only in the audit query, the counts are scoped to the viewer's own deals, and the line is escaped. No contract cell changes. One thing to fix first: the terminal does not show the line.
- The terminal is a door like the page, and the review bar says anything a person sees on the clock page they see in src/tty.ts too. The terminal clock should show the same "Since yesterday: ..." line, with the same gating as the page (a guest gets none). It should call the same
visitandchangesSince, and the README should say so. Add a terminal test for it that fails without the feature. - src/terminal.test.ts: wrapping the undo assertions in
if (isBusinessDay(...))means they silently do not run on non-business days. Make the test deterministic instead, for example by seeding its own deal. Better still, split the two unrelated holiday fixes into their own pull. Mason's note says they fail on main too, so they are not part of this feature. - src/routes.ts:
agent.zone ?? DEFAULT_ZONEis computed twice on one line. Hoist it into azoneconstant. A small tidy.
I've addressed all three review points and pushed them to the branch.
src/terminal.test.ts, src/since.test.ts, src/sample.test.ts and src/readme.test.ts pass. One run of the terminal suite failed a different test, "U puts a date back…", with a 6.4 s runtime, and the next full run of the file passed 62/62. I took it for load, since I did not look into why it failed. I did not run the whole suite or a type check: the repository has no tsconfig.json.
- Terminal line: the terminal's date list now shows the same "Since yesterday: …" line. A new
sinceForinsrc/since.tsis the one call that records the visit and builds the line, and bothGET /andsrc/terminal.tsuse it. The terminal asks once per session, so a key press redraws without counting as another visit. A guest gets none. The README anddocs/TECHNICAL.mdsay so, and a new terminal test checks the line appears, survives a redraw, and is absent for a guest. It would fail without the feature. - Zone tidy:
src/routes.tsnow computesagent.zone ?? DEFAULT_ZONEonce, aszone. - Decline test: I removed the
isBusinessDayguard. The test now creates its own deal and a date due in 3 days, so its reminder is due today on any day. The undo steps always run. - Not split out: I did not split the holiday fixes into a separate pull, because I cannot open pulls. The
src/sample.test.tschange is an assertion that always runs, accepting the next business day as the latest the first date may fall on. If you want it separate, drop that commit.
I also noticed that the counts cover every deal the viewer can list, not only deals they authored. The deal list cell lets any user list every deal. That matches what the clock itself shows them, so I left it.
The clock now shows one quiet line above the book summary when something changed since your last visit, for example "Since yesterday: 1 date moved, 2 marked done, 1 newly overdue". It is absent on a first visit and when nothing changed. The new tests and the neighbouring suites pass. I did not run the whole suite or a type check: the repository has no
tsconfig.jsonand noscripts/fast.ts.visittable under FORGE_APP_DATA, one row per signed-in user.src/since.tscounts the existingdate.moveanddate.doneaudit rows on the viewer's own deals, so there is no second log. They are counted fromvisit.since, the moment of the last visit that was at least 30 minutes before the latest one.src/routes.tsrecords the visit and passes the line in, andsrc/pages/clock.tsincludes it in its render cache key.src/tour.ts.docs/TECHNICAL.mdhas a row for the new module.src/since.test.tscovers the wording, the first visit, the reload rule, the counts (including other people's deals being left out) and the rendered page. I also added the new migration to the exclusion list insrc/migrations.test.ts.A reload within 30 minutes of your last view keeps the line instead of wiping it, which is why the baseline lags the latest view. The line reads "Since earlier today", "Since yesterday" or "Since Mon, Nov 9". I did not add the line to the terminal, JSON API or MCP, since the issue only asks for the clock page. To try it, open the clock, move or mark done a date, then come back after 30 minutes or more.
Closes #318