Skip to content

fix(inference): remove ghost bridge and unowned KB rule loading - #232

Merged
cryptoxdog merged 4 commits into
mainfrom
claude/cognitive-engine-graphs-pack-lrx6cy
Aug 23, 2026
Merged

fix(inference): remove ghost bridge and unowned KB rule loading#232
cryptoxdog merged 4 commits into
mainfrom
claude/cognitive-engine-graphs-pack-lrx6cy

Conversation

@claude

@claude claude Bot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Problem

engine/inference_bridge.py was a tombstone module that raised ImportError on
import while directing every caller to engine.inference_bridge_v2.DerivationGraph
and docs/migration/inference_bridge_v2.md. Neither exists in this repository —
verified at base e155f873: no engine/inference_bridge_v2.py, no docs/migration/
directory at all. The module advertised a successor protocol that was never built.

Separately, engine/startup_wiring.py executed load_domain_rules(spec.kb) for every
domain, but DomainSpec (engine/config/schema.py) declares no kb field. Had that
recipe ever run it would have raised AttributeError.

Root cause

A historical gap-fix bundle left authoritative-looking compatibility and raw-KB
integration artifacts behind. Neither was ever incorporated into the canonical
GraphLifecycle / DomainPackLoader runtime, so both survived as false authority
rather than as working code.

Fix

  • delete the ghost inference-bridge tombstone
  • remove the dead spec.kb / load_domain_rules recipe block and the stale bridge comment
  • remove the raw-dictionary rule loader (load_domain_rules, _register_condition_rule)
  • add focused anti-regression coverage

All built-in @register_inference_rule functions and the execute_rule() registry
boundary are preserved unchanged. InferenceContext.domain_kb is retained as
optional caller-supplied tuning context (infer_material_grade_from_mfi still reads
it); only the claim that a domain spec injects it is removed.

Architecture

DomainSpec + DomainPackLoader remain the single typed owner of domain
configuration. engine.inference_rule_registry.InferenceResult remains the supported
registry result contract. No successor bridge, NaryFact schema, YAML-to-fact adapter,
generic result type, or parallel inference engine is introduced — this PR only removes
dead code and false authority.

Verification performed on this branch

Reverse-import trace at base e155f873:

  • engine.inference_bridge — no live consumer. Only self-references plus a stale
    comment in engine/startup_wiring.py and a generated artifacts/audit_report.md entry.
  • load_domain_rules — referenced only by engine/startup_wiring.py, which itself has
    no caller anywhere in the tree (it is a documented "recipe" file, not a runtime entrypoint).
  • engine/inference_rule_registry is imported only by tests/gap_fixes/; it is not
    exported from engine/__init__.py and defines no __all__. No public API surface changes.
  • No docs/ or contracts/ file references load_domain_rules or inference_bridge.

Post-change exact-symbol scan: no inference_bridge, inference_bridge_v2,
docs/migration/inference_bridge_v2.md, spec.kb, load_domain_rules,
DerivationGraph, NaryFact, to_rule_engine_format, or load_kb_facts remains
outside the new regression test that asserts their absence.

Commands run locally (Python 3.13 poetry env):

  • make agent-check-unitpassed (action refs, contract wiring, contract scanner,
    payload compiler, ruff check + ruff format --check, mypy engine/, unit tests,
    contract coverage, audit harness "HARNESS PASSED"). Also run green on unmodified
    main first to establish the baseline.
  • PYTHONPATH=. pytest tests/gap_fixes/test_gap3_inference_registry.py tests/gap_fixes/test_gap9_inference_authority.py
    11 passed
  • PYTHONPATH=. pytest tests/ --ignore=tests/e2e --ignore=tests/integration --ignore=tests/performance
    1914 passed, 14 skipped, 56 xfailed, 0 failed

Not verified locally

tests/integration/ and tests/performance/ could not run in this container: no Docker
socket is available, so the testcontainers-neo4j fixture errors at setup
(FileNotFoundError on the docker socket). This is environmental and pre-existing —
those suites error identically on unmodified main, and none of them import the modules
touched here. CI is the authority for them.

Known limitation (deliberately not fixed here)

There is no verified production edge from DomainPackLoader / DomainSpec into
engine.inference_rule_registry. engine/startup_wiring.py remains a recipe file with
no caller, and the registry remains reachable only from tests. This PR does not invent
that integration. If domain-configured inference is wanted, it needs a separate program
that first establishes the producer, the consumer, the typed configuration contract, and
the runtime owner — not a kb field bolted onto DomainSpec.

Risk

Low. The change deletes dead code and a module that could only ever raise on import.
The one residual risk is an unindexed external consumer importing
engine.inference_bridge — such a consumer already fails at import on current main.

Rollback

Revert the PR if a real consumer surfaces. Do not restore the ghost v2 target; re-plan
against the actual consumer contract.

Files changed

  • delete engine/inference_bridge.py
  • modify engine/inference_rule_registry.py
  • modify engine/startup_wiring.py
  • add tests/gap_fixes/test_gap9_inference_authority.py

4 files changed, 60 insertions(+), 127 deletions(-)


Generated by Claude Code

claude added 3 commits August 23, 2026 19:18
engine/inference_bridge.py was a tombstone that raised ImportError while
directing callers to engine.inference_bridge_v2.DerivationGraph and
docs/migration/inference_bridge_v2.md. Neither exists in this repository,
so the module advertised a successor protocol that was never implemented.

Reverse-import verification at this base found no live consumer: the only
references were the module's own text and a stale comment in
engine/startup_wiring.py. The tombstone is deleted rather than replaced —
no successor bridge is introduced for compatibility alone.

Task: CEG-001

Claude-Session: https://claude.ai/code/session_01Fc1ayR9FNiXRQ22HxMSRsh
engine/startup_wiring.py attempted `load_domain_rules(spec.kb)` for every
domain, but DomainSpec does not declare a `kb` field and the production
GraphLifecycle boot path never invokes apply_all_gap_fixes(). The path was
dead and, had it run, would have raised AttributeError.

Removes the dead recipe block, the raw-dictionary rule loader
(load_domain_rules / _register_condition_rule), and the stale bridge
comment. The typed DomainSpec / DomainPackLoader boundary stays the single
owner of domain configuration; no second rule-configuration surface and no
`kb` field are added. All built-in @register_inference_rule functions and
the execute_rule() registry boundary are preserved unchanged.

InferenceContext.domain_kb is retained as optional caller-supplied tuning
context — infer_material_grade_from_mfi still reads it — but it is no
longer documented as populated by domain-spec injection.

Task: CEG-002

Claude-Session: https://claude.ai/code/session_01Fc1ayR9FNiXRQ22HxMSRsh
Adds tests/gap_fixes/test_gap9_inference_authority.py alongside the
existing gap-fix test owners. It asserts that the bridge module stays
deleted, that the startup recipe does not reintroduce spec.kb /
load_domain_rules, that the registry exposes no raw-KB or n-ary symbols,
that no engine/ source references the nonexistent v2 successor or its
migration guide, and that execute_rule() still returns the canonical
InferenceResult for a registered built-in rule.

Task: CEG-003 (regression portion)

Claude-Session: https://claude.ai/code/session_01Fc1ayR9FNiXRQ22HxMSRsh
@claude
claude Bot requested a review from cryptoxdog as a code owner August 23, 2026 19:20
@github-actions

Copy link
Copy Markdown

PR reviewable size is within recommended limits

@github-actions

github-actions Bot commented Aug 23, 2026

Copy link
Copy Markdown

L9 Audit Harness Report

  • Generated: 2026-08-23T19:27:04.917527+00:00
  • Repo root: /home/runner/work/Cognitive.Engine.Graphs/Cognitive.Engine.Graphs
  • Overall result: ✅ PASSED
  • Exit code: 0

Step Results

Step Status Exit Code Notes
Architecture Audit ✅ Passed 0
Spec Coverage ✅ Passed 0
Contract Wiring ✅ Passed 0

Architecture Audit Findings

Severity Count
🔴 CRITICAL 0
🟠 HIGH 0
🟡 MEDIUM 23
🔵 LOW 0

See artifacts/audit_report.md for full details.

Spec Coverage

  • ✅ Implemented: 37
  • ⚠️ Partial: 9
  • ❌ Missing: 0
  • Total features: 46
Category Implemented Partial Missing Total
gates 10 0 0 10
scoring 7 0 0 7
v1.1_node 2 0 0 2
v1.1_edge 2 0 0 2
v1.1_action 0 2 0 2
v1.1_scoring 1 1 0 2
action_handler 0 6 0 6
gds_algorithm 5 0 0 5
research_pattern 10 0 0 10

See artifacts/coverage_report.md for full details.

Next Steps

All checks passed. Safe to merge.

Comment thread tests/gap_fixes/test_gap9_inference_authority.py Fixed
github-code-quality flagged tests/gap_fixes/test_gap9_inference_authority.py
for importing engine.inference_rule_registry with both `import ... as` and
`from ... import ...`.

Keeps the module alias only, and reaches InferenceContext, InferenceResult and
execute_rule through it. The module-surface hasattr() assertions stay exactly
as they were; no test behaviour changes.

Claude-Session: https://claude.ai/code/session_01Fc1ayR9FNiXRQ22HxMSRsh
@sonarqubecloud

Copy link
Copy Markdown

@cryptoxdog
cryptoxdog merged commit 5868bc4 into main Aug 23, 2026
49 checks passed
cryptoxdog pushed a commit that referenced this pull request Aug 23, 2026
Evidence-only repair of four factual defects in the audit record. The
seven-module cleanup, its classifications, and all runtime code are unchanged.

1. Predecessor attribution. The record identified the inference-ownership
   closure contract as having merged as PR #232. False: PR #232 is
   "fix(inference): remove ghost bridge and unowned KB rule loading"
   (merge commit 5868bc4, this PR's base). It deliberately RETAINED
   engine/inference_rule_registry.py and explicitly recorded that the module
   has no verified production edge. The ownership-closure contract is a
   separate, unexecuted program. All "predecessor" wording now names PR #232
   and its actual scope.

2. Inference registry classification. HISTORICAL_REFERENCE was wrong — the
   module is executable, current, and reachable only from
   tests/gap_fixes/test_gap3_inference_registry.py and test_gap9. Reclassified
   TEST_ONLY_IMPLEMENTATION (CONFIRMED, runtime_callers: [],
   production_reachability: NONE_VERIFIED). KEEP stands, restated as what it
   is: a scope decision deferring inference ownership, not a canonicality
   claim.

3. GateRegistry mechanics. The record said all_gates.py holds
   "decorator-registered gate classes". There is no decorator registration
   anywhere in engine/gates/ — GateRegistry._REGISTRY is a static dictionary
   mapping GateType values to classes imported from all_gates.py.

4. Gate finding upgraded from speculation to GATE-001. "May be a real defect
   because GateCompiler bypasses it" understated the evidence. Recorded facts:
   GateCompiler is the production-reachable compiler with its own per-GateType
   handlers and composite recursion (_compile_composite); GateRegistry +
   all_gates form a production-unreachable ALTERNATE implementation surface in
   which CompositeGate recurses via GateRegistry.get_gate_class; tests
   (test_boot_and_registry.py::TestGateRegistry) and the active
   gate-development skill both maintain that alternate surface. Whether it
   carries semantics that must be preserved before consolidation is UNKNOWN —
   deferred to a dedicated gate-by-gate parity audit. No conclusion (wire it /
   delete it / keep both) is authorized by this record, and engine/gates/** is
   untouched.

DEF-001's full-tree reachability-gate deferral, the 59-module UNKNOWN
classification, the no-large-baseline decision, and every deletion conclusion
are preserved verbatim.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants