Skip to content

refactor(aidd-context): clean the memory engine and fix what real refreshes showed - #1195

Merged
blafourcade merged 10 commits into
nextfrom
refactor/memory-engine-clean
Nov 11, 2026
Merged

blafourcade merged 10 commits into
nextfrom
refactor/memory-engine-clean

Conversation

@blafourcade

Copy link
Copy Markdown
Contributor

Summary

Cleanup and fixes to the project memory engine, each found on a real refresh (gouvernail, kairos-app, this framework) and re-checked on the same data.

  • Engine dispatch: main() was a 96-line chain of ifs; each command is now a function in one table, and the usage line is built from it.
  • Tests: the skill-files suite matched sentences with regexes; it now checks behaviour only (templates pass the engine, capability table matches the templates, engine paths match the real installs, every engine command the skill names exists). Closes test(aidd-context): check the project memory skill's behaviour, not its sentences #1192.
  • Plan: the chat gets counts by verb and the path to plan.md; plan.md holds each item numbered, with its verb, every line whole and a path:line link. A reply takes a range (not 5-12).
  • Lost lines: on a real refresh, 24 of 25 lines flagged lost were wrapped prose rewritten as lists, or paths an approved move rewrote; one was real (a dropped number). A line is now lost when a word that carries a fact (a number, a path, code, a word of six letters or more) is held fewer times across the bank. On that refresh: no false alarm, the real loss still caught. An approved move is read on both sides, so a move not yet made loses nothing.
  • Placement: the root loads every session, internal/ and external/ on demand; where a file sits is the team's choice. A capability file in internal/ is no longer reported misplaced (a real refresh moved 35,000 on-demand words into every session); an always-written file kept on demand counts as present.
  • Engine lookup: found from the skill's own folder, never another copy in the project.
  • Report: a folder of more than three written files reads as one entry.

Limits

  • A change of one short word (three to four) is not flagged lost; it stays visible as a plan item.
  • A model that does not find the engine can still skip the report; the turn-end hook still lists losses.

Test plan

  • node scripts/check-tests-leave-git-alone.js -- node --test 'scripts/__tests__/**/*.test.js': 2069 pass
  • Each new guard has a mutation that turns its test red
  • Real refresh runs (Sonnet, clones without remotes): gouvernail, kairos-app, framework

🤖 Generated with Claude Code

https://claude.ai/code/session_01RY5w5aeGrLa7U4uNXpujGQ

blafourcade and others added 8 commits November 11, 2026 10:00
…e table

main was one 96-line chain of ifs. Each command is now its own function,
listed with its usage in one table; main looks it up, and the usage line
is built from the same table.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RY5w5aeGrLa7U4uNXpujGQ
…ts sentences

Closes #1192. The skill-files suite matched sentences of the skill with
exact regexes, so any rewording broke it with no behaviour changed. What
stays runs the engine or the file tree: the templates pass the engine,
the capability table matches the templates, the lint command fails a
planted marker, the engine paths match the real installs, the skill's
markdown is table-first. New: every engine command the skill names is
one the engine accepts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RY5w5aeGrLa7U4uNXpujGQ
…ole of it in a file

On a real refresh the plan quoted 70-word paragraphs and showed no verb.
The chat now gets one line per item, its verb in a column (write, add,
change, move, remove) and the quoted line cut short; plan.md beside the
sheet holds every line whole with a path:line link. A reply takes a
range: not 5-12.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RY5w5aeGrLa7U4uNXpujGQ
… by its wrapping

On a real refresh, 24 of 25 lines flagged lost were a wrapped paragraph
rewritten as a list, or paths an approved move rewrote; one was a real
loss. A line is now lost when a word that carries a fact (a number, a
path, code, or a word of six letters or more) is held fewer times across
the bank: one such word, two words, or every word it had. An approved
move rewrites its paths first. On that refresh: no false alarm, and the
real loss, a dropped number, is still caught.

Limit: a change of one short word (three to four) is not flagged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RY5w5aeGrLa7U4uNXpujGQ
…er of files in the report

The chat gets the change count by verb and the path to plan.md; plan.md
leads each item with its number and verb, then every line whole. The
report names a folder of more than three written files once.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RY5w5aeGrLa7U4uNXpujGQ
…ne from the skill

A real refresh approved a move it had not made yet: the old paths still on
disk read as lost. In a repository that holds its own copy of the plugin,
the model found that copy's older engine by file name.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RY5w5aeGrLa7U4uNXpujGQ
The root loads every session, internal/ and external/ on demand: where a
file sits is the team's choice. A capability file in internal/ was
reported misplaced, and a real refresh moved 35,000 words of on-demand
files into every session. Only a folder no loading rule reaches is still
reported, and an always-written file kept on demand counts as present.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RY5w5aeGrLa7U4uNXpujGQ
@blafourcade
blafourcade requested a review from a team as a code owner November 11, 2026 11:08

/** Where the quoted line sits in its bank file, as `path:line`, or null. */
function locate(root, file, quoted) {
if (quoted === null) return null;
blafourcade and others added 2 commits November 11, 2026 12:32
… as a lost fact

On jq and fzf, refreshes left stale table rows in place: a fact could not
hold a pipe, so no line could quote a row. A sheet line is now read from
both ends, the fact taking what lies between. A heading left empty by
approved removals was flagged lost: a heading holds no fact.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RY5w5aeGrLa7U4uNXpujGQ
On jq, a refresh removed a whole table with approval and its header row
read as lost. Like a heading, a header holds no fact.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RY5w5aeGrLa7U4uNXpujGQ
@blafourcade
blafourcade merged commit f23d853 into next Nov 11, 2026
33 checks passed
@blafourcade
blafourcade deleted the refactor/memory-engine-clean branch November 11, 2026 16:40
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.

2 participants