Problem
silk check --watch can compile an intermediate file image when a non-atomic save takes longer
than one second.
The watcher correctly waits for two equal source-tree fingerprints, but it caps that wait at 40
samples spaced 25 ms apart. When the cap expires, it returns the last fingerprint even if the tree
is still changing. A slow writer can therefore leave a source file truncated or partially written
when compilation begins.
This is product behavior, not only a flaky test: shell redirection, sed -i, and editors without
atomic save can expose the same open(O_TRUNC) → write → close sequence.
Current behavior
The settle loop is effectively:
sample tree
repeat 40 times:
wait 25 ms
sample tree
if unchanged: compile
compile the last sample anyway
The final line runs after about one second even when every sample changed.
A file that previously contained:
pub fn main() -> i32 { return 42 }
may temporarily be observed as empty or as a prefix while the replacement is still being written.
Watch mode can compile that intermediate state and publish diagnostics that do not describe any
completed save.
Expected behavior
A finite non-atomic save must be compiled only after the complete file image settles, even when the
writer takes longer than one second.
An intentionally empty completed file remains a valid edit and must still compile. The watcher
therefore cannot solve this by rejecting every zero-length file.
A source tree rewritten continuously forever must not block the watch loop without a defined policy.
The implementation may use an adaptive deadline, writer-progress detection, or another bounded
strategy, but it must distinguish a finite slow save from an edit stream that never settles.
Required cases
Slow finite save
- Start from a non-empty valid Silk file.
- Truncate it.
- Write the replacement in several chunks over more than one second.
- Close the writer.
Watch mode must compile the complete replacement and must never compile an empty or partial prefix.
Intentional empty save
Truncate the file and finish the save without writing bytes. After the tree settles, watch mode must
compile the empty file exactly once and report its ordinary diagnostics.
Continuous rewrites
Keep changing the file without a settled interval. Watch mode must follow one documented bounded
behavior and remain responsive to interruption; it must not claim that an arbitrary mid-write
snapshot is a completed save.
Evidence
packages/compiler-cli/src/Workflow.ts defines settleInterval = '25 millis' and
settleSamples = 40.
settledFingerprint returns the last changing fingerprint after the loop rather than a distinct
“not settled” result.
packages/compiler-cli/test/Workflow.test.ts already performs 200 non-atomic writes and rejects
any observed source outside the set of complete programs, but its timing is load-dependent.
Acceptance criteria
Problem
silk check --watchcan compile an intermediate file image when a non-atomic save takes longerthan one second.
The watcher correctly waits for two equal source-tree fingerprints, but it caps that wait at 40
samples spaced 25 ms apart. When the cap expires, it returns the last fingerprint even if the tree
is still changing. A slow writer can therefore leave a source file truncated or partially written
when compilation begins.
This is product behavior, not only a flaky test: shell redirection,
sed -i, and editors withoutatomic save can expose the same
open(O_TRUNC) → write → closesequence.Current behavior
The settle loop is effectively:
The final line runs after about one second even when every sample changed.
A file that previously contained:
may temporarily be observed as empty or as a prefix while the replacement is still being written.
Watch mode can compile that intermediate state and publish diagnostics that do not describe any
completed save.
Expected behavior
A finite non-atomic save must be compiled only after the complete file image settles, even when the
writer takes longer than one second.
An intentionally empty completed file remains a valid edit and must still compile. The watcher
therefore cannot solve this by rejecting every zero-length file.
A source tree rewritten continuously forever must not block the watch loop without a defined policy.
The implementation may use an adaptive deadline, writer-progress detection, or another bounded
strategy, but it must distinguish a finite slow save from an edit stream that never settles.
Required cases
Slow finite save
Watch mode must compile the complete replacement and must never compile an empty or partial prefix.
Intentional empty save
Truncate the file and finish the save without writing bytes. After the tree settles, watch mode must
compile the empty file exactly once and report its ordinary diagnostics.
Continuous rewrites
Keep changing the file without a settled interval. Watch mode must follow one documented bounded
behavior and remain responsive to interruption; it must not claim that an arbitrary mid-write
snapshot is a completed save.
Evidence
packages/compiler-cli/src/Workflow.tsdefinessettleInterval = '25 millis'andsettleSamples = 40.settledFingerprintreturns the last changing fingerprint after the loop rather than a distinct“not settled” result.
packages/compiler-cli/test/Workflow.test.tsalready performs 200 non-atomic writes and rejectsany observed source outside the set of complete programs, but its timing is load-dependent.
Acceptance criteria
compilation of an empty or partial image.
promptly.