src.dackar.RCA.doc_extraction¶
Submodules¶
Attributes¶
Exceptions¶
Base error for DocExtractionStore backend failures (Chroma / embedding backend). |
|
Raised when the query-time embedding model does not match the collection's stored model. |
Classes¶
str(object='') -> str |
|
One extraction record per identified causal chain within a source document. |
|
Wraps HybridNERPipeline + causal_condition_adapter to produce DocExtractionRecords. |
|
Chroma-backed store for DocExtractionRecord objects. |
|
One deduplicated result from a DocExtractionStore.query() call. |
|
Applies the four-way epistemic classification to a document record. |
|
Versioned configuration artifact for the epistemic routing table. |
Functions¶
Build the epistemics section of run_manifest.artifacts (Phase A). |
Package Contents¶
- class src.dackar.RCA.doc_extraction.ConfidenceLevel[source]¶
Bases:
str,enum.Enumstr(object=’’) -> str str(bytes_or_buffer[, encoding[, errors]]) -> str
Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.__str__() (if defined) or repr(object). encoding defaults to ‘utf-8’. errors defaults to ‘strict’.
- HIGH = 'high'¶
- MEDIUM = 'medium'¶
- LOW = 'low'¶
- class src.dackar.RCA.doc_extraction.DocExtractionRecord[source]¶
One extraction record per identified causal chain within a source document.
A single CR/WO may produce multiple records (one per causal chain). Records with all semantic fields null are stored but flagged for human review. fm_id_candidate is null at ingestion time; resolved via batch KG lookup at RCA run time (§3.3 Step C). embedding_model_version is null until the record is embedded in Stage 2.
- doc_id: str¶
- chain_index: int¶
- identified_effect: str | None¶
- assessed_cause: str | None¶
- inferred_fm_label: str | None¶
- fm_id_candidate: str | None¶
- fm_id_candidate_alt: str | None¶
- confidence: ConfidenceLevel¶
- cause_is_symptom: bool¶
- as_found: str | None¶
- as_left: str | None¶
- procedural_deviation_score: float¶
- extraction_version: str¶
- embedding_model_version: str | None¶
- needs_human_review: bool = False¶
- ruled_out_mechanisms: List[str] = []¶
- event_time_start: datetime.datetime | None = None¶
- event_time_end: datetime.datetime | None = None¶
- event_time_confidence: str | None = None¶
- source_cr_id: str | None = None¶
- source_wo_id: str | None = None¶
- source_event_id: str | None = None¶
- fm_resolution_status: str | None = None¶
- fm_resolution_score: float | None = None¶
- doc_type: str = ''¶
- finding_status: str | None = None¶
- authority_level: str | None = None¶
- epistemic_class: str | None = None¶
- classification_resolution_level: str | None = None¶
- degraded_classification: bool = False¶
- embed_text()[source]¶
Concatenation of semantic fields used for embedding (null-safe).
- Return type:
str
- is_null_record()[source]¶
Return True when no semantic content was extracted (all three core fields empty).
Null records are the sentinel produced for a document with no extractable causal language; they are stored and retrievable by metadata but never surface in similarity queries (their embed_text is a single space).
- Return type:
bool
- is_recurrence_eligible()[source]¶
Return True when this record may contribute to recurrence counting.
Records with fm_resolution_status == “ambiguous” require analyst promotion before being eligible; all others (auto_resolved, unresolved, or not yet resolved) are treated as eligible by default.
Phase C will add an additional gate: records whose epistemic_class is not “analyzes_past_degradation” will be ineligible regardless of fm_resolution_status. That gate is intentionally off here to avoid a scoring change before calibration.
- Return type:
bool
- class src.dackar.RCA.doc_extraction.DocExtractionAdapter(ner_pipeline, nlp=None, llm_cfg=None, extraction_version='ner-v1.0_gaz-v1_llm-none', _causal_extractor=None)[source]¶
Wraps HybridNERPipeline + causal_condition_adapter to produce DocExtractionRecords.
Produces one record per identified causal chain in the document. A document with no extractable causal language produces one null record (confidence=low, needs_human_review=True).
fm_id_candidate is always None at extraction time; resolved via batch KG lookup at RCA run time (see DocExtractionStore.resolve_fm_candidates).
- Parameters:
ner_pipeline (Any)
nlp (Any)
llm_cfg (Optional[Dict[str, Any]])
extraction_version (str)
_causal_extractor (Optional[Any])
- _ner¶
- _nlp = None¶
- _llm_cfg = None¶
- extraction_version = 'ner-v1.0_gaz-v1_llm-none'¶
- __causal_extractor = None¶
- extract(doc_id, text, doc_type, section_role='body')[source]¶
Extract all causal chains from a single document text.
- Parameters:
doc_id (str) – Source document identifier (e.g. “CR-2026-00123”).
text (str) – Full document text (single chunk; multi-chunk handling is a future extension).
doc_type (str) – Must be one of EXTRACTABLE_DOC_TYPES.
section_role (str) – Hint for condition-state extraction (“body”, “as_found”, “as_left”, etc.).
- Returns:
List of DocExtractionRecord, one per causal chain. Never empty — a document with no causal language returns a single null record.
- Raises:
ValueError – if doc_type is not in EXTRACTABLE_DOC_TYPES.
- Return type:
List[src.dackar.RCA.doc_extraction.schema.DocExtractionRecord]
- class src.dackar.RCA.doc_extraction.DocExtractionStore(persist_directory, embed_model='nomic-embed-text-v1.5', ollama_base_url=None, fm_resolution_threshold=0.88, epistemics_classifier=None)[source]¶
Chroma-backed store for DocExtractionRecord objects.
One collection (
"doc_extractions") stores all extraction records across all document types. Each record’s embed_text (§4.1) is computed and stored at upsert time; similarity queries run against these pre-computed vectors.Key guarantees: - Embedding model version is written into every record’s metadata.
A mismatch between query-time model and stored model raises EmbeddingModelVersionError.
fm_id_candidate is always null at ingestion; resolve_fm_candidates() writes it back in batch at the start of an RCA run (§3.3 Step C).
query() deduplicates by doc_id, returning only the best-scoring chain per document.
- Parameters:
persist_directory (str)
embed_model (str)
ollama_base_url (Optional[str])
fm_resolution_threshold (float)
epistemics_classifier (Optional[Any])
- COLLECTION_NAME = 'doc_extractions'¶
- _HNSW_SPACE = 'cosine'¶
- persist_directory¶
- embed_model = 'nomic-embed-text-v1.5'¶
- ollama_base_url¶
- fm_resolution_threshold = 0.88¶
- epistemics_classifier = None¶
- _collection = None¶
- _embedder = None¶
- _degraded_operations: List[Dict[str, Any]] = []¶
- property embedding_model_version: str¶
- Return type:
str
- upsert(record)[source]¶
Embed and store one extraction record. Returns the Chroma record_id.
Records with no embed_text are stored with a single-space document to avoid Chroma rejecting empty strings; they are retrievable by metadata but will not surface in similarity queries.
- Parameters:
record (src.dackar.RCA.doc_extraction.schema.DocExtractionRecord)
- Return type:
str
- upsert_batch(records)[source]¶
Embed and store multiple extraction records in one batch call.
- Parameters:
records (List[src.dackar.RCA.doc_extraction.schema.DocExtractionRecord])
- Return type:
int
- query(query_text, *, top_k=5, similarity_threshold=0.75, near_match_window=0.1, filter_meta=None, exact_doc_ids=None)[source]¶
Query for semantically similar extraction records.
The embedding model used at query time must match the collection’s stored
embedding_model_version. A mismatch raises EmbeddingModelVersionError.Deduplication: only the highest-scoring chain per doc_id is returned.
- Parameters:
query_text (str) – The query string (e.g.
fm.name | fm.expected_symptoms | event.symptom_description).top_k (int) – Maximum number of doc_id-deduplicated results to return.
similarity_threshold (float) – Minimum cosine similarity for inclusion in the main result set.
near_match_window (float) – Width of the soft zone below threshold that populates near_matches.
filter_meta (Optional[Dict[str, Any]]) – Optional Chroma metadata pre-filter (e.g.
{"doc_type": "CR"}).exact_doc_ids (Optional[set]) – Set of doc_ids already counted via exact-match recurrence (kg_context.past_events). Matching records are excluded from both matches and near_matches to prevent double-counting. None or empty set disables the guard.
- Returns:
matches: similarity >= similarity_threshold, deduplicated, top_k max, exact_doc_ids excluded
near_matches: similarity in [similarity_threshold - near_match_window, similarity_threshold)
- Return type:
(matches, near_matches) where
- _assert_model_version()[source]¶
Raise EmbeddingModelVersionError if stored records use a different model.
- Return type:
None
- resolve_fm_candidates(fm_list, *, resolution_threshold=None)[source]¶
Resolve fm_id_candidate for unresolved extraction records.
Called once per RCA run before Step 3 / Step 2d. For each record with fm_id_candidate == “” (unresolved), embeds the stored inferred_fm_label and compares against the KG FM list for the current asset neighborhood. Writes fm_id_candidate (and fm_id_candidate_alt) back to the collection if cosine similarity >= resolution_threshold.
- Parameters:
fm_list (List[Tuple[str, str]]) – List of (fm_id, fm_label) tuples from the KG.
resolution_threshold (Optional[float]) – Override default; defaults to self.fm_resolution_threshold.
- Returns:
Number of records updated.
- Return type:
int
- delete_by_doc_id(doc_id)[source]¶
Delete all extraction records for a given source document (re-ingestion path).
- Parameters:
doc_id (str)
- Return type:
None
- _record_degradation(operation, exc)[source]¶
Record a degraded (error-swallowed) operation for run-manifest surfacing.
query() and resolve_fm_candidates() degrade to empty/zero results on backend failure rather than crashing a batch run; each such event is captured here so store_health_summary() can report it and the failure is not misread downstream as a legitimate “no semantic recurrence”.
- Parameters:
operation (str)
exc (Exception)
- Return type:
None
- property degraded: bool¶
True when any query/resolve operation swallowed a backend error this run.
- Return type:
bool
- store_health_summary()[source]¶
Degradation summary for run_manifest (store_health section).
Returns
{"degraded": bool, "degraded_operation_count": int, "events": [...]}. The orchestrator stamps this onto the run manifest so a swallowed Chroma/embedding error surfaces as an explicit degraded-run signal instead of a silent under-count.- Return type:
Dict[str, Any]
- class src.dackar.RCA.doc_extraction.SemanticMatch[source]¶
One deduplicated result from a DocExtractionStore.query() call.
- record_id: str¶
- doc_id: str¶
- chain_index: int¶
- identified_effect: str | None¶
- assessed_cause: str | None¶
- inferred_fm_label: str | None¶
- fm_id_candidate: str | None¶
- cause_is_symptom: bool¶
- similarity_score: float¶
- fm_resolution_status: str | None = None¶
- doc_type: str = ''¶
- finding_status: str | None = None¶
- authority_level: str | None = None¶
- epistemic_class: str | None = None¶
- classification_resolution_level: str | None = None¶
- degraded_classification: bool = False¶
- property confidence_weight: float¶
Numeric weight for this match’s confidence level (HIGH=1.0, MEDIUM=0.7, LOW=0.3).
Used as a multiplier in semantic_contribution (§4.3) so lower-confidence extractions contribute proportionally less to effective_recurrence_count.
- Return type:
float
- property cause_is_symptom_factor: float¶
Down-weight factor when the assessed cause is itself a symptom (0.5) vs. a mechanism (1.0).
A symptom-as-cause is a weaker recurrence signal than a true failure mechanism, so it halves this match’s semantic_contribution.
- Return type:
float
- property semantic_contribution: float¶
Fractional recurrence contribution for effective_recurrence_count (§4.3).
- Return type:
float
- exception src.dackar.RCA.doc_extraction.DocExtractionStoreError[source]¶
Bases:
RuntimeErrorBase error for DocExtractionStore backend failures (Chroma / embedding backend).
query() and resolve_fm_candidates() deliberately degrade to empty/zero results on backend failure rather than raising, recording each event via _record_degradation() so it surfaces in the run manifest (see store_health_summary()). Callers that prefer fail-loud semantics can inspect store_health_summary()[“degraded”] and escalate.
- exception src.dackar.RCA.doc_extraction.EmbeddingModelVersionError[source]¶
Bases:
DocExtractionStoreErrorRaised when the query-time embedding model does not match the collection’s stored model.
- class src.dackar.RCA.doc_extraction.EpistemicClassifier(config=None)[source]¶
Applies the four-way epistemic classification to a document record.
Usage¶
config = EpistemicsRoutingConfig(policy_version=”epistemics-v1.0”) classifier = EpistemicClassifier(config) annotation = classifier.classify(meta)
metamay be a dict (Chroma metadata), a DocExtractionRecord, or a SemanticMatch — any object that exposes the relevant fields via attribute or dict access.Priority chain (§3.3)¶
finding_status — semantic; not degraded
authority_level — semantic; not degraded
doc_type — syntactic proxy; degraded_classification = True
default — no metadata; degraded_classification = True
- config¶
- _doc_type_table¶
- classify(record)[source]¶
Classify one record and return an EpistemicAnnotation.
recordmay be: - a dict (Chroma metadata dict) - a DocExtractionRecord - a SemanticMatch - any object with attribute access for the relevant fields- Parameters:
record (Any)
- Return type:
- annotate_record(record)[source]¶
Classify
recordin-place, writing annotation fields back to it.Supports DocExtractionRecord and SemanticMatch (both have the three annotation fields as attributes). No-ops silently on other types.
- Parameters:
record (Any)
- Return type:
None
- _resolve_finding_status(finding_status, doc_type)[source]¶
Look up (finding_status, doc_type) in the routing table.
Tries exact (finding_status, doc_type) first, then (finding_status, “”) as the doc_type-agnostic fallback. Returns None if not found.
- Parameters:
finding_status (str)
doc_type (str)
- Return type:
Optional[str]
- Parameters:
config (Optional[EpistemicsRoutingConfig])
- class src.dackar.RCA.doc_extraction.EpistemicsRoutingConfig[source]¶
Versioned configuration artifact for the epistemic routing table.
policy_version is stamped on run_manifest.pipeline_config and on every EpistemicAnnotation so that routing decisions are reproducible.
The routing tables are embedded in epistemics.py and versioned via policy_version; changing any table entry requires a version bump.
- policy_version: str = 'epistemics-v1.0'¶
- doc_type_overrides: Dict[str, str]¶
- src.dackar.RCA.doc_extraction.build_epistemics_manifest_summary(cross_pattern_evidence, policy_version)[source]¶
Build the epistemics section of run_manifest.artifacts (Phase A).
Counts epistemic_class distribution, degraded_classification counts by doc_type, and classification_resolution_level distribution across all doc extractions visible to the pipeline. Sourced from cross_pattern_evidence all_links provenance when available; otherwise returns a minimal stub.
This function is called by the orchestrator’s _stage_g_finalize_manifest(). It is defined here (not in the orchestrator) so that it can be unit-tested independently without the orchestrator’s heavy kg dependencies.
- Parameters:
cross_pattern_evidence (Optional[Dict[str, Any]])
policy_version (Optional[str])
- Return type:
Dict[str, Any]