core/docs/decisions/ADR-0149-derived-recognizer-pipeline-wiring.md
Shay 81718a0952
feat(W-007): wire DerivedRecognizer registry into CognitiveTurnPipeline (ADR-0149) (#274)
- RecognizerRegistry.first_admitted() — deterministic first-registered selection
- CognitiveTurnPipeline consults runtime registry when no recognizer explicitly passed
- ChatRuntime gains _pending_recognizer_examples + record_recognition_example()
- checkpoint_engine_state() derives and registers recognizer from accumulated examples
- RuntimeConfig.recognition_grounded_graph gate (already existed) controls wiring
- ADR-0149 decision record
2026-05-25 12:24:48 -07:00

2.4 KiB

ADR-0149 — Integrate DerivedRecognizer into CognitiveTurnPipeline

Status: Accepted Date: 2026-05-25 Work item: W-007


Context

ADR-0143 introduced deterministic DerivedRecognizer derivation and matching. ADR-0144 gave CognitiveTurnPipeline an epistemic graph carrier and an optional recognizer constructor slot. ADR-0146 added persisted engine state, including RecognizerRegistry. ADR-0148 / W-003 wired vault promotion so COHERENT entries can eventually become recognition evidence.

The missing edge was live admission: the runtime had a registry, but the pipeline never consulted it. A populated registry was therefore inert unless a test or caller manually passed a recognizer to CognitiveTurnPipeline.


Decision

RecognizerRegistry.first_admitted() returns the first registered recognizer in deterministic insertion order, or None when empty.

ChatRuntime now exposes first_admitted_recognizer(), gated by RuntimeConfig.recognition_grounded_graph. When the flag is false, the method returns None and the turn path is byte-behavior compatible with the previous runtime.

CognitiveTurnPipeline uses an explicitly supplied recognizer first. When no recognizer is supplied, it asks the runtime for the first admitted recognizer. If the registry is empty, recognition remains absent and the existing intent-derived graph path is used.

ChatRuntime.record_recognition_example(tokens, bundle) records deterministic training pairs for test harnesses and future automated collection. At checkpoint_engine_state(), after the vault promotion boundary, a non-empty pending example set is passed to derive_recognizer() and the result is registered before engine-state persistence.


Null-Drop

recognition_grounded_graph=False means the registry is ignored, no recognizer is passed to the pipeline, and pending examples are not derived at checkpoint. The default therefore preserves the previous turn behavior.


Follow-Up

Automated example collection is intentionally out of scope. derive_recognizer() requires (TokenSequence, FeatureBundle) pairs with span-level evidence, not teaching corpus templates. The follow-up path is:

finalize_turn -> FeatureBundle with evidence spans -> record_recognition_example -> checkpoint derivation

That follow-up makes the registry self-populating; this ADR makes the registry live and replay-persistent.