Skip to content

Cross-campaign registry: accumulate knowledge across campaigns #272

@susiejojo

Description

@susiejojo

Problem

After #270 (merged in #271), /post-campaign extracts structured knowledge from each campaign into ~/.nous/wiki/campaigns/<name>/. But each campaign's data is isolated — there's no way to:

  1. See which entities (code components) were studied across multiple campaigns
  2. Query what's known about a specific subsystem without manually opening each campaign's files
  3. Deduplicate entities that appear under slightly different names in different campaigns
  4. Identify which areas have dense coverage vs. which are unexplored

The extracted knowledge compounds in value when it's cross-referenced, but right now it's just a flat collection of per-campaign directories.

Desired Outcome

An /index-wiki Claude skill that takes a campaign name, reads its extracted files (from ~/.nous/wiki/campaigns/<name>/), and merges them into a single ~/.nous/wiki/registry.json — a cross-campaign routing index.

The registry should:

  • Track entities across campaigns (same code module studied from different angles gets one entry with multiple campaign references)
  • Deduplicate entities by normalized name (case-insensitive, strip parentheticals)
  • Assign globally-unique IDs to all items (E-1, C-1, P-1, DE-1, F-1, I-1)
  • Group entities into semantic clusters by functional role (e.g., "Saturation Detection", "Request Routing")
  • Nest concepts, parameters, principles, dead-ends, frontiers, and interactions under their source campaign (knowledge only makes sense in the context of the research question that produced it)

The registry is a lean routing index — it stores names and IDs, not full definitions. Full detail stays in the per-campaign files. Downstream skills (/suggest-next, /visualize-registry) will read the registry to find what's relevant, then load detail from per-campaign files.

Constraints

  • This is the only skill that writes to registry.json — clear ownership, no write conflicts
  • Idempotent: running on an already-indexed campaign is a no-op
  • Append-only: never modifies existing campaign entries, only adds new ones
  • Entity clusters are recomputed on each run (the only field that gets replaced, not appended)
  • No script dependencies — pure LLM logic (read JSON, reason about dedup, write JSON)
  • No modifications to existing orchestrator code

Inputs

Reads from ~/.nous/wiki/campaigns/<name>/ (produced by /post-campaign):

  • concepts.json — contains repo_path, system_name, research_question, plus entities/concepts/parameters
  • principles.json — principle IDs
  • dead-ends.json — refuted approaches
  • frontiers.json — boundary conditions
  • interactions.json — untested combinations

Output

Writes ~/.nous/wiki/registry.json with this structure:

{
  "version": 1,
  "projects": {
    "<repo_path>": {
      "name": "<system name>",
      "campaigns": [{ "name", "date", "research_question", "concepts", "parameters", "principles", "dead_ends", "frontiers", "interactions" }],
      "entities": [{ "id", "name", "aliases", "campaigns" }],
      "entity_clusters": [{ "id", "label", "entities" }]
    }
  }
}

Context

See Discussion #269 for how this fits into the broader persistence strategy. This is PR 2 of 4 — it enables the downstream /suggest-next and /visualize-registry skills.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions