Skip to content

fix(hooks): count HH:MM memory.md rows so the stop reminder can clear - #64

Open
meketreve wants to merge 1 commit into
cytostack:mainfrom
meketreve:fix/semantic-summary-detection
Open

fix(hooks): count HH:MM memory.md rows so the stop reminder can clear#64
meketreve wants to merge 1 commit into
cytostack:mainfrom
meketreve:fix/semantic-summary-detection

Conversation

@meketreve

Copy link
Copy Markdown
Contributor

The bug

The stop hook prints this on every stop, forever, no matter how many summaries have been written:

ACTION REQUIRED: N files were modified this session but no semantic summary was written to memory.md. Append a one-line summary: | HH:MM | description | file(s) | outcome | ~tokens |

countSemanticEntries counts only rows starting with | YYYY-MM-DD, and nothing in the codebase writes rows in that shape:

where format
src/templates/OPENWOLF.md:41 documents | HH:MM | description | file(s) | outcome | ~tokens |
src/hooks/stop.ts:297 the reminder text asks for | HH:MM | ... |
src/hooks/stop.ts:197 the hook's own rows: `| ${timeShort()} | Session end: ...`
src/hooks/session-start.ts:147 sessions are delimited by ## Session: YYYY-MM-DD HH:MM

So the count is always 0. Following the reminder's own instructions can never satisfy its check — the agent writes a summary, the reminder fires again, and the loop repeats until someone reads the source.

The fix

Decide "today" from the enclosing ## Session: header instead of from the row, then count non-mechanical | HH:MM | rows inside today's block.

Two properties kept deliberately:

  • rows with an explicit | YYYY-MM-DD | prefix still count — nothing that already worked regresses;
  • rows from an earlier session still don't count — a naive "accept any HH:MM row" would break the check the other way, and the reminder would never fire again once memory.md had a single entry.

The mechanical-row filter is unchanged, so the hook's own Created / Edited / Multi-edited / Session end: / designqc: rows are still excluded.

Tests

New tests/semantic-entries.test.ts, in the style of tests/token-measurement.test.ts. Two cases fail on the old implementation and pass on the new one; the other four pass on both and pin the surrounding behaviour so this can't silently loosen:

case old new
HH:MM row inside today's session block ✖ 0 ✔ 1
stacked sessions — only today's rows counted ✖ 1 ✔ 2
mechanical rows ignored ✔ 0 ✔ 0
rows from an earlier session ✔ 0 ✔ 0
explicit | YYYY-MM-DD | row ✔ 1 ✔ 1
missing memory.md ✔ 0 ✔ 0

Verification

Linux (WSL2), Node 24:

  • node --test tests/*.test.ts32/32 pass
  • tsc --noEmit -p tsconfig.hooks.json → clean

Behaviour change is confined to countSemanticEntries; its only caller is checkSemanticSummaries in src/hooks/stop.ts, which is unchanged.

`countSemanticEntries` only counted rows starting with `| YYYY-MM-DD`, but
nothing writes rows in that shape:

- `src/templates/OPENWOLF.md` documents `| HH:MM | description | file(s) |
  outcome | ~tokens |`
- the stop-hook reminder itself asks for `| HH:MM | ... |` (stop.ts)
- the hook writes its own rows that way too (`| ${timeShort()} | Session end:
  ... |`, stop.ts)
- sessions are delimited by `## Session: YYYY-MM-DD HH:MM` headers
  (session-start.ts)

So the count was always 0 and the stop hook emitted "ACTION REQUIRED: N files
were modified this session but no semantic summary was written to memory.md" on
every single stop, no matter how many summaries the agent had written. Following
the reminder's own instructions could never satisfy its check.

Decide "today" from the enclosing `## Session:` header instead of from the row,
and count non-mechanical `| HH:MM |` rows inside today's session block. Rows with
an explicit `| YYYY-MM-DD` prefix still count, so nothing that already worked
regresses, and rows from an earlier session still don't — otherwise the reminder
would go the other way and never fire again once memory.md had any entry.

Tests cover both directions: the two new cases fail on the old implementation
(HH:MM row today, and stacked sessions) and the other four pass on both, pinning
the mechanical-row filter, the earlier-session boundary, the explicit-date path
and the missing-file path.

Verified on Linux (WSL2), Node 24: `node --test tests/*.test.ts` 32/32 and
`tsc --noEmit -p tsconfig.hooks.json` clean.
meketreve added a commit to meketreve/logica-em-jogo that referenced this pull request Jul 27, 2026
O aviso "no semantic summary was written to memory.md" repetia a cada stop
porque `countSemanticEntries` só conta linha `| YYYY-MM-DD` e nada escreve
nesse formato — o template, o texto do aviso e as linhas do próprio hook usam
`| HH:MM |`. Corrigido no pacote global (o `pnpm update -g` sobrescreve) e
mandado upstream: cytostack/openwolf#64.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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