18 Commits

Author SHA1 Message Date
Hermes
5993f260a2 docs(phase-1): capture dev notes from lore-engine-merge PRD
Moves the 'Dev Notes' sections from the lore-engine-merge PRD stories
(S2-phase-1-substrate-merge.md, S3-phase-2-ontology-time-planes.md)
into lore-engine-poc as documentation, since the lore-engine-merge
codebase is not yet bootstrapped as a separate working repo.

These notes document decisions made during the planned worker migration
from GraphMCP into the lore-engine stack:
- port remap 8765 → 8766 (damascus stack conflict)
- nsc plugin as single-file to match existing plugin convention
- discord-connector disabled via env var (per PRD ambiguity)
- multi-world ontology migration with defensive cleanup

When the lore-engine-merge codebase is bootstrapped, these notes can
be moved into docs/decisions/ there.
2026-06-27 16:53:17 +00:00
Hermes
ecd64883da Merge feat/p1-substrate-merge: Phase 1 substrate merge (S2) 2026-06-27 03:48:55 +00:00
Hermes
adbb6f0cce feat(substrate): Phase 1 merge — Redis + 8 Go workers + nsc plugin
Ports the GraphMCP-Example substrate into lore-engine-poc:

- 8 Go workers under workers/ (discord-connector, discord-filter, lore-watcher, ingestion-worker, entity-extractor, lore-extractor, encounter-processor, mcp-server), each with Dockerfile + go.mod

- 3 Go unit-test files (encounter-processor, ingestion-worker, lore-extractor) — other 5 workers rely on integration tests via the live stack

- plugins/nsc.py: thin httpx proxy from gateway to lore-mcp-server:9000, exposes all 11 inherited GraphMCP tools (input schemas verbatim from mcp-server/main.go)

- docker-compose.yml: adds lore-redis + lore-mcp-server + the 7 worker services (lore- prefix to avoid clash with other GraphMCP stacks)

- verify-merge.sh (171 LOC, 7 pass conditions) + docs/VERIFICATION.md

- tests/contract/test_graphmcp_tool_contracts.py (15 tests; skipped when stack is down — TDD pattern, becomes active once docker compose up brings the stack)

- README.md + test.sh updated for the merged service inventory

Leader notes (2026-06-27 03:50):

- Worker self-blocked review-required after 2 runs (run #7 hit 120/120 iteration budget; run #8 staged 40 files and reported shippable).

- Tests are SKIPPED until docker compose up — worker chose that pattern over mocking (consistent with the lore-engine-poc project convention). To activate, run `docker compose up -d --build && pytest tests/contract/`.

- File Scope reconciliation: story said gateway/plugins/nsc/__init__.py; worker shipped plugins/nsc.py (flat file). Justified by the existing plugins/ convention in lore-engine-poc (server.py glob("*.py")). A future PR could split nsc into a package once server.py learns __init__.py discovery.

- nsc plugin exposes 11 tools (not 8) — the AC said "8" but the worker enumerated all 11 tools present in mcp-server/main.go. The encounter-specific 3 tools (list_encounters, search_encounters, get_encounter) were included for consistency. Story AC #2 reads "≥ 8 GraphMCP tools" so this exceeds AC.

Refs: S2-phase-1-substrate-merge, milestone #64 P1 — Substrate merge
2026-06-27 03:48:54 +00:00
Kay
c27adc6713 Merge feat/p0-inventory: Phase 0 inventory (S1)
Worker shipped 20/20 tests green on first run. Inventory catalogs all 10 Go workers, 11 MCP tools, 4 Redis streams from the pinned GraphMCP-Example substrate (commit 064daa9). Closes story S1-phase-0-inventory.
2026-06-27 02:17:17 +00:00
hermes-agent
f62d6e8447 docs(merge): Phase 0 inventory — GraphMCP substrate catalog
Phase 0 of the lore-engine × GraphMCP merge (gate story S1).

- docs/merge/00-inventory.md: canonical catalog of every worker (10),
  MCP tool (11), and Redis stream (4) in the GraphMCP-Example substrate
  pinned at commit 064daa9. Each row includes env vars, streams read/
  written, Cypher queries emitted, LLM call sites, and source line refs
  in services/<worker>/main.go. Under the 500-line budget (450 lines).
- tests/test_inventory_completeness.py: TDD gate. 20 tests covering
  existence, line budget, name coverage, required attribute coverage,
  source path accuracy against the pinned checkout, and bidirectional
  cross-links. RED→GREEN: test_inventory_doc_exists failed with
  FileNotFoundError before the doc was written; all 20 pass now.
- meta/prd.md + planning-artifacts/architecture.md: mirrored from the
  lore-engine-merge-prds repo with a 'Phase 0' index link back to
  00-inventory.md appended, satisfying the cross-link acceptance
  criterion in the story.

Acceptance criteria from S1-phase-0-inventory.md: all 7 met.

Refs: lore-engine-merge-prds/_bmad-output/planning-artifacts/stories/S1-phase-0-inventory.md
2026-06-26 23:11:38 +00:00
Kay
c5030805e9 v2.T9: integration — T7 re-ran E2E suite, results updated against merged main 2026-06-17 01:21:59 +00:00
kanban-dev
99535a8f3a docs(v2): T8 — update README + CHANGELOG + 3 worked-example docs
- README.md: 5 plugins / 19 tools (matches /healthz); 'what this proves'
  now lists consistency engine, multi-world namespace, LLM consumer;
  'next steps' section replaced with 'shipped in v2'
- docs/CONSISTENCY_DEMO.md: 4 tools, 5 violations, all output verified
  against live bash examples/test_consistency.sh
- docs/MULTI_WORLD_DEMO.md: list_worlds() + entity_context in both
  worlds + cross-world isolation tests, all output verified live
- docs/LLM_CONSUMER_DEMO.md: 5 question types, 9 distinct tools, all
  output traced to examples/results/*.json
- CHANGELOG.md: v1 -> v2 entry, all 9 task refs (T1-T9)
- examples/test_e2e.sh: T7 E2E validation script (untracked)
2026-06-17 00:45:30 +00:00
Kay
bcda8eff00 Merge branch 'wt/t5-consistency-impl' into main
This merge also brings wt/t6-multi-world (4f92289) since T5 was rebased
on top of T6's namespace work.

Conflicts resolved (always took theirs — the implementation supersedes
the stub):
- README.md: updated 'What's not in this POC' to reflect that T5
  detection is now real, and marked T5 done in 'Next steps'
- plugins/consistency.py: T5's full 254-line implementation replaces
  T1's 153-line stub (find_contradictions / find_anachronisms /
  find_orphans / find_ontology_violations all backed by real Cypher)
2026-06-17 00:40:28 +00:00
Kay
7c3fa52ab5 Merge branch 'wt/t2-pgvector' into main
Resolved conflicts in neo4j/init.cypher and seed.py by taking theirs:
- neo4j/init.cypher: T2's version adds severity/status indexes on all 4
  violation types (T1 had them on Contradiction/Anachronism only)
- seed.py: T2 adds seed_embeddings() function for pgvector backfill
  on first run; HEAD removed it accidentally during T1 merge
2026-06-17 00:39:40 +00:00
Kay
07ebf260ac Merge branch 'wt/t1-gitea-push' into main
T1 — push v1 + open v2 milestone board (fab3321)
T3 — consistency plugin skeleton (8e8503e): 4 violation tools (find_contradictions, find_anachronisms, find_orphans, find_ontology_violations) + 4 Neo4j uniqueness constraints + severity/status indexes

Adds docs/SMOKE.md, scripts/ci-smoke.sh, .gitignore, .env.seed
2026-06-17 00:33:08 +00:00
Hermes
8261c2dcc1 v2.T5: implement 4 consistency tools — 5/5 violations surfaced
The 4 tools (find_contradictions, find_anachronisms, find_orphans,
find_ontology_violations) now read pre-materialized violation nodes
from Neo4j, populated by seed.py:seed_violations. The seed computes
the 5 hand-crafted violations from the same heuristics the design
calls for (overlapping MEMBER_OF windows, Person.born > event year,
orphaned entities, OntologyRule-driven checks) so the math is
visible in plain Python — not hidden in Cypher.

* plugins/consistency.py: 4 tools fully implemented; _severity_where
  helper moves the WHERE BEFORE the OPTIONAL MATCH in the ontology
  query (trailing WHERE on OPTIONAL MATCH rolls the optional row
  back to null when the predicate doesn't match, which broke the
  severity filter).
* seed.py: 5 violations pre-materialized (1 contradiction, 1
  anachronism, 1 orphan, 2 ontology) + 1 OntologyRule
  (persons_born_before_280_must_die). Rule id was normalized from
  'persons-born-before-280-must-die' to underscored form so it
  parses cleanly as a node id.
* examples/test_consistency.sh: 10 assertions across 4 tools
  (severity filter variants), exits 0.
* tests/test_consistency.py: 10 pytest cases — envelope shape,
  per-tool counts, severity filter, OntologyRule node presence.
* README.md: T5 marked done.

Verification:
  pytest tests/test_consistency.py     10/10 PASS
  bash examples/test_consistency.sh    10/10 assertions, exit 0
  bash test.sh                          no regressions, exit 0
2026-06-16 23:14:34 +00:00
Kay
4f922899af T6: multi-world namespace — world_id on every node, list_worlds(), arda_greyscale seed
Every read tool (entity_context, state_at, was_true_at, ancestors_of,
descendants_of, lineage_of, recall_images, search_images_by_caption,
register_image) now accepts an optional world_id parameter, defaulting
to 'default' so v1 callers see no change.

* Neo4j: every Person/Faction/Location/Item/Event/Lineage/Image node
  carries a world_id string property. seed.py backfills existing nodes
  to 'default' and writes a second minimal world 'arda_greyscale'
  (2 people, 1 faction, 1 location, 4 relations, 1 event, 1 era).
* Cypher: every MATCH in the world/lineage/images plugins filters by
  world_id on the right node type.
* New admin tool list_worlds() — runs
  MATCH (n) WHERE n.world_id IS NOT NULL RETURN DISTINCT n.world_id
  to expose the namespace.
* Postgres image_manifest gains a world_id column (init.sql).
* 4 placeholder images generated for the greyscale world (portraits of
  Mael and Sira, Ashen Hall, the Ashen Oath).
* test.sh now calls every tool with world_id='default' to verify v1
  behaviour, plus a new section 12 that calls list_worlds().
* tests/test_multi_world.py: 14 pytest cases covering list_worlds,
  entity_context/world isolation, was_true_at, state_at, lineage
  filter, image recall isolation, and the image_manifest schema.

Verification:
  pytest tests/test_multi_world.py         14/14 pass
  bash test.sh                             12/12 sections green,
                                           MinIO image bytes flow 200 OK
  list_worlds() returns [{arda_greyscale}, {default}]
2026-06-16 23:09:40 +00:00
Hermes
cfc555925d v2.T4: LLM consumer driving the 16-tool MCP gateway end-to-end
- examples/llm_consumer.py: raw httpx + urllib driver — discovers tools
  via tools/list, runs the tool-use loop against LiteLLM (minimax-m3), saves
  per-question JSON traces. No agent framework per task scope.
- examples/system_prompt.txt: 5 question types + tool protocol (per
  lore-engine/docs/07-reasoning-harness.md).
- examples/run_questions.sh: bash driver — exits 0 iff all 5 questions pass
  hand-verified correctness against the seed data.
- examples/results/*.json: traces from a real end-to-end run, all 5 PASS.
- examples/REPORT.md: per-question ground truth vs answer, with tool-call
  audit. The model used 9 distinct tools across 5 questions (requirement
  was >=4); every factual claim is grounded in a tool result; no
  fabrication.
2026-06-16 22:47:52 +00:00
Hermes
add264eb04 T2: pgvector image embeddings — plugin, schema, seed, hook, tests
- docker-compose: swap postgres image to pgvector/pgvector:pg16
- postgres/init.sql: CREATE EXTENSION vector; image_embedding table
- plugins/embeddings.py: embed_images + search_images_semantic
  (sentence-transformers all-MiniLM-L6-v2, lazy-loaded, pgvector <=> cosine)
- plugins/images.py: register_image kicks off background embed worker
- seed.py: seed_embeddings writes 4 embeddings for the mock images
- README: semantic image search section + T3 note
- 11 tests across 4 files, all green:
    test_embeddings_plugin.py (4): schema, ordering, idempotency, stub
    test_embeddings_real_model.py (3): real MiniLM, acceptance queries
    test_register_image_hook.py (2): manifest row, end-to-end hook
    test_seed_embeddings.py (2): writes 4, idempotent
- Includes T3 consistency plugin skeleton (4 stub tools)
2026-06-16 14:30:10 +00:00
kaykayyali
fab33213de docs(v2): T1 — push v1 + open v2 milestone board
T1 deliverables for the v2 iteration:
- .gitignore — keep __pycache__, .smoke-*.log, and editor noise out
- docs/SMOKE.md — single source of truth for bringing up the v1 stack
  from a fresh clone. Documents the 5-command path, expected output at
  each step, the CI runner, and a troubleshooting table.
- scripts/ci-smoke.sh — CI smoke runner. Brings the stack up, waits for
  all four services healthy, polls /healthz, idempotently seeds (skip
  if data already present), runs test.sh. Exits 0 on pass. Supports
  --keep-up and --skip-build for dev iteration. Shell-only because the
  Gitea instance has no Actions runner wired up yet — the script is
  the same shape a future Actions step will wrap.

Gitea milestones T1-T9 are created on kaykayyali/lore-engine-poc via
'tea milestones create'. See docs/SMOKE.md for the milestone → task
mapping (T7, T8 are deferred per the T9 integration task's body).

Verification:
- ./scripts/ci-smoke.sh --skip-build --keep-up  → SMOKE PASSED
  (12 v1 tools registered, 11/11 test.sh sections green)
- tea milestones list → all 9 milestones present

Co-located with the v1 baseline commit already on wt/t1-gitea-push
(commit 8e8503e adds the T3 consistency-skeleton plugin on top of v1;
that is T3's work, surfaced here only because T1, T2, T3 share a
single working dir). The T1 deliverables are additive: SMOKE.md,
ci-smoke.sh, .gitignore.
2026-06-16 14:23:31 +00:00
hermes
8e8503e8f9 T3: consistency plugin skeleton (4 violation tools, 4 Neo4j labels)
- plugins/consistency.py: find_contradictions, find_anachronisms, find_orphans,
  find_ontology_violations — all stub queries returning the
  {violations, count} envelope, ready for T5 to populate violation nodes.
  Two of the tools accept a severity filter (any|critical|major|minor).
- neo4j/init.cypher: uniqueness constraints on Contradiction, Anachronism,
  Orphan, OntologyViolation (id) + severity/status indexes on the
  contradiction/anachronism labels.
- README.md: bump plugin list to five, replace 'no consistency engine' copy
  with 'consistency engine is a stub', drop the two T3 bullet points from
  the next-steps section.

Verification: /healthz lists 18 tools (was 14), all 4 new tools return
{"violations": [], "count": 0}, full test.sh passes.
2026-06-16 14:21:48 +00:00
Kay
c1be608b34 checkpoint: import v1 baseline before T2 pgvector work 2026-06-16 14:11:19 +00:00
92a01884f5 Initial commit 2026-06-16 06:33:02 +00:00