popoto.extraction.candidates¶
popoto.extraction.candidates
¶
Deterministic candidate enumeration for auditable extraction (M3, #562).
A candidate is a span of one conversation turn that the rest of the extraction pipeline decides on: the firewall scans it, the verdict stage votes on it, and the decision log records exactly one terminal state for it.
This module is the pipeline's only source of candidates, and it is deliberately the dullest stage:
- Pure. No Redis, no LLM, no network, no clock.
generate_candidatesis a function of(turn_id, text)alone. - Deterministic. The same input always yields the same list, in the same order, with the same ids. Auditability depends on this -- a non-deterministic candidate set makes a decision log unreplayable.
- Exhaustive. Nothing is filtered here. Short sentences, duplicate sentences and low-value entities are all emitted, because dropping a candidate is a decision that must be logged by the caller, not a silence produced here. There is deliberately no per-turn cap.
Two generator rules produce the v1 candidate set:
sentence
One candidate per sentence span, using the same split regex as
:class:~popoto.extraction.HeuristicExtractionProvider.
entity
One candidate per pattern-lifted named entity. The lift is a regex, not
a model call -- an LLM here would make the candidate set
non-reproducible.
Candidate
dataclass
¶
One deterministically enumerated span of a turn.
Attributes:
| Name | Type | Description |
|---|---|---|
text |
str
|
The verbatim span. Byte-identical to
|
turn_id |
str
|
Id of the turn this span came from. |
candidate_id |
str
|
|
start |
int
|
Character offset of the span's first character in the turn text. |
end |
int
|
Character offset one past the span's last character. |
generator_rule |
str
|
Which rule produced this candidate --
|
Source code in src/popoto/extraction/candidates.py
generate_candidates(turn_id, text)
¶
Enumerate the complete v1 candidate set for one turn.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
turn_id
|
str
|
Id of the turn being extracted. Becomes the first segment
of every |
required |
text
|
Optional[str]
|
The turn's raw text. |
required |
Returns:
| Type | Description |
|---|---|
List[Candidate]
|
Sentence candidates in document order, followed by entity |
List[Candidate]
|
candidates in document order. Empty list when |
List[Candidate]
|
whitespace-only or not a string -- an empty turn produces zero |
List[Candidate]
|
candidates, and the caller (not this module) logs the |
List[Candidate]
|
|
List[Candidate]
|
dependency. |