Commit History
-
[NOTICKET] feat(knowledge-extraction): derived outline + corroborated key parameters
Rifqi Hafizuddin +1: Claude Opus 5The two DETERMINISTIC halves of the DomainContext v3 reshape. No LLM, no spend, no prompt change - which is exactly why they ship ahead of the rest: the parts that need a prompt rewrite and an eval run are split off and still proposed. outline Derived from the artifact's heading_path, in reading order, de-duplicated. The blocker was upstream: adapter.py was dropping heading_path on the floor, so the internal Chunk never carried it - the same way it once dropped `latex`, and with the same consequence, a branch inventing prose about a document whose own structure was sitting unread. Fixed at the seam. It is the only field on this branch carrying the strong guarantee for free: verbatim source structure, nothing to hallucinate. On the BUMA fixture it yields 11 entries from 29 of 31 chunks, including the verbatim "Physical of Availability (PA)" the pipeline is required to surface rather than tidy. key_parameters Was list[str]; now list[KeyParameter{surface, term_id}],…6f5d619
-
[NOTICKET] fix(knowledge_extraction): formula_latex is checked against Chunk.latex
Rifqi Hafizuddin +1: Claude Opus 5The field was guarded in name only. It sat in GUARDED_FIELDS but not in _TRANSCRIBED, so its value was never searched in the source -- only its provenance.span was. A structurally wrong transcription with a valid prose span passed, which is exactly the shape X21 produced: a \frac that lost its division reads as a product and states something the document does not. Adding the field to _TRANSCRIBED was not the fix. `text` carries rendered prose and can never contain LaTeX, so that would have nulled every formula entry and presented as a model failure rather than a validation bug. The haystack was the problem, not the check. Chunk.latex is now the haystack. The parsing half has always emitted it; extraction's adapter dropped it on the floor, which is what left the claim unprovable. It now crosses the seam and is compared with whitespace removed ENTIRELY rather than collapsed. That is a different notion of equality, not a weaker one. In LaTeX, whitespace outside \text{} is not significa…9c8a6e4
-
[NOTICKET] fix(knowledge_extraction): refuse an artifact that will not name its backend
Rifqi Hafizuddin +1: Claude Opus 5MinerU's `pipeline` and `vlm` backends emit different text from the same PDF. The same equation arrives as a semantic `\times` from one and as a spaced literal `x` from the other, and word boundaries that survive in `\text{...}` under `vlm` are gone under `pipeline`. Two extraction results measured on different backends are therefore not comparable, and nothing downstream can tell them apart after the fact. This is not hypothetical: the two halves spent a week comparing numbers taken from two different parses and read the disagreement as a rendering bug. Each side was measuring correctly, on a different artifact. The provenance already existed and was walked around. `ParsedDocument` carries `parser_backend`, and the parsing half reads it from MinerU's own `_middle.json` rather than from config, precisely so the recorded backend is the one actually used. It never reached extraction because what crossed the seam was a bare `content_list.json`, stripped of its envelope. So the CLI now …4db5f14 -
[NOTICKET] fix(knowledge): settle the chunk_id separator on `::`
Rifqi Hafizuddin +1: Claude Opus 5The two halves minted provenance keys differently: the parsing half emits `<doc_id>::<seq>`, while the extraction adapter fell back to `<doc_id>#<seq>` for artifacts arriving without one. Nothing broke in practice — the adapter prefers the supplied id, so real runs always carried `::` — but the two shapes could diverge the moment a fixture or an older artifact took the fallback. `::` wins: it is what the producer actually emits, the calibration doc already uses it in prose, and `#` is URL-fragment syntax that would bite once these ids become MCP resource identifiers. The `KNOWLEDGE_OUTPUT_CONTRACT.md` cited as the source of `#` does not exist in the repo or its history. The separator is now stated in the contract next to the field, because this is the second time an undocumented detail of the seam's shape has cost both halves a round trip. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>e8cc26c
-
[NOTICKET] feat(knowledge_extraction): consume the parsing half's ParsedDocument
Rifqi Hafizuddin +1: Claude Fable 5Wires the adapter to the contract Sofhia landed in src/knowledge_parsing, so the seam is exercised with the real types on both sides rather than a hand-written dict. - accepts a ParsedDocument instance directly, not just a dict - page_idx / page_idxs / page_idx_end are now the primary field names; the older draft and prototype names still load so existing fixtures keep working - page numbers pass through 0-BASED with no conversion anywhere. Converting is the review UI's job, done once at display time — an off-by-one here would be invisible until an expert opened the wrong page - parser_backend is folded into parser_version, because the same MinerU build emits different text from `pipeline` and `vlm`; a shift in extraction output has to stay attributable to one or the other New local seam tests import src.knowledge_parsing.contracts directly, so a field rename on either side fails there instead of silently degrading a corpus run. They pin the three properties the seam exists…f132cc1
-
[NOTICKET] feat(knowledge_extraction): free stages — models, seam adapter, filters, cluster, ranking
Rifqi Hafizuddin +1: Claude Fable 5First slice of extraction v2, rebuilt in this repo (the kex prototype is not being ported). All stages here are free: zero API calls, CPU only. New module src/knowledge_extraction/ (named to avoid colliding with src/knowledge/, the existing OCR->pgvector service, which is untouched): - models.py pydantic v2 contracts. Encodes the three invariants: content fields Optional, subdomain_tags as an enum, provenance.span mandatory. Adds source_wording so the literal source wording survives instead of being normalised away. - adapter.py THE ONLY file that knows the seam's shape. Stages depend on an internal Chunk subset, so the artifact contract can settle either way without touching a stage. Verified against both live shapes: Sofhia's bare-list draft with its `kind` discriminator, and the document-level envelope proposed in the checklist.…024c30a