Summary
Tools/KnowledgeHarvester.ts writes harvest output directly into KNOWLEDGE/People/, KNOWLEDGE/Companies/, etc. — but KNOWLEDGE/README.md and the architecture summary describe a _harvest-queue/ curation gate that should sit between auto-harvest and committed knowledge:
"KNOWLEDGE/ is curated and structured. Entries follow a frontmatter contract... Harvesters elsewhere in MEMORY/ propose candidates that get promoted into here only after curation."
— MEMORY/KNOWLEDGE/README.md
The _harvest-queue/ pattern is also referenced in PAISystemArchitecture.md and the Memory pipeline section: Tools/SessionHarvester.ts --mine → KNOWLEDGE/_harvest-queue/.
But in practice, KnowledgeHarvester.ts skips the queue and promotes directly:
✅ Ideas/design-provider-abstraction-layer-for-swappable-services.md
✅ Companies/worktree-sprint-security-perf-decompose-quick-wins.md
✅ People/fix-n1-queries-and-add-code-splitting.md
The third entry is plainly miscategorized — "Fix N+1 queries" is an Ideas-class technical idea, not a Person. Without the queue, it lands in KNOWLEDGE/People/ where it pollutes the entity graph until the user manually moves it.
Repro
- Run
bun KnowledgeHarvester.ts harvest against any session corpus that includes mixed-domain content (technical work, person mentions, company references).
- Inspect the output paths — they go straight into
KNOWLEDGE/<domain>/ based on the harvester's classification heuristics.
- Inspect classification quality — TYPE_KEYWORDS at line ~58-65 is a small fixed keyword list; misclassifications are common.
- Result: low-quality candidates land in committed KNOWLEDGE/ with no human review step.
In my MemberOS harvest of 10 ISAs:
- 3/5 entries plausibly classified (Ideas/Companies)
- 2/5 entries questionable (1 misclassified as People, 1 marginally a Company)
- All landed in committed
KNOWLEDGE/ directly
Why the gate matters
KNOWLEDGE/ is the system's curated long-term memory — what MemoryRetriever.ts reads, what KnowledgeGraph.ts navigates, what the Pulse /knowledge dashboard surfaces, what semantic search in MemoryRetriever keys against. Pollution here propagates downstream into every consumer of the graph. The _harvest-queue/ is the proposed-vs-canonical boundary; bypassing it makes the entire knowledge graph as good as the harvester's classification heuristics, which the existing keyword-list approach explicitly is not.
Suggested fix
Two-line change in the harvest write path:
// Currently:
const outputDir = path.join(KNOWLEDGE_DIR, candidate.domain);
// Proposed:
const outputDir = path.join(KNOWLEDGE_DIR, "_harvest-queue", candidate.domain);
Plus a small companion CLI verb to promote:
bun KnowledgeHarvester.ts promote <slug> # move queue entry into KNOWLEDGE/<domain>/
bun KnowledgeHarvester.ts promote-all --domain Ideas # promote all Ideas candidates
bun KnowledgeHarvester.ts reject <slug> # delete from queue
bun KnowledgeHarvester.ts review # interactive curation TUI
Promotion preserves the harvested_from: provenance frontmatter that already exists.
The README's curation language already implies this UX — implementation just hasn't caught up.
Migration concern
Users with existing KNOWLEDGE/<domain>/ populated by current direct-write behavior shouldn't lose anything on the change. Suggested compatibility: existing entries stay where they are; _harvest-queue/ only catches new candidates. No backfill needed.
Verified locally
Confirmed direct-write behavior on MemberOS harvest run. The _harvest-queue/ directory does not exist and is never created by current code path. The README's claim that harvest "propose[s] candidates that get promoted into here only after curation" does not match implementation.
Related
- Companion issue: KnowledgeHarvester is single-PAI-instance; per-project memory dirs invisible without
PAI_DIR override (filed separately).
Summary
Tools/KnowledgeHarvester.tswrites harvest output directly intoKNOWLEDGE/People/,KNOWLEDGE/Companies/, etc. — butKNOWLEDGE/README.mdand the architecture summary describe a_harvest-queue/curation gate that should sit between auto-harvest and committed knowledge:The
_harvest-queue/pattern is also referenced inPAISystemArchitecture.mdand the Memory pipeline section:Tools/SessionHarvester.ts --mine→KNOWLEDGE/_harvest-queue/.But in practice, KnowledgeHarvester.ts skips the queue and promotes directly:
The third entry is plainly miscategorized — "Fix N+1 queries" is an Ideas-class technical idea, not a Person. Without the queue, it lands in
KNOWLEDGE/People/where it pollutes the entity graph until the user manually moves it.Repro
bun KnowledgeHarvester.ts harvestagainst any session corpus that includes mixed-domain content (technical work, person mentions, company references).KNOWLEDGE/<domain>/based on the harvester's classification heuristics.In my MemberOS harvest of 10 ISAs:
KNOWLEDGE/directlyWhy the gate matters
KNOWLEDGE/is the system's curated long-term memory — whatMemoryRetriever.tsreads, whatKnowledgeGraph.tsnavigates, what the Pulse/knowledgedashboard surfaces, what semantic search inMemoryRetrieverkeys against. Pollution here propagates downstream into every consumer of the graph. The_harvest-queue/is the proposed-vs-canonical boundary; bypassing it makes the entire knowledge graph as good as the harvester's classification heuristics, which the existing keyword-list approach explicitly is not.Suggested fix
Two-line change in the harvest write path:
Plus a small companion CLI verb to promote:
Promotion preserves the
harvested_from:provenance frontmatter that already exists.The README's curation language already implies this UX — implementation just hasn't caught up.
Migration concern
Users with existing
KNOWLEDGE/<domain>/populated by current direct-write behavior shouldn't lose anything on the change. Suggested compatibility: existing entries stay where they are;_harvest-queue/only catches new candidates. No backfill needed.Verified locally
Confirmed direct-write behavior on MemberOS harvest run. The
_harvest-queue/directory does not exist and is never created by current code path. The README's claim that harvest "propose[s] candidates that get promoted into here only after curation" does not match implementation.Related
PAI_DIRoverride (filed separately).