M4a task 14: post's comment was now_ms's; fixed, and every comment read

A script that rewrote the skeleton's comments put `now_ms`'s text on `post`. Task 14's second
session saw the contradiction and deliberated until cut off. Both comments are fixed, each
todo!() comment in tasks 14 and 15 was read beside its signature, and both tasks now say to stop
and quote a comment that does not fit. Lesson T29.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-24 00:40:05 -07:00
co-authored by Claude Opus 5.5
parent 564875f0a0
commit 02d5e25046
5 changed files with 19 additions and 3 deletions
+2
View File
@@ -65,6 +65,8 @@ How it is used:
| T27 | Every wait in a given test has a limit (`recv_timeout`, a deadline loop, `is_finished` before `join`). A test that waits forever on a broken implementation hangs the driver instead of failing, and the implementer cannot tell a hang from slowness. | M4a planning: breaking the reference's ping made `ws_conn` hang on `rx.recv()`; retrying a refused token made the serve test hang on `join()`. Both now fail within 5 s. | | T27 | Every wait in a given test has a limit (`recv_timeout`, a deadline loop, `is_finished` before `join`). A test that waits forever on a broken implementation hangs the driver instead of failing, and the implementer cannot tell a hang from slowness. | M4a planning: breaking the reference's ping made `ws_conn` hang on `rx.recv()`; retrying a refused token made the serve test hang on `join()`. Both now fail within 5 s. |
| T28 | Before hand-over, break the reference on purpose, one line at a time (drop a check, move a bound by one, skip a save), and run the given tests against each change. A change the tests still pass is a missing test, unless it cannot change behaviour. Rustfmt reflows lines: match on text that survives formatting. | M4a planning: 69 changes over six modules; the tests missed 8. Five were real gaps and got tests (a reconnect that re-sent "interrupted" for a running turn was one), two could not change behaviour, and one was left (an event frame with another id, which `loopd` never sends). | | T28 | Before hand-over, break the reference on purpose, one line at a time (drop a check, move a bound by one, skip a save), and run the given tests against each change. A change the tests still pass is a missing test, unless it cannot change behaviour. Rustfmt reflows lines: match on text that survives formatting. | M4a planning: 69 changes over six modules; the tests missed 8. Five were real gaps and got tests (a reconnect that re-sent "interrupted" for a running turn was one), two could not change behaviour, and one was left (an event frame with another id, which `loopd` never sends). |
| T29 | Check a skeleton's comments, not only its code. Print every `todo!()` beside its signature and read each pair before hand-over. Filling the bodies from your own code proves the split can pass; it cannot show that a comment sits on the wrong function. Edit comments by function, never by "the next comment after this name". And tell the implementer to stop and quote a comment that does not fit. | M4a task 14, second session: `post`'s comment was `now_ms`'s text, put there by a script; Ornith saw the contradiction and deliberated over it until the turn ran out. |
## What worked and should be kept ## What worked and should be kept
- Byte-exact fixtures, compared in both directions. No wire-format defect reached review. - Byte-exact fixtures, compared in both directions. No wire-format defect reached review.
+2
View File
@@ -107,6 +107,8 @@ never set.
## Stop and report if ## Stop and report if
- A comment above a `todo!()` does not fit its function, or contradicts a test. The comments were
written by hand and one was wrong before; stop at once and quote it, rather than guess.
- A test passes only sometimes, or a test takes 5 s or more (that is a wait that timed out, not a - A test passes only sometimes, or a test takes 5 s or more (that is a wait that timed out, not a
pass). pass).
- A written function (`run`, `connect`, `Gateway::new`, `event_loop`, `catch_up`) seems to need a - A written function (`run`, `connect`, `Gateway::new`, `event_loop`, `catch_up`) seems to need a
+1
View File
@@ -54,4 +54,5 @@ This is the last task of M4a. Stop after the commit.
## Stop and report if ## Stop and report if
- The comment above the `todo!()` does not fit the function, or contradicts a test: quote it.
- A test's output contains the token. - A test's output contains the token.
+9
View File
@@ -90,6 +90,15 @@ At the end of task 15: about 762 tests (650 before task 01).
checked in a scratch copy of the branch at task 14's start: the skeletons compile and fail checked in a scratch copy of the branch at task 14's start: the skeletons compile and fail
(`serve` 6, `serve_restart` 5 with 2 passing, `main` 4 with 1 passing), and filled from their (`serve` 6, `serve_restart` 5 with 2 passing, `main` 4 with 1 passing), and filled from their
comments they pass (five runs), clippy clean, gate ok. Resume from task 14. comments they pass (five runs), clippy clean, gate ok. Resume from task 14.
- 2026-09-24, task 14 again: this session copied the files and saw the tests fail, as told, then
deliberated until cut off, over a real contradiction: `post`'s comment was `now_ms`'s text.
The design model's script that rewrote the comments placed each after the first
eight-space comment following the function's name; `now_ms` is a free function with a
four-space comment, so its text went to `post`, and `post`'s was lost. The check filled the
bodies from the design model's own code, not from the comments, so it could not see this.
Both comments are fixed; every `todo!()` comment in tasks 14 and 15 was then read beside its
signature. Tasks 14 and 15 now say to stop and quote a comment that does not fit. The attempt is
saved in `.state/runs/M4a/14-second-attempt*`. Resume from task 14.
## Running it ## Running it
@@ -14,15 +14,17 @@ use crate::ws::conn::Ws;
/// Now, in Mattermost's milliseconds. /// Now, in Mattermost's milliseconds.
fn now_ms() -> i64 { fn now_ms() -> i64 {
// Milliseconds since the Unix epoch as i64, with try_from (i64::MAX if it does not fit). // `let ms = SystemTime::now().duration_since(UNIX_EPOCH).map(|d| d.as_millis()).unwrap_or(0);`
// then `i64::try_from(ms).unwrap_or(i64::MAX)`.
todo!() todo!()
} }
impl Gateway { impl Gateway {
/// Post in a thread; a failure is logged, not fatal. /// Post in a thread; a failure is logged, not fatal.
pub(super) fn post(&self, channel: &str, root: &str, text: &str) { pub(super) fn post(&self, channel: &str, root: &str, text: &str) {
// `SystemTime::now().duration_since(UNIX_EPOCH).map(|d| d.as_millis()).unwrap_or(0)`, then // `if let Err(e) = self.client.create_post(channel, root, text)`: log
// `i64::try_from(ms).unwrap_or(i64::MAX)`. // "gatewayd: cannot post in <channel> (thread <root>): <e>", with `(self.log)(&line)`.
// Nothing else: posting records nothing in the state.
todo!() todo!()
} }