Skip to content

Fix #1836: Decisions tab reads time-only and missing stamps without a warning - #1837

Merged
waleedkadous merged 11 commits into
mainfrom
builder/bugfix-1836
Oct 19, 2026
Merged

waleedkadous merged 11 commits into
mainfrom
builder/bugfix-1836

Conversation

@waleedkadous

@waleedkadous waleedkadous commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Almost every Decisions card showed Not converted: the date or time is not in a recognized format, because hub architects write a bare time (6:30 pm) or no stamp at all, and the tab accepted only a full YYYY-MM-DD h:mm am ZONE stamp. The tab now reads a file-level zone, converts time-only stamps, and keeps the warning only for the case it was written for: an ambiguous or unknown zone, or a time the clocks skipped or repeated.

Fixes #1836

Root Cause

Three places:

  1. servers/decisions/stamp.ts: STAMP_RE required both a date and a zone, and resolveStamp took no context, so any stamp missing either came back as unrecognized-format. Nothing read a file-level zone.
  2. servers/decisions/parse.ts splitHeading: the first · part was always taken as the stamp. So in ### main-4 · Should we file the bug? the question was sent to resolveStamp, flagged, and the card's question came out empty.
  3. DecisionsView.tsx Stamp: every null instant got the "Not converted" flag.

Fix

  • File zone. The one _Zone: <zone>_ line above the first ## (same zone vocabulary as stamps) applies to every stamp that names no zone. No dashboard.decisionsZone setting: the file stays the only state.
  • Time-only stamps. h:mm am or HH:mm is read as today in the effective zone at read time, so today's offset applies. Per the architect's ruling, the card shows only the converted time (e.g. 6:30 PM PDT), never a date the writer didn't give. Full stamps still show their date. The "## Ruled line" date clause was dropped, also per the ruling.
  • No stamp, or a part that isn't one. resolveStamp returns null and the text stays in the question as written, with no warning. A stamp with no zone in a file that names none is shown as written, with no warning.
  • Warning kept for IST/BST/AST and other unknown zones (written in the stamp or in the file) and for skipped/repeated clock times.
  • Type. unrecognized-format is removed from DecisionStamp.unconvertedReason, since it can no longer reach the wire; timeOnly?: true is added.
  • Doc (resources/decision-protocol.md, both trees, byte-identical): the heading rule, a new "A file may name its zone once" bullet (a bare time is "as written, converted to your clock"), and the full form kept as the one to write. The doc's new example runs through the parser and resolveStamp in decision-protocol-doc.test.ts.

Two changes worth a reviewer's eye:

  • A stamp's zone is now a single token (\S+). When a time-only stamp names a zone the tab can't resolve, it warns only if that word is shaped like a zone (all-caps abbreviation, Area/Location, or offset); otherwise the text is a question (10:30 standup?). Dated stamps warn for any unknown zone, as before. This came from the CMAP round (codex, claude).
  • The template's <YYYY-MM-DD h:mm am/pm ZONE> placeholder is not a stamp, so it now reads as part of the template's question. The doc test asserts this.

Integration review and owner ruling

  • Everything in UTC (owner ruling). The doc's §4 file template ships _Zone: UTC_, and its note says the line stays UTC. Agents write stamps as YYYY-MM-DD HH:mm UTC (date -u '+%Y-%m-%d %H:%M UTC'), and the doc's examples use that form. Other zones are still accepted for anything a person types. The tab converts every stamp to the viewer's clock.
  • §3 step 1 now mentions the zone line. The parse.ts header now says the parse reads the clock, and notes the version cache key and splice.verify() caveats.
  • Follow-up: Decisions tab: report an unusable _Zone: header line once, as a file-level problem #1838 (report an unusable _Zone: header line once, as a file-level problem).

Test Plan

  • Regression tests added: decisions-stamp.test.ts (_Zone: PT_ + 6:30 pm; no zone + 6:30 pm shown as written with no reason; full stamp unchanged; today taken in the zone, not UTC; IST still warns; skipped/repeated times today), decisions-parse.test.ts (no-stamp heading keeps its question; header-only, single zone line; time-only via the header), decision-protocol-doc.test.ts (the doc's file-zone example), and DecisionsView.test.tsx (time alone with no date; no flag without a reason). With HEAD's source, 25 server tests and 2 web tests fail; with the fix, all pass.
  • Playwright Decisions suite (playwright.decisions.config.ts, throwaway Tower): 11/11 pass, including two new cases. The zoned file shows 6:30 PM PDT, the no-stamp card keeps its question, the full stamp is dated, and the view has no Not converted. The unzoned file shows 6:30 pm as written, and only the IST card warns. Screenshots checked.
  • Build passes (porch build check)
  • codev unit suite passes (6511 tests; porch tests check)
  • Note: locally, 74 web tests in Terminal*, VirtualKeyboard and architect-toolbar fail on Node v26.3.1 because jsdom's localStorage is undefined there. These tests don't touch the Decisions code; the Decisions web tests pass.

🤖 Generated with Claude Code

waleedkadous and others added 7 commits October 19, 2026 08:34
The Decisions tab flagged nearly every card "Not converted" because the stamp
parser accepted only a full `YYYY-MM-DD h:mm am ZONE` stamp, and a heading with
no stamp had its question read as one.

- A `_Zone: <zone>_` line in the file's header is the zone of every stamp that
  names none. A time-only stamp is today in that zone, at read time, and the
  card shows the converted time alone, never a date nobody wrote.
- A heading part that is not a stamp stays in the question, as written. A stamp
  with no zone known is shown as written, with no warning.
- The warning stays for an unknown or ambiguous zone (IST, BST, AST) and for a
  time the clocks skipped or repeated.
- decision-protocol.md (both trees) documents the zone line and bare times and
  keeps the full form as the one to write; its new example runs in the doc test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`### main-4 · 10:30 standup?` read `standup?` as an unknown zone, so the card
warned and lost its question. A time-only stamp whose written zone the tab
cannot resolve now warns only when the word is shaped like a zone (an
abbreviation, an Area/Location name, an offset); otherwise it is not a stamp.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@waleedkadous

Copy link
Copy Markdown
Contributor Author

Thank you — this does exactly what the issue asked, and the round-one catch (a bare time followed by a word staying in the question) was the right call. I checked the parser, the view and both doc trees against the issue item by item, and the two screenshots show the time-only card without a date and the unzoned one as written with no flag. Blast radius is contained: resolveStamp has one production caller and dropping unrecognized-format from the wire union touches only the view.

Two small changes before merge:

  1. Put the _Zone: line where a hub will actually write it. It is documented in "What the tab reads" but §4's file template and §3's hub steps never mention it, so a hub following the doc produces a file without one and the feature goes unused. Add _Zone: <zone>_ to the §4 template (with a one-line note) and a clause in §3 step 1.
  2. Fix the parse.ts header. It still says the parse is a pure function of the text; it now reads the clock for time-only stamps. Say so, and add a one-line note that version (the client's cache key, a hash of the text) does not cover that time dependence, and that splice.verify() is safe only because it compares no stamps.

Not for this PR, file as a follow-up: a _Zone: line that does not parse, or is duplicated, either fails silently or warns on every card with nothing pointing at the header. A file-level DecisionsFileProblem shown once at the top of the tab is the right home.

…ds the clock

- decision-protocol.md (both trees): the §4 file template carries
  `_Zone: <zone>_` with a note to replace it, and §3 step 1 says the hub keeps
  that line naming the zone its clock reads, so a hub following the doc writes
  one. The doc test checks the template line and that, once filled in, a
  bare-time item converts.
- parse.ts header: the parse is no longer a pure function of the text (bare
  times are read as today). `version` hashes the text only, so a client keeps
  the instants it has until the file changes; splice's verify() is safe only
  because it compares no stamps.

Follow-up: #1838.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
waleedkadous and others added 2 commits October 19, 2026 09:14
Owner ruling: agents write stamps in UTC and the tab converts them to the
viewer's clock.

- decision-protocol.md (both trees): the §4 template ships `_Zone: UTC_`, and
  its note says the line stays UTC. Agents write stamps as
  `YYYY-MM-DD HH:mm UTC` (24-hour, `date -u '+%Y-%m-%d %H:%M UTC'`). §2's
  template, the worked example and the file-zone example use that form; other
  zones are still accepted for anything a person types.
- Doc test: every dated example stamp is that form; a bare time in the template
  file converts in UTC. The unfilled-placeholder case is now a parser test on a
  literal.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
decision-protocol.md (both trees): §3's relay, Ruled and DONE times are
`<time> UTC`, the closing guidance reads the clock with `date -u '+%H:%M UTC'`
(a stamp adds the date), and the 3c Q&A example uses UTC times. The doc test
pins the placeholders, the command and the Q&A example times.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@waleedkadous
waleedkadous merged commit 537639d into main Oct 19, 2026
7 checks passed
waleedkadous added a commit that referenced this pull request Oct 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Decisions tab: a time-only stamp, or a missing one, flags nearly every card as 'not converted'

1 participant