Skip to content

A date is one day in every source - #371

Merged
VeryComplexAndLongName merged 1 commit into
mainfrom
wip-date-is-one-day
Sep 10, 2026
Merged

A date is one day in every source#371
VeryComplexAndLongName merged 1 commit into
mainfrom
wip-date-is-one-day

Conversation

@VeryComplexAndLongName

Copy link
Copy Markdown
Owner

A date is one day in every source

Fifth of the six changes from the code review. Resumed from the branch where an earlier interrupted run left partial work. The kept half was the date-fact shape in change-dates.ts; the discarded line was an import of a symbol that does not exist, so the interrupted commit did not compile.

The day disagreed with itself

A commit date was an instant normalised to UTC and then sliced to a day. A folder-name date was a local day stamped as UTC midnight. The same action got two different days depending on which source answered.

The day now comes from the record's own offset, before normalisation. The full instant is kept for ordering and lead times, and the two sort sites that read it keep the normalised form.

A correction to the review that proposed this. I wrote that two of ninety-one archive commits fall in the affected band. Measured properly: three of 192. And two of those three move away from their folder's day rather than onto it. Both were committed at 00:00:24 +03:00, twenty-four seconds after the day openspec archive had named their directories for. The commit is the better evidence and the specification already says so, but the proposal's framing assumed the folder was the truth. Corrected in place rather than left standing.

The rest

  • The audit-log work-date source was unreachable from either host. getChangeTimelines now takes audit timestamps, and both hosts read the log once per request.
  • A malformed archive prefix threw through the whole timelines request, against a module header promising it never throws. Every source now parses through one helper that reports an unreadable date instead.
  • readArchiveCommitDates told a date line from a path line by its first letter. A workspace under a directory beginning with C turned that into a silent fallback to the per-change read measured at 80 seconds. It now uses a delimiter no path can contain, resolves paths against the repository root, and reports the lines it could not read.
  • Chart arithmetic moved from webui into a core leaf module. A figure a second host wants to print is a figure two hosts would compute twice.
  • The sentence about the chart that is not drawn is computed from the workspace shown, instead of telling every user "measured over this repository, 135 of 185 changes".
  • Lead-time buckets are named by their boundaries, not "Same day" for a span that crosses midnight.

Looked at, not just asserted

Rendered the standalone app over this repository and opened the image. 192 changes, all dated from a commit, nothing excluded, no unread lines. Lead times: under a day 138, 1-2 days 26, 2-3 days 9, 3-8 days 14, 8 days or more 5.

The four days that moved:

Day Before After
2026-08-26 15 14
2026-08-27 2 3
2026-09-08 20 18
2026-09-09 17 19

The drawn table shows exactly that.

Premises the tasks got wrong

Task 6.1 offered "commit the archive on a different day from the folder's" as a way to reach the folder-name fallback. It cannot: a commit beats the folder whichever day it lands on. Split into two tests, one per path.

Task 1.1 said every reader of slice(0, 10) should read the new day. There was exactly one.

The design claimed audit timestamps carry an offset. They do not; every writer calls toISOString(). Corrected.

Verification

npm run verify unpiped, exit 0: 48 cli, 915 core, 320 extension, 80 server, 352 webui. Whole browser suite: 11 passed. openspec validate --strict --changes: 9 passed.

Two screenshots change. change-charts.png is this change's own output. harness-settings.png differs only in its version footer, catching up with Version Packages (#365).

One item stays open, delegated to copilot-cli.

🤖 Generated with Claude Code

A commit date was an instant normalised to UTC and then sliced to a day,
while a folder-name date was a local day stamped as UTC midnight. The
same action got two different days depending on which source answered.
The day now comes from the record's own offset, before normalisation;
the full instant is kept for ordering and lead times, and the two sort
sites that read it keep the normalised form.

Measured on this repository: three archive commits of 192 fall in the
band, not two of ninety-one as the proposal claimed. Two of the three
move away from their folder's day rather than onto it. Both were
committed at 00:00:24 +03:00, twenty-four seconds after the day
`openspec archive` had named their directories for. The commit is the
better evidence and the specification already says so; the proposal's
framing assumed the folder was the truth. Corrected in place.

Also here: the audit-log work-date source was unreachable from either
host, so getChangeTimelines takes audit timestamps and both hosts read
the log once per request. A malformed archive prefix threw through the
whole timelines request; every source now parses through one helper that
reports an unreadable date instead. readArchiveCommitDates told a date
line from a path line by its first letter, which a workspace under a
directory beginning with C turned into a silent fallback to the
per-change read measured at 80 seconds; it now uses a delimiter no path
can contain, resolves paths against the repository root, and reports the
lines it could not read.

The chart arithmetic moved from webui into a core leaf module: a figure
a second host wants to print is a figure two hosts would compute twice.
The sentence about the chart that is not drawn is computed from the
workspace shown, instead of stating 135 of 185 of this repository to
everyone. Lead-time buckets are named by their boundaries.

Rendered over this repository and looked at: 192 changes, all dated from
a commit, nothing excluded, no unread lines. The four days that moved
are 08-26 15 to 14, 08-27 2 to 3, 09-08 20 to 18, 09-09 17 to 19, and
the drawn table shows exactly that.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@VeryComplexAndLongName
VeryComplexAndLongName merged commit 1806701 into main Sep 10, 2026
9 checks passed
@VeryComplexAndLongName
VeryComplexAndLongName deleted the wip-date-is-one-day branch September 10, 2026 18:37
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.

1 participant