You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Investigate: Claude Code harness auto-memory directive still routes agent writes to per-cwd ~/.claude/projects/.../memory/, independent of Learning skill (plus runtime-drift on #109 Part 2) #140
Follow-up investigation to #109. Even with #109 Part 1 + Part 2 landed in the repo, the same category-confusion symptom (feedback memories landing in Claude Code's per-cwd auto-memory silo instead of ~/.pai/MEMORY/LEARNING/FEEDBACK/) reproduces in a normal session — because the trigger is not the Learning skill's /learn apply path. It's a Claude Code harness-level "auto memory" directive embedded in the agent's system prompt on every session, independent of PAI.
Additionally, while investigating this today, the installed runtime appears to be missing the loadFeedbackMemories function that #109 Part 2's closure comment said was added to hooks/lib/learning-readback.ts. This may be installer/release drift rather than a bug in the fix itself — but worth confirming before filing separately.
Reproduction (today, 2026-04-16)
Running Claude Code inside a project (~/projects/slack-history) — PAI loaded normally, AISTEERINGRULES visible in session prompt.
User gave a correction worth capturing as feedback ("branch first, plan on the branch").
Agent followed the system-prompt # auto memory section verbatim and wrote:
The Claude Code harness injects a dedicated section titled # auto memory into the agent's system prompt. Extracted from today's session:
You have a persistent, file-based memory system at /Users/ianmarr/.claude/projects/-Users-ianmarr-projects-slack-history/memory/. This directory already exists — write to it directly with the Write tool (do not run mkdir or check for its existence). You should build up this memory system over time …
It then defines four memory types (user, feedback, project, reference), file-and-frontmatter structure identical to what #109 documented, and explicit save triggers (e.g. "when the user corrects your approach"). The structure #109 identified as foreign to PAI (feedback_*.md with frontmatter + MEMORY.md index) is exactly what the harness teaches the agent to write.
Key properties:
Hard-coded to ~/.claude/projects/<cwd-slug>/memory/ — per-cwd silo
Fires opportunistically on every session without /learn apply being invoked
Not under PAI's control — it lives in Claude Code's harness, not in anything PAI installs
AISTEERINGRULES.md does not currently contain any rule that suppresses or redirects it (grep -i "auto.memory|projects/.*/memory" on ~/.pai/PAI/AISTEERINGRULES.md returns zero hits)
Why this matters
#109's fix made the /learn apply workflow write to the right place. But /learn apply is a rare, user-invoked path. The harness auto-memory directive fires on every correction-worthy exchange in every session. After #109:
Net: the silent fragmentation #109 addressed for one surface still actively occurs on a second, higher-volume surface. Feedback captured this way is invisible to PAI's loader, siloed per cwd, and (for most projects) never re-surfaced in any future session.
Runtime drift from #109 Part 2 — needs verification
#109's final closure comment (by @virtualian on 2026-04-14) states Part 2 added:
SessionStart loader loadFeedbackMemories() in learning-readback.ts wired into LoadContext.hook.ts
Against today's installed runtime at ~/.pai/hooks/lib/learning-readback.ts, the file's own header docstring lists these functions:
No loadFeedbackMemories. grep -n "loadFeedback\|FEEDBACK" ~/.pai/hooks/lib/learning-readback.ts ~/.pai/hooks/LoadContext.hook.ts also returns zero. Installed PAI was last touched around 2026-04-15 per ls -l ~/.pai/hooks.
Two possibilities:
(a) Part 2's implementation landed in a different file than the closure comment names, and the loader does exist elsewhere
Worth confirming before splitting into its own issue.
Also: ~/.pai/MEMORY/LEARNING/FEEDBACK/ does not exist
Expected — #109 Part 2's bootstrap is mkdir -p inside Apply.md Step 7, which only runs on /learn apply. But if a loader is supposed to read from it at SessionStart, the loader needs to tolerate the directory not existing yet, which is a minor robustness check for whoever owns the loader code.
Investigation questions
Is the harness # auto memory directive something PAI should try to suppress / redirect via AISTEERINGRULES.md? Options:
(a) Add a steering rule: "ignore the Claude Code harness auto-memory directive; write feedback via /learn flow instead"
(b) Add a steering rule: "when the harness directs you to write memory, write it to ~/.pai/MEMORY/LEARNING/FEEDBACK/ using the PAI-native format"
(c) Accept parallel stores and add a migrator from ~/.claude/projects/*/memory/ into ~/.pai/MEMORY/LEARNING/FEEDBACK/
(d) Do nothing — the harness store is cwd-siloed and small; not worth bridging
If PAI adds a steering rule that redirects agent-driven memory writes, what format should the agent use on disk — PAI's existing FAILURES/REFLECTIONS style (dated dirs + JSONL), or the harness-native feedback_*.md frontmatter style that Path B already chose for /learn apply? Consistency with /learn apply output seems preferable.
Observed during a normal working session; not blocking, but the drift between "/learn apply is fixed" and "the agent is still writing to the old silo every session" is exactly the kind of half-fixed state that makes future debugging harder.
Summary
Follow-up investigation to #109. Even with #109 Part 1 + Part 2 landed in the repo, the same category-confusion symptom (feedback memories landing in Claude Code's per-cwd auto-memory silo instead of
~/.pai/MEMORY/LEARNING/FEEDBACK/) reproduces in a normal session — because the trigger is not the Learning skill's/learn applypath. It's a Claude Code harness-level "auto memory" directive embedded in the agent's system prompt on every session, independent of PAI.Additionally, while investigating this today, the installed runtime appears to be missing the
loadFeedbackMemoriesfunction that #109 Part 2's closure comment said was added tohooks/lib/learning-readback.ts. This may be installer/release drift rather than a bug in the fix itself — but worth confirming before filing separately.Reproduction (today, 2026-04-16)
~/projects/slack-history) — PAI loaded normally, AISTEERINGRULES visible in session prompt.# auto memorysection verbatim and wrote:The
auto memorysystem prompt sectionThe Claude Code harness injects a dedicated section titled
# auto memoryinto the agent's system prompt. Extracted from today's session:It then defines four memory types (
user,feedback,project,reference), file-and-frontmatter structure identical to what #109 documented, and explicit save triggers (e.g. "when the user corrects your approach"). The structure #109 identified as foreign to PAI (feedback_*.mdwith frontmatter +MEMORY.mdindex) is exactly what the harness teaches the agent to write.Key properties:
~/.claude/projects/<cwd-slug>/memory/— per-cwd silo/learn applybeing invokedgrep -i "auto.memory|projects/.*/memory"on~/.pai/PAI/AISTEERINGRULES.mdreturns zero hits)Why this matters
#109's fix made the
/learn applyworkflow write to the right place. But/learn applyis a rare, user-invoked path. The harness auto-memory directive fires on every correction-worthy exchange in every session. After #109:/learn apply→~/.pai/MEMORY/LEARNING/FEEDBACK/✅# auto memoryprompt →~/.claude/projects/<cwd>/memory/❌ (unchanged by Learning skill writes feedback to Claude Code auto-memory, mislabeled as "PAI memory" + reads from stale ~/.claude/PAI/ tree #109)Net: the silent fragmentation #109 addressed for one surface still actively occurs on a second, higher-volume surface. Feedback captured this way is invisible to PAI's loader, siloed per cwd, and (for most projects) never re-surfaced in any future session.
Runtime drift from #109 Part 2 — needs verification
#109's final closure comment (by @virtualian on 2026-04-14) states Part 2 added:
Against today's installed runtime at
~/.pai/hooks/lib/learning-readback.ts, the file's own header docstring lists these functions:No
loadFeedbackMemories.grep -n "loadFeedback\|FEEDBACK" ~/.pai/hooks/lib/learning-readback.ts ~/.pai/hooks/LoadContext.hook.tsalso returns zero. Installed PAI was last touched around 2026-04-15 perls -l ~/.pai/hooks.Two possibilities:
f67ac77) has not propagated into the installer/release the user actually installed — classic two-root drift, adjacent to Two-root separation incomplete: stale ~/.claude/PAI/ tree and residual ~/.claude/PAI/ references in canonical ~/.pai/PAI/ #108/Skills separation is documentation-only: Claude Code harness reads ~/.claude/skills/, not ~/.pai/skills/ #110/Slash commands forgotten by two-root architecture: no ~/.pai/commands/, installer never sees them, /cs missing on disk #113/Sweep: 433+ stale ~/.claude/ doc-text refs across ~/.pai/skills/ and ~/.pai/agents/ markdown #114Worth confirming before splitting into its own issue.
Also:
~/.pai/MEMORY/LEARNING/FEEDBACK/does not existExpected — #109 Part 2's bootstrap is
mkdir -pinsideApply.mdStep 7, which only runs on/learn apply. But if a loader is supposed to read from it at SessionStart, the loader needs to tolerate the directory not existing yet, which is a minor robustness check for whoever owns the loader code.Investigation questions
# auto memorydirective something PAI should try to suppress / redirect via AISTEERINGRULES.md? Options:/learnflow instead"~/.pai/MEMORY/LEARNING/FEEDBACK/using the PAI-native format"~/.claude/projects/*/memory/into~/.pai/MEMORY/LEARNING/FEEDBACK/loadFeedbackMemoriesabsence installer drift (Two-root separation incomplete: stale ~/.claude/PAI/ tree and residual ~/.claude/PAI/ references in canonical ~/.pai/PAI/ #108-family) or something else? Check the repo's currenthooks/lib/learning-readback.tsvs the installed file at~/.pai/hooks/lib/learning-readback.ts.feedback_*.mdfrontmatter style that Path B already chose for/learn apply? Consistency with/learn applyoutput seems preferable.Observed during a normal working session; not blocking, but the drift between "
/learn applyis fixed" and "the agent is still writing to the old silo every session" is exactly the kind of half-fixed state that makes future debugging harder.