feat(aidd-context): rebuild project-memory as three actions, verified on both hosts#442
Merged
Conversation
The memory skill carried five actions, four of them a step wearing an action's coat, and a SKILL.md that listed the references its own actions already point at. Rebuild the router on the onboard anatomy: a linear scan -> generate -> sync mermaid, a three-verb table, and the line that makes the skill run on a host that reads only SKILL.md. Scan detects the tools and takes the user's pick, so no tool is ever wired without being chosen. One tools.md carries detection and the context-file path, since both are keyed by tool. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Clients running Codex and Copilot got their core memory written into a core/ or internal/ subfolder. The old action forbade it in prose, inside a step, and the prose lost to the template tree's own shape. A nested memory file is not auto-loaded, so the project silently lost the memory it thought it had. Give every template an exact destination in a table. The capability folder gates which rows generate and never enters a path. Generate reads the destination instead of deriving it. Generate now also scaffolds and reviews, folding two actions that were each a single step. The review fans out to readers that did not write the file, and says so when the host cannot give it any. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sync could not create a context file, so a project whose tool had none was told to go make one first. And the fill script wrote into every context file it found, including an AGENTS.md the user never chose. Sync now owns the context file end to end: it creates a missing one from the template, upserts the block, then fills it. The script takes the picked tools and fills only theirs. Called with no tool, it still fills every file present, which is what the auto hook wants. It refuses a tool it does not know rather than filling nothing and reporting success. It never inserts a block. A hand-written AGENTS.md with no block stays as its author left it, unless its tool is picked. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Delete the five old actions and the AI map, now carried by three actions and tools.md. Fix docs/CATALOG.md, stale for project-memory and for onboard, whose rework renamed its actions and never told the catalog. Verified by running it, not by reading it. Both hosts were synced to this branch first: their caches held 2.2.0 and its old actions, so an unsynced run would have passed for the wrong reason. Claude and Codex each walked scan -> generate -> sync and wrote nine flat memory files. Codex's hand-written AGENTS.md, which had no block at all, got the section, the block, and the fill, and kept its own line. Neither host touched a tool the user had not picked. The review found real defects a writer cannot see in its own draft: a dependency declared and never imported, and an architecture diagram drawing edges the code does not have. The no-subagent review fallback stays unproven. Both hosts have subagents. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… is used Scan asked which AI tools you use before a single memory file existed, a leftover of the design where the context file came first. The answer was only ever consumed by sync, three steps later, and holding it there made the whole pipeline all-or-nothing: wiring a new tool into a project that already had its memory meant regenerating that memory. Move the tool pick to sync, which now detects, asks, and wires on its own. A detected tool is offered ticked, so adding codex cannot silently unwire claude and leave its block to rot. Scan gains the guard it never had: memory records what exists, so a project with no code, no INSTALL.md and no PRD is told to go make something first, rather than handed six hollow files that its own rules forbid. Proven by running it. Sync alone wired codex into a memory it did not write, refreshed claude's block, and left all nine memory files byte for byte. An empty repo stopped at Ground and wrote nothing. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The templates changed shape three times in the past month. A file generated from an older one silently kept that shape: generate refreshed its content from the code and never looked at its sections, so a section the template gained was never mentioned. The bank reported itself up to date while missing a section it was supposed to have. Generate now compares the template's sections to the file's. It reports what is missing and injects nothing, the same rule already applied to a nested file. A version field would have been the cheaper-looking fix and the wrong one. It has to be bumped by hand, so a forgotten bump makes the drift invisible, and it has to live in the generated file, which the AI loads every session, so every project would pay tokens forever for a check that fires three times a month. Sections are derived from what is actually there, cost no field, and cost no tokens. The noise it does not make matters as much as the drift it finds: a section left out because the project has nothing to put there stays unmentioned. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
SKILL.md carried two rule blocks and called both transversal. Only one was. The six rules about what a memory file holds have exactly one consumer, generate, so every action paid for them, including sync, which writes no memory at all and can now run alone. They were also said twice: three of the review protocol's four axes restated them from the reviewer's side. Now they have one home. Generate writes against it, the reviewers judge against it, sync never loads it. Also stop the fill script from staging when the skill calls it. Staging is right for the auto hook, which owns no other change. Called after generate has written eight files the script knows nothing about, it staged its own two and left an index that read like the whole change was ready to commit. SKILL.md drops from 349 to 229 tokens. Both hosts still apply the rules from behind the reference: no placeholder, no version in a tech name, memory pointing at the code instead of copying it. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…t can see Two ways the skill reached outside itself. It named skills from other plugins. Scan sent an empty project to aidd-pm:03-prd, and the review protocol called for aidd-dev:checker by name. A plugin that may not be installed is not a dependency a worker skill gets to have, and the review, the part that had to work, was the one hard-wired to a neighbour. Both now say what they need in plain words. Claude still found its checker on its own and ran nine independent reviewers, which caught the same dependency-declared-but-never-imported bug as before. The behaviour survived the decoupling. Scan also grounded itself on AIDD's own artefacts, an INSTALL.md or a spec under aidd_docs/, as if a project could only exist inside the ecosystem. It now looks for source code, or anything written that says what the project is. The Test sections restated the rules they sat under: "scan never asks about AI tools" is the rule, not a way to find out whether it held. They now name what can be observed once the action has run: a find that comes back empty, a file at an exact path, an exit code, an unstaged working tree. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A file-by-file pass over the skill with the maintainer. Each reference now carries only what no table or action already says: tools.md keeps two rules the columns cannot express, capability-signals drops the files column (it lived in memory-destinations) and the monorepo row (codebase-map's job), memory-destinations is a plain mapping, memory-rules lists a memory file's properties, review-protocol is a numbered protocol addressed to the reviewer and now catches dead commands, invented rationale, and omissions. memory-block.md is deleted: the block's shape lives in assets/AGENTS.md and its fill in the script, so sync's upsert points at the template and needs no separate reference. A new structure.md fixes the scaffold tree; a new report.md shapes generate's report like onboard. The actions gain what the review surfaced: scan splits the empty-project stop from detection, generate splits Write from Prune and Review from Fix and reports through the asset, sync gains a Require guard and offers to reconcile a context file drifted from the template. SKILL.md's description leads with the project, not the plumbing, and the mermaid shows both entries. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…rose updateMarkers anchored on the first open tag. A user who quotes `<aidd_project_memory>` in hand-written prose above the real block turned that mention into the cut point, splicing out every line between it and the block on the next fill. Anchor on the close tag, then take the nearest open before it. The real block is always the open closest to its own close, so a marker quoted above is never chosen. Proven on the exact case plus the normal, no-block, and hook paths. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The database template shipped an erDiagram, which is a restated schema the migrations already hold. Replace it with an optional domain diagram: the aggregate roots the schema does not show, gated to non-obvious cases. auth and deployment are the most flow-shaped concerns and had no diagram. Give each an optional, gated flow: the login-to-session path, the pipeline stages, drawn only when non-trivial and never a derivable schema or tree. The memory README shows how the bank loads as a mermaid instead of prose, and its maintenance rules now match memory-rules.md rather than drifting. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The hook derived every skill's argument-hint from its action file names. That fits a loop, but not a router whose actions are not all entry points: project-memory's generate never runs alone, and a user thinks in cases (set up, refresh, re-wire), not action names. Add a manual list the hook leaves untouched, so a skill can hand-write a case-based hint. project-memory is the first, its hint now `setup | refresh | rewire`. This is the base for any case-based router to come. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…roof The plan gains the decisions taken during the file-by-file review, the smoke test records ten fixtures verified on disk across both hosts, and the session report is the map of what changed and why. Notes the one asymmetry: independent review is real on Claude, an honest self-pass on Codex, accepted. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ebuild # Conflicts: # plugins/aidd-context/skills/02-project-memory/actions/02-scaffold-docs.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #417
Rebuilds
02-project-memoryon the onboard anatomy: five actions become three (scan → generate → sync), each asking its own question when the answer is used.What changed
aidd-dev:checkeragents, degrading to an honest fresh-context self-pass where a host has no subagents.argument-hintnames the user's cases (setup | refresh | rewire) via a new manual-hint exemption in the shared hook — the base for any case-based router.A shared-hook change rides along
scripts/sync-skill-argument-hints.mjsgains aMANUAL_ARGUMENT_HINTlist so a skill can hand-write a case-based hint. Repo-wide mechanism, additive, flagged for review.Verified in execution
Ten headless fixtures, both hosts, every claim read off disk — 31/31. See
aidd_docs/tasks/2026_07/2026_07_13_project-memory-rebuild/smoke-test.md. One asymmetry, accepted: independent review is real on Claude, an honest self-pass on Codex (codex execspawns no subagents).Not proven
Accepting a Prune removal or a reconcile: headless offers but cannot answer, so only the decline path is proven.
Follow-up ticket
Wire
node --testinto CI, then unit-testupdate_memory.js(updateMarkers,resolveTargets).🤖 Generated with Claude Code