MEMORY.md and TODO.md carry stale claims that actively misdirect agents #3

Closed
opened 2026-08-09 03:38:53 +02:00 by clawbot · 2 comments
Collaborator

Problem

MEMORY.md is the first thing agents are told to read, and three of its
statements are now false. Each one actively misdirects an agent working this
repo. TODO.md carries a fourth false claim.

1. MEMORY.md describes the gameEnd panic unwind, which was removed

MEMORY.md "Error handling":

> The game already unwinds C's exit() calls via a gameEnd panic recovered
> in Run.

Refactor step 8 deleted exactly this. Per TODO.md:

> The gameEnd panic unwind is gone: one game run is one process, so
> myExit restores the terminal (new Terminal.Fini) and calls
> os.Exit(0), and Run() no longer returns.

An agent reading MEMORY.md will believe it can let the game unwind and be
recovered. It cannot — the process exits, which is precisely why the
playtest tests need the fortify() HP-pinning helper.

2. MEMORY.md says lint exceptions live in the config; they do not

MEMORY.md "Linting":

> he approves specific exceptions, which are recorded in the config's
> "Repo-specific exceptions" block with the approval date.

The golangci-v2.12.2 work moved every exception out of the config into
targeted in-code //nolint directives, specifically so the config stays
byte-identical to canonical (verified: sha256
021cc83f4e6fc7c31b95b34b846723dfcf20b66b7baeea1dc40406e643346bcb). There is
no "Repo-specific exceptions" block in .golangci.yml any more. An agent
following MEMORY.md would edit the canonical config — the one thing the org
standard forbids outright.

MEMORY.md also still lists paralleltest as an approved disable
(2026-07-06), but it was actually fixed, not disabled — t.Parallel() was
added to all 32 tests.

3. MEMORY.md tells agents to run go test directly

MEMORY.md "Debugging":

> Write real, committed test files with t.Logf output and run plain
> go test -v

This contradicts the standing rule that only make targets / script/
entrypoints may be used, because they carry the project-specific flags and
policies that raw invocations silently bypass. This matters more once the
test: target gains -timeout/-race/-cover (#2) — a raw go test -v
would skip the race detector entirely.

4. TODO.md asserts a golangci-lint version that is not what runs

TODO.md:

> make lint runs the host golangci-lint, currently v2.12.2

The host linter on this machine is v2.10.1. The repo pins nothing, so this
line documents an accident of one machine at one moment, and it is already
wrong. (The pin question itself is tracked separately — this issue only asks
that the false claim stop being asserted.)

Definition of done

  1. MEMORY.md "Error handling" describes the current os.Exit/Terminal.Fini
    model, and notes the testing consequence (a death exits the test binary;
    see the fortify() pattern in the playtest tests).
  2. MEMORY.md "Linting" states that approved exceptions live in in-code
    //nolint directives carrying the approval date
    , and that .golangci.yml
    is byte-identical to canonical and must not be edited. The
    paralleltest entry is corrected from "disabled" to "fixed".
  3. MEMORY.md "Debugging" directs agents to the repo's make targets rather
    than raw go test.
  4. TODO.md no longer asserts a specific host linter version.
  5. make check green; make fmt run so the markdown is prettier-clean.
  6. Commit title ends with (closes #N).

Implementation requirements

  • Documentation-only. Zero changes to code, Makefile, .golangci.yml,
    or any config — if a change outside *.md seems necessary, stop and report.
  • Verify each claim against the code before rewriting it; do not simply
    paraphrase this issue. In particular, confirm the current exit path in the
    source rather than trusting this description.
  • Run make fmt and include the result in the same commit (prettier,
    4-space tabs, proseWrap: always).
  • Do not restate history that is already correct; keep the edits surgical.
## Problem `MEMORY.md` is the first thing agents are told to read, and three of its statements are now false. Each one actively misdirects an agent working this repo. `TODO.md` carries a fourth false claim. ### 1. `MEMORY.md` describes the `gameEnd` panic unwind, which was removed `MEMORY.md` "Error handling": > The game already unwinds C's `exit()` calls via a `gameEnd` panic recovered > in Run. Refactor step 8 deleted exactly this. Per `TODO.md`: > The `gameEnd` panic unwind is gone: one game run is one process, so > `myExit` restores the terminal (new `Terminal.Fini`) and calls > `os.Exit(0)`, and `Run()` no longer returns. An agent reading `MEMORY.md` will believe it can let the game unwind and be recovered. It cannot — the process exits, which is precisely why the playtest tests need the `fortify()` HP-pinning helper. ### 2. `MEMORY.md` says lint exceptions live in the config; they do not `MEMORY.md` "Linting": > he approves specific exceptions, which are recorded in the config's > "Repo-specific exceptions" block with the approval date. The `golangci-v2.12.2` work moved every exception **out** of the config into targeted in-code `//nolint` directives, specifically so the config stays byte-identical to canonical (verified: sha256 `021cc83f4e6fc7c31b95b34b846723dfcf20b66b7baeea1dc40406e643346bcb`). There is no "Repo-specific exceptions" block in `.golangci.yml` any more. An agent following `MEMORY.md` would edit the canonical config — the one thing the org standard forbids outright. `MEMORY.md` also still lists `paralleltest` as an approved disable (2026-07-06), but it was actually **fixed**, not disabled — `t.Parallel()` was added to all 32 tests. ### 3. `MEMORY.md` tells agents to run `go test` directly `MEMORY.md` "Debugging": > Write real, committed test files with `t.Logf` output and run plain > `go test -v` This contradicts the standing rule that only `make` targets / `script/` entrypoints may be used, because they carry the project-specific flags and policies that raw invocations silently bypass. This matters more once the `test:` target gains `-timeout`/`-race`/`-cover` (#2) — a raw `go test -v` would skip the race detector entirely. ### 4. `TODO.md` asserts a golangci-lint version that is not what runs `TODO.md`: > `make lint` runs the host `golangci-lint`, currently v2.12.2 The host linter on this machine is **v2.10.1**. The repo pins nothing, so this line documents an accident of one machine at one moment, and it is already wrong. (The pin question itself is tracked separately — this issue only asks that the false claim stop being asserted.) ## Definition of done 1. `MEMORY.md` "Error handling" describes the current `os.Exit`/`Terminal.Fini` model, and notes the testing consequence (a death exits the test binary; see the `fortify()` pattern in the playtest tests). 2. `MEMORY.md` "Linting" states that approved exceptions live in **in-code `//nolint` directives carrying the approval date**, and that `.golangci.yml` is byte-identical to canonical and must not be edited. The `paralleltest` entry is corrected from "disabled" to "fixed". 3. `MEMORY.md` "Debugging" directs agents to the repo's `make` targets rather than raw `go test`. 4. `TODO.md` no longer asserts a specific host linter version. 5. `make check` green; `make fmt` run so the markdown is prettier-clean. 6. Commit title ends with ` (closes #N)`. ## Implementation requirements - Documentation-only. **Zero** changes to code, `Makefile`, `.golangci.yml`, or any config — if a change outside `*.md` seems necessary, stop and report. - Verify each claim against the code before rewriting it; do not simply paraphrase this issue. In particular, confirm the current exit path in the source rather than trusting this description. - Run `make fmt` and include the result in the same commit (prettier, 4-space tabs, `proseWrap: always`). - Do not restate history that is already correct; keep the edits surgical.
Author
Collaborator

Scope addition, and a bump in priority.

Add a fifth item to the definition of done: README.md line 75 documents
running the suite as go test ./game/ directly. That is the same defect as
item 3 in this issue (MEMORY.md telling agents to run go test -v), and it
now has teeth: since PR #9 landed, make test carries
-timeout 30s -race -cover, so anyone following the README runs the suite
without the race detector and believes they have verified the change.

Fix it the same way — point at the make targets. Found by the reviewer on
PR #9 as observation O-2.

Priority bump: this issue is worth doing early. It stopped being
theoretical within the hour. The independent reviewer on PR #9 — who was
otherwise careful enough to prove -race was live by injecting a real data
race — stated in their review that the os.Exit paths "unwind through the
gameEnd panic recovered in Run". That is exactly the stale MEMORY.md
claim described in item 1 of this issue, and it is false: refactor step 8
removed the unwind.

It did not affect their verdict, because their conclusion rested on empirical
evidence rather than on that belief. But it is a clean demonstration that
these stale docs are actively propagating wrong mental models into the work,
which is precisely the harm this issue was filed to stop.

Definition of done is otherwise unchanged. Still docs-only, still eligible for
the docs-only fast path (no adversarial review, merge on green make check).

Scope addition, and a bump in priority. **Add a fifth item to the definition of done:** `README.md` line 75 documents running the suite as `go test ./game/` directly. That is the same defect as item 3 in this issue (`MEMORY.md` telling agents to run `go test -v`), and it now has teeth: since PR #9 landed, `make test` carries `-timeout 30s -race -cover`, so anyone following the README runs the suite **without the race detector** and believes they have verified the change. Fix it the same way — point at the `make` targets. Found by the reviewer on PR #9 as observation O-2. **Priority bump: this issue is worth doing early.** It stopped being theoretical within the hour. The independent reviewer on PR #9 — who was otherwise careful enough to prove `-race` was live by injecting a real data race — stated in their review that the `os.Exit` paths "unwind through the `gameEnd` panic recovered in `Run`". That is exactly the stale `MEMORY.md` claim described in item 1 of this issue, and it is false: refactor step 8 removed the unwind. It did not affect their verdict, because their conclusion rested on empirical evidence rather than on that belief. But it is a clean demonstration that these stale docs are actively propagating wrong mental models into the work, which is precisely the harm this issue was filed to stop. Definition of done is otherwise unchanged. Still docs-only, still eligible for the docs-only fast path (no adversarial review, merge on green `make check`).
Author
Collaborator

Implementation plan

Verified every claim against the tree at c922a16 before planning the rewrite.
Findings:

  1. gameEnd unwind — confirmed gone. grep -rn gameEnd --include=*.go
    returns nothing. The live exit path is game/rip.go:17myExit() calls
    g.scr.Fini() then os.Exit(0). Run() (game/game.go:205) is
    func (g *RogueGame) Run() with no return values and its own doc comment
    already says "It does not return". The testing consequence is real and
    already documented in-code at game/run_test.go:10-22 (fortify()) and
    :24-28 (driveTurns). MEMORY.md is the outlier.
  2. Lint exceptions — confirmed not in the config. .golangci.yml contains
    no "Repo-specific exceptions" block and no mention of paralleltest,
    testpackage, exhaustive, or mnd; its sha256 is
    021cc83f4e6fc7c31b95b34b846723dfcf20b66b7baeea1dc40406e643346bcb, matching
    the canonical hash cited in the issue. The approvals live in-code as
    file-level and line-level //nolint directives carrying "(approved
    2026-07-07)". paralleltest was fixed, not disabled: no paralleltest
    token exists anywhere in the Go sources, and the suite has 32 top-level
    func Test* against 32 t.Parallel() calls.
  3. Raw go test — confirmed harmful now. Makefile test: runs
    go test -timeout 30s -race -cover $(GO_PKGS) with the verbose-rerun
    failure path. A plain go test -v skips -race, -cover, and the timeout.
  4. Linter version — confirmed false. Host golangci-lint is 2.10.1,
    not v2.12.2, and nothing in the repo pins it.
  5. README.md:75 documents go test ./game/ — same defect as item 3.

Work, all on a temporary worktree off main, docs-only:

  • MEMORY.md "Error handling": replace the gameEnd-unwind sentence with the
    myExit / Terminal.Fini / os.Exit(0) model and the testing consequence
    (a death exits the test binary; drive command() directly and pin the hero
    with the fortify() pattern in game/run_test.go).
  • MEMORY.md "Linting": exceptions live in in-code //nolint directives
    carrying the approval date; .golangci.yml is byte-identical to canonical
    and must not be edited. Move paralleltest from the approved-disables list
    to a note that it was fixed with t.Parallel().
  • MEMORY.md "Debugging": point at make test / make check instead of
    go test -v, naming what the target carries.
  • README.md: replace go test ./game/ with the make targets.
  • TODO.md: drop the "currently v2.12.2" claim from the 2026-08-07 entry (the
    pin question itself is out of scope — tracked separately), and add a
    Completed Steps entry. Next Step is not rotated — out-of-band issue work
    leaves it alone (precedent from PR #9), and "broaden unit test coverage" is
    unfinished.
  • Explicitly not touching ARCHITECTURE.md (tracked in #16), and no
    non-.md file gets modified.

Then make fmt in the same commit, make check green, commit title ending
(closes #3), PR against main.

## Implementation plan Verified every claim against the tree at `c922a16` before planning the rewrite. Findings: 1. **`gameEnd` unwind — confirmed gone.** `grep -rn gameEnd --include=*.go` returns nothing. The live exit path is `game/rip.go:17` — `myExit()` calls `g.scr.Fini()` then `os.Exit(0)`. `Run()` (`game/game.go:205`) is `func (g *RogueGame) Run()` with no return values and its own doc comment already says "It does not return". The testing consequence is real and already documented in-code at `game/run_test.go:10-22` (`fortify()`) and `:24-28` (`driveTurns`). `MEMORY.md` is the outlier. 2. **Lint exceptions — confirmed not in the config.** `.golangci.yml` contains no "Repo-specific exceptions" block and no mention of `paralleltest`, `testpackage`, `exhaustive`, or `mnd`; its sha256 is `021cc83f4e6fc7c31b95b34b846723dfcf20b66b7baeea1dc40406e643346bcb`, matching the canonical hash cited in the issue. The approvals live in-code as file-level and line-level `//nolint` directives carrying "(approved 2026-07-07)". **`paralleltest` was fixed, not disabled**: no `paralleltest` token exists anywhere in the Go sources, and the suite has 32 top-level `func Test*` against 32 `t.Parallel()` calls. 3. **Raw `go test` — confirmed harmful now.** `Makefile` `test:` runs `go test -timeout 30s -race -cover $(GO_PKGS)` with the verbose-rerun failure path. A plain `go test -v` skips `-race`, `-cover`, and the timeout. 4. **Linter version — confirmed false.** Host `golangci-lint` is **2.10.1**, not v2.12.2, and nothing in the repo pins it. 5. **`README.md:75`** documents `go test ./game/` — same defect as item 3. Work, all on a temporary worktree off `main`, docs-only: - `MEMORY.md` "Error handling": replace the `gameEnd`-unwind sentence with the `myExit` / `Terminal.Fini` / `os.Exit(0)` model and the testing consequence (a death exits the test binary; drive `command()` directly and pin the hero with the `fortify()` pattern in `game/run_test.go`). - `MEMORY.md` "Linting": exceptions live in in-code `//nolint` directives carrying the approval date; `.golangci.yml` is byte-identical to canonical and must not be edited. Move `paralleltest` from the approved-disables list to a note that it was fixed with `t.Parallel()`. - `MEMORY.md` "Debugging": point at `make test` / `make check` instead of `go test -v`, naming what the target carries. - `README.md`: replace `go test ./game/` with the `make` targets. - `TODO.md`: drop the "currently v2.12.2" claim from the 2026-08-07 entry (the pin question itself is out of scope — tracked separately), and add a Completed Steps entry. **Next Step is not rotated** — out-of-band issue work leaves it alone (precedent from PR #9), and "broaden unit test coverage" is unfinished. - Explicitly **not** touching `ARCHITECTURE.md` (tracked in #16), and no non-`.md` file gets modified. Then `make fmt` in the same commit, `make check` green, commit title ending ` (closes #3)`, PR against `main`.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/rgoue#3