11 Commits

Author SHA1 Message Date
Lore Engine Dev
2367960540 slice 7.1: 50-question reasoning harness test set
Per docs/plan/exec/07-harness.md sub-slice 7.1:

  - tests/harness/questions.yaml — the human-friendly
    YAML source. 50 questions across the 5 design-doc
    types (10 each): identity, time_fact, world_state,
    causal, narrative. Each question pins id, type,
    query, expected_tools, expected_answer_shape, and
    expected_citations. Targets the Mardonari codex
    (the slice 0 fixture) so the harness can run
    end-to-end against the real graph.
  - tests/harness/questions.json — the compiled JSON
    (committed so the runner reads it without rebuilding).
  - scripts/harness/build_questions.py — the strict
    compiler. Validates the YAML schema, counts questions
    per type, enforces uniqueness, writes the JSON.
    Validation errors fail loudly with field paths.
  - tests/harness/test_questions.py — 6 tests pinning the
    contract: schema, 50 total, 10 per type, expected_tools
    non-empty, ids unique, version set.

Track A only (no API key needed). Track B (executing
against the live LLM) is gated on $OLLAMA_API_KEY.

Suite: 761 → 767 (+6).

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-19 20:51:18 -04:00
Lore Engine Dev
f88616ed89 slice 6.6: Region↔Plane migration (script + 9 tests)
Adds the slice 6.6 migration as a library helper
(lore_engine_poc.migration: scan_codex_for_planes /
apply_plane_migration) plus a thin CLI wrapper at
scripts/05_migrate_planes.py.

Discriminator: frontmatter signals — plane: true,
tags contains plane, OR type: plane — promote an
entry to :Plane. Default Material Plane convention
remains mardonari.material (added by the 6.4
backfill). Idempotent: re-running on the same codex
produces the same graph state.

LAYER_OF edges are created only between co-referenced
Planes (markdown body [[X]] → Plane node X). Direction
follows docs/17-planes.md: (:Plane A)-[:LAYER_OF]->
(:Plane B) where A is the layer and B is the parent.
In the voldramir fixture, Voldramir(demiplane) LAYER_OF
Underdark(plane).

The script supports --dry-run (print planned changes,
exit 0) and --codex / --setting overrides.

Suite: 747 → 756 tests (+9). No regressions.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-19 15:12:20 -04:00
Lore Engine Dev
fbf6c9668e slice 5.7: LORE_GRAPH_BACKEND env var in MCP entry scripts
Both MCP entry scripts (05_mcp_server.py for stdio and
06_mcp_http_server.py for Streamable HTTP) now select their
graph backend at startup through a shared loader
(scripts/mcp_server_entry.load_graph):

  * LORE_GRAPH_BACKEND=pickle (default) — load the
    .graph.pkl built by 01_ingest.py.
  * LORE_GRAPH_BACKEND=neo4j — connect to Neo4j at
    $LORE_NEO4J_URI (default bolt://127.0.0.1:7687) and
    load the mirrored graph.
  * Anything else — clear error and exit 4.

Exit codes:

  * 0: graph loaded (only happens if the caller ignores
    the sys.exit() call below and treats load_graph() as
    non-throwing — for the supported backends, load_graph
    returns normally).
  * 1: pickle path missing.
  * 2: neo4j_graph not importable.
  * 3: neo4j unreachable.
  * 4: unknown backend value.

Neo4jGraph.__init__ now eagerly calls verify_connectivity()
so the loader fails loudly at startup rather than on the
first query — the driver pool opens sockets lazily otherwise,
and the first session.run would be too late for the
entry scripts to log a clear error.

Refactors:

  * scripts/05_mcp_server.py: removed inline _load_graph(),
    now imports from scripts.mcp_server_entry.
  * scripts/06_mcp_http_server.py: same.
  * lore_engine_poc/neo4j_graph.py: Neo4jGraph.__init__
    eagerly verifies connectivity.

Tests:

  * tests/test_mcp/test_backend_switch.py — 5 docker-gated
    tests (pickle default, neo4j up, neo4j down exits 3,
    garbage backend exits 4, trivial registry works with
    both backends).

Suite: 624 -> 629 passed (+5 backend-switch tests, all 559
baseline + 38 Neo4j + consistency + ingest + backend-switch
tests preserved).
2026-06-18 23:10:08 -04:00
Lore Engine Dev
299ad5c146 slice 5.6: 01_ingest.py --write-neo4j dual-write flag
After the in-memory graph + pickle are written, the new flag
mirrors the full graph into the Neo4j 5 container at
$LORE_NEO4J_URI (default bolt://127.0.0.1:7687). The flag
is opt-in (default off) so the existing test suite's
invocations of 01_ingest.py without Docker still work.

The mirror logic:

  * Pre-pass for LoreSource nodes (full metadata via
    add_lore_source so SOURCED_FROM links find them with
    name, source_type, reliability, source_confidence).
  * Pre-pass for bare names (entities registered without
    any edge participation — keeps :Entity count in sync
    with in-memory all_names()).
  * Then the edges, add()-ed one by one.

Failure semantics:

  * Neo4j unreachable at startup → log + exit 3.
  * neo4j_graph not importable → log + exit 2.
  * Pickle is always written before the mirror attempt, so
    a flaky Neo4j container never loses the in-memory state.

Consistency runner stability:

  _detect_contradictions Pattern 2 (same object, different
  subjects) now sorts the two claims alphabetically so
  claim_a / claim_b are stable across runs. The
  graph.all_names() set iteration order is otherwise
  non-deterministic across Python processes and across
  the in-memory / Neo4j backends, and the original
  dict-iteration insertion order broke when slice 5.4
  migrated to all_names().

Tests:

  * tests/test_scripts/test_ingest_neo4j.py — 5 docker-gated
    tests (exits zero, entity count, relation count,
    default-off untouched, fails loud on unreachable URI).
  * tests/test_consistency/test_runner_categories.py — one
    test updated to assert claim_a/claim_b as a set rather
    than a specific order (matches the runner's new
    lexicographic-sort contract).

Suite: 619 -> 624 passed (+5 ingest-neo4j tests, all 559
baseline + 32 Neo4j + consistency + ingest tests preserved).
2026-06-18 23:01:35 -04:00
Lore Engine Dev
451325503e scripts/06: streamable HTTP MCP server entry (slice 11.3)
* scripts/06_mcp_http_server.py: uvicorn entry. Mirrors
  05_mcp_server.py's _load_graph() shape. CLI flags --host,
  --port, --log-level. Env overrides LORE_GRAPH_PATH,
  LORE_HTTP_HOST, LORE_HTTP_PORT. Single-process only; multi-worker
  is intentionally not exposed (graph is in-memory per-process and
  write tools do not persist).
* tests/test_mcp/test_scripts_06.py: 7 subprocess tests booting
  on LORE_HTTP_PORT=0 (OS-assigned) and parsing the bound port
  from the 'Uvicorn running on' line. Tests 1-5: initialize,
  tools/list (36), was_true_at, SSE, notification 202. Test 6:
  SIGTERM exits 0 or -SIGTERM (no traceback). Test 7: missing
  graph exits non-zero with the expected error message.
  543 -> 550 green.
2026-06-18 14:07:10 -04:00
Lore Engine Dev
29f7b89d53 slice 3.4+3.5: 01_ingest.py LORE_INGEST_LLM wiring + smoke script (8/8 + manual)
- 01_ingest.py: LORE_INGEST_LLM=1 enables LLM extraction after the
  deterministic path; build_graph is now called AFTER LLM triples
  merge in (the 3.4 ordering fix).
- LORE_INGEST_FAKE_LLM=1 + LORE_INGEST_FAKE_LLM_SCRIPT=path selects
  FakeProvider for offline/CI runs.
- Missing OLLAMA_API_KEY degrades gracefully: stderr warning, rc=0,
  deterministic graph still built (no crash, no LLM triples).
- scripts/06_llm_smoke.py: one-shot manual smoke for the real
  Ollama Cloud provider; loads one NPC, runs extractor, prints
  triples. Skips (rc=0, helpful message) when OLLAMA_API_KEY unset.
- FakeProvider gains dict-style {match_any, response} / {match_any,
  raise} entries so tests can skip exact-prompt matching when the
  body is large.
- tests/test_extraction/test_ingest_wiring.py: 8 subprocess tests
  covering default-off, enabled, idempotency (x2), adds-fact,
  provider-failure tolerance, bad-JSON tolerance, and missing-key
  fallback.
- tests/fixtures/llm_empty_script.json: [] (used by the enabled-
  path test where no triples are expected).

435/435 tests pass (was 382 pre-slice; +53). End-to-end ingest with
--skip-cognee runs cleanly on default-off path.
2026-06-18 11:27:52 -04:00
Lore Engine Dev
482c6adde5 slice 2.6.3+2.6.4: stdio subprocess tests + scripts/05_mcp_server.py entry (10+7 tests; 382/382 total; stdlib JSON-RPC 2.0 MCP server) 2026-06-18 10:13:56 -04:00
Lore Engine Dev
6510e767c6 slice 4: 16 read tools + 3 write tools + Graph reverse indexes (92/92 tests; 341/341)
- Graph reverse indexes (slice 4.0): edges_by_object (O(1) reverse lookups)
  and entities_by_type (type-filtered queries) added to lore_engine_poc/tools.py
- responses.py (slice 4.1): shared edge_to_fact / entity_summary / envelope
  helpers — single source of truth for tool response shape
- read_tools.py (slice 4.2-4.6): 16 read tools across 5 groups
  - Group 1: lookup, entity_context
  - Group 2: true_during, entities_present, timeline (state_at deferred to 4.6+)
  - Group 3: list_lineage, list_offspring, ancestors_of, descendants_of,
    location_hierarchy
  - Group 4: event_chain, events_during
  - Group 5: lore_about (cite deferred to 4.7+)
- write_tools.py (slice 4.7): 3 minimal world-builder tools
  (add_entity, add_relation, add_lore_source) with allowlist + envelope
- scripts/02_demo.py: now exercises every read tool + write/read round-trip
- 92 new tests (7 graph_indexes + 7 responses + 10 group1 + 15 group2 +
  19 group3 + 11 group4 + 7 group5 + 16 write_tools). 341/341 green.

Excluded: state_at (composes 4 tools + consistency engine), summarize_chain
+ narrate_arc (LLM-required), cite (vector store), and Group 8 write tools
beyond the 3 minimal — all deferred per slice 4 plan.
2026-06-18 09:41:02 -04:00
Lore Engine Dev
96563bc912 slice 2.5: 04_consistency.py script + demo wiring (4/4 tests; AC 2.4)
- scripts/04_consistency.py: standalone on-demand run of the consistency
  engine over the seed codex; prints summary + per-category detail
- scripts/02_demo.py: append consistency section using the singleton
  consistency_tools path so 'latest_run()' agrees with the run summary
- tests/test_consistency/test_consistency_script.py: 2 tests (end-to-end
  run + --codex flag)
- tests/test_consistency/test_demo.py: 2 tests (end-to-end run + --query
  flag exercises the consistency section)
- 249/249 tests pass
2026-06-18 02:56:47 -04:00
Lore Engine Dev
b0cc840e3e slice 1.7: seed/yaml + ingest walks structured path; demo exercises time filter; integration tests prove AC 1.11 (85/85 green) 2026-06-18 01:03:12 -04:00
Lore Engine Dev
40880735ec slice 0: time-aware query POC on Cognee (was_true_at, 13/13 time_model, 11/11 confidence) 2026-06-18 00:13:08 -04:00