refactor: delegate StateManager knowledge loading to KnowledgeTracker (plan 010)#79
Merged
Merged
Conversation
StateManager contained a complete second implementation of knowledge-file
loading (scanKnowledgeFiles + its own cache + dir resolution) that had diverged
from KnowledgeTracker.loadKnowledgeFiles — most importantly, the StateManager
copy did NOT run ${env.*}/${config.*} interpolation. Researcher (the only
production consumer of the StateManager copy) therefore saw raw
${env.PASSWORD} text while Navigator, TaskAgent, ExperienceTracker and commands
saw interpolated content for the same page.
Delete the copy and delegate to KnowledgeTracker (the CLAUDE.md single owner of
the knowledge dir), sharing one tracker instance from Explorer. Make the tracker
scan recursively (superset of both implementations), invalidate its isLoaded
cache on addKnowledge (so a same-instance /learn read sees the write), and unify
the two divergent Knowledge types onto one exported interface.
Intended behavior deltas: the 30s rescan is gone (in-app writes picked up via
addKnowledge invalidation), recursive scan now applies to every consumer, and
Researcher now receives interpolated knowledge.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…r/knowledge-single-owner
…taleness) Deleting StateManager's knowledge scanner (which rescanned every 30s) left the shared KnowledgeTracker caching forever; addKnowledge's isLoaded invalidation is per-instance, so /learn (which builds its own tracker) and hand-edited files were never picked up by Explorer's shared instance until restart — and CLAUDE.md's documented "30-second refresh" existed nowhere. Restore the refresh in the single owner: loadKnowledgeFiles re-scans when the cache is older than 30s (KNOWLEDGE_REFRESH_MS), so on-disk changes from any source reach every consumer. Same-instance addKnowledge still forces an immediate reload via isLoaded=false. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This was referenced Jul 12, 2026
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.
Implements plan 010 (
plans/010-delegate-statemanager-knowledge.md) — a P1 bug + dedup refactor.Problem
StateManagerhad a second implementation of knowledge loading (scanKnowledgeFiles+ its own cache + dir resolution) that had diverged fromKnowledgeTracker.loadKnowledgeFiles:${env.X}/${config.X}interpolationThe only production consumer of the StateManager copy is Researcher — so Researcher saw raw
${env.ADMIN_PASSWORD}literal text while every other agent saw interpolated content for the same page. This also violated CLAUDE.md's Code Ownership Map ("Reading/writing./knowledge+ var interpolation →KnowledgeTrackeronly").Fix
scanKnowledgeFiles,knowledgeCache,lastKnowledgeScan,knowledgeDir) and delegategetRelevantKnowledge()to the sharedKnowledgeTracker. Explorer now constructs the tracker first and injects it (CLAUDE.md shared-instance rule).KnowledgeTracker.loadKnowledgeFilesscan recursively (superset of both).addKnowledgenow setsisLoaded = falseso a same-instance read (the/learncommand) sees what it just wrote — a secondary bug.Knowledgetypes onto one exported interface (re-exported from state-manager for back-compat).Verification
addKnowledge-invalidation test (knowledge-tracker.test.ts), and an interpolation-through-StateManager regression (state-manager.test.ts) — confirmed it fails on the old code (returns literal${env.SM_TEST_VAR}) and passes now.bun test tests/unit→ 731 pass, 0 fail;bun test tests/integration/researcher.test.ts→ 8 pass;bun run lintclean.Intended behavior deltas (per plan)
30s rescan removed (in-app writes picked up via
addKnowledgeinvalidation; hand-edited files mid-session no longer auto-detected); recursive scan now applies to all consumers; Researcher now receives interpolated knowledge.🤖 Generated with Claude Code