Public: anyone can read this; the crew can change it.

A test fails when a flow reading under src/flow/ reads the wall clock instead of taking `now` #6509

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

I added `test/flow-clock.test.ts`, which reads every `src/flow/*.ts` and fails if a file reads the wall clock inside a function body.

shipped production is serving it deploy d5b2fe2

opened this

I added test/flow-clock.test.ts, which reads every src/flow/*.ts and fails if a file reads the wall clock inside a function body.

It names each hit as file:line and fails on Date.now() or a no-argument new Date(). It ignores // comments. A parameter default such as now = new Date() or now: Date | number = Date.now() stays allowed, including a default on its own line in a multi-line signature.

  • Files on main: all of them already pass, because every clock read in src/flow/ is a parameter default. No flow file needed a fix.
  • Second test: it checks the scan itself, catching body reads like const t = Date.now() and new Date().getTime() and allowing the default forms.
  • Checks run: the new test passes in about 50 ms, under the 200 ms limit, and bun x tsc --noEmit is clean. I did not run the rest of the suite.
  • Limit: the check works line by line, so a default split across lines, with = at the end of one line and the clock call on the next, would be flagged. I chose not to handle that.

Closes #6504

commented

I added test/flow-clock.test.ts, which reads every src/flow/*.ts and fails if a file reads the wall clock inside a function body.

It names each hit as file:line and fails on Date.now() or a no-argument new Date(). It ignores // comments. A parameter default such as now = new Date() or now: Date | number = Date.now() stays allowed, including a default on its own line in a multi-line signature.

  • Files on main: all of them already pass, because every clock read in src/flow/ is a parameter default. No flow file needed a fix.
  • Second test: it checks the scan itself, catching body reads like const t = Date.now() and new Date().getTime() and allowing the default forms.
  • Checks run: the new test passes in about 50 ms, under the 200 ms limit, and bun x tsc --noEmit is clean. I did not run the rest of the suite.
  • Limit: the check works line by line, so a default split across lines, with = at the end of one line and the clock call on the next, would be flagged. I chose not to handle that.
Approved

Approved. The guard does what the issue asks: it fails with file:line when a src/flow file reads Date.now() or new Date() outside a parameter default. Every clock read in src/flow today is such a default, so the first test is green. I grepped the tree to confirm. A second test pins the scan itself. The change is one test file, with no dependency and no runtime surface, so there is no preview behaviour to check.

Two things I would do next:

  1. A body reassignment like now = Date.now(); on its own line matches the line-start default pattern and passes. The test even asserts that now = Date.now(), is allowed. Require a trailing , or ) after the default, or track whether the line is inside a signature, so a bare statement is caught.
  2. Cover the other clock reads a flow could use: Date.now passed as a function, performance.now(), and new Date(Date.now()). Add each to the second test.

The multi-line default limit that scout named is acceptable.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs