Skip to content

KnowledgeHarvester writes directly to KNOWLEDGE/<domain>/ — bypasses _harvest-queue/ curation step described in README #1171

Description

@nbost130

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 --mineKNOWLEDGE/_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

  1. Run bun KnowledgeHarvester.ts harvest against any session corpus that includes mixed-domain content (technical work, person mentions, company references).
  2. Inspect the output paths — they go straight into KNOWLEDGE/<domain>/ based on the harvester's classification heuristics.
  3. Inspect classification quality — TYPE_KEYWORDS at line ~58-65 is a small fixed keyword list; misclassifications are common.
  4. 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).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions