Commit Graph
48 Commits
Author SHA1 Message Date
funkpower f3e70b9bf7 citefind: a note that cites three works is three references
Measured against the citations an LLM had already extracted from 40 books of
the same corpus — 19,340 of them over 3,424 chunks — and improved where the
comparison showed a real gap rather than a difference of task.

On pages of notes, where most citations live: year agreement with the model
44% -> 56%, title 18% -> 23%, author 16% -> 24%.

What changed:

- A note listing several works, semicolon-separated, becomes one record per
  work. The note number is kept on all of them.
- A full stop is not a separator. It parts the author from the title in every
  bibliography entry there is.
- A page of body text with notes at its foot no longer reads the body as the
  first note.
- A run carrying a page reference or a semicolon is not reported as a title.
- Six sentences with no imprint, no page and no identifier is a remark about
  the argument, not a reference.
- A translator standing where the journal goes is a credit, not a container,
  and `(London, 1973)` is a place, not a publisher.

The model is not ground truth and the comparison is not a score: on several
sampled disagreements it named the journal where the article was wanted, or
the collected works instead of the essay.
2026-09-20 11:10:42 -04:00
funkpower c071f84829 citefind: the references in a bibliography, and what could not be read off them
Cuts a reference list into entries — at the note numbers where there are any,
at the layout where there are not — and reads each as far as its punctuation
allows. Fields that would not parse are named in `unsettled` rather than
guessed at, and `--prompt` asks a model about exactly those and no others.

Over 202 real reference sections from the corpus: 8,566 references, 95% with
a title, 82% with a year, 46% settling every field with no model involved.
A title is refused where the entry was never divided, so no record reports
its own text back as the work it cites.

`ibid.` is flagged and left alone — it points at a work, and the entry does
not say which. A rule of dashes is filled in, because the style defines it as
the author above.

chunkmd gains `note_starts` and `cites_something`: recognising a page of
notes and splitting one are the same knowledge, and two copies of that
pattern would drift.
2026-09-20 10:38:48 -04:00
funkpower d24e37bd12 langid and tocfind: what language a book is in, and what it says its chapters are 2026-09-20 10:02:15 -04:00
funkpower 05759ab902 bookmeta: the metadata a file already carries, and a question about the rest 2026-09-20 09:41:37 -04:00
funkpower 0b849c39c4 cueseg: chapter by vectors somebody else made, where there are some
The hashed bag of words asks only whether two stretches repeat the same
words, and cannot tell that ships and vessels are one subject. An embedding
can. segment_with takes one vector per window and falls back to the words
when it is given none, or the wrong number of them — a caller that embedded
some other recording's windows is asking about that recording.

windows_of gives the text to embed, in the order the vectors come back in,
so nobody has to reimplement the windowing pass to use this.

Bound in all three languages, and on the command line as --windows and
--embeddings, which pipe through emb. The C ABI version goes to 2:
catena_segment_cues gained an argument.
2026-09-20 09:12:04 -04:00
funkpower dd09499e68 bindings: cueseg, so a transcript can be chaptered in process 2026-09-20 09:00:26 -04:00
funkpower f9f809f701 chunkmd: the half of a word boundary that applies before a digit 2026-09-20 07:18:34 -04:00
funkpower 84d95b1022 mdscrub: a page anchor the engine cannot backtrack on 2026-09-19 21:01:24 -04:00
funkpower 577b381868 bindings: how to verify a swap, without the scaffolding for one 2026-09-19 20:43:16 -04:00
funkpower 645116d5ed shadow: run both implementations over a corpus and diff them 2026-09-19 20:40:15 -04:00
funkpower d47881ef3b idnorm and bibfetch: an identifier read, and a register asked 2026-09-19 19:19:54 -04:00
funkpower 4d14544409 bibclean: an abstract that arrived as an index 2026-09-19 19:09:27 -04:00
funkpower 484017fc18 vocabmerge: a subject scheme, supplied rather than compiled in 2026-09-19 19:06:57 -04:00
funkpower 05b363ea8a seriesof: the series a book belongs to, and which volume this is 2026-09-19 19:03:47 -04:00
funkpower e9d22ee1fa bindings: typecheck the declarations the package ships 2026-09-19 18:57:24 -04:00
funkpower 48600bd90c bindings: a C ABI and an npm package alongside the wheel 2026-09-19 18:40:08 -04:00
funkpower cf126dddc3 bindings: the libraries in process, for Python 2026-09-19 17:54:18 -04:00
funkpower a80f8a024d chunkmd: say rfind, which is what this was doing 2026-09-19 17:36:18 -04:00
funkpower 9fd654ad5f docs: the manual-page flag, and the records that belong to one tool 2026-09-19 17:06:17 -04:00
funkpower 619672d403 pdfgutter: never rewrite a page tree it cannot account for 2026-09-19 16:51:12 -04:00
funkpower a03dcd400c avplan: paths an encoder can actually read, and a pipeline that runs 2026-09-19 15:31:17 -04:00
funkpower ab33ac4693 every tool writes its own manual page 2026-09-19 15:25:13 -04:00
funkpower df2a62ec84 pdfgutter: drop a doctest marker from prose 2026-09-19 15:20:12 -04:00
funkpower 3c697bee50 pdfgutter: two facing pages photographed as one, found and cut 2026-09-19 15:19:35 -04:00
funkpower 49f12c9718 avplan: whether a recording plays, and the one call that fixes it 2026-09-19 15:07:33 -04:00
funkpower ea0a3694b1 mdsplit: the works inside one file, and the books inside scripture 2026-09-19 14:58:54 -04:00
funkpower 9bf59f6ebb vocabmerge: the near-duplicate headings a catalogue accumulates 2026-09-19 14:37:22 -04:00
funkpower 739e6c82e9 lints 2026-09-19 14:30:22 -04:00
funkpower 3c16892ebf bibclean: a name from the book's own pages, where the record has none 2026-09-19 14:29:12 -04:00
funkpower 14e1fcf3ef bibclean: slugs, and whether the one a record has still names it 2026-09-19 14:23:36 -04:00
funkpower 7fa610c578 each crate carries its own readme, and the contract describes rather than instructs 2026-09-19 14:15:01 -04:00
funkpower b0743d5bf7 a missing word, a hidden dependency, and a second pass that changed things 2026-09-19 13:00:29 -04:00
funkpower 6e26d5cf4b bibclean: record faults, weighed, with the repairs that need no lookup 2026-09-19 12:50:53 -04:00
funkpower c6575b2d42 emb: lines into vectors, against a server that owns the model 2026-09-19 12:43:20 -04:00
funkpower 1071f0bed3 booksniff, and one place for the parts every tool shares 2026-09-19 12:40:20 -04:00
funkpower 36afe3350b cuepack: cues into passages that keep their timestamps 2026-09-19 12:32:41 -04:00
funkpower b6602ee1e9 rrf: rank fusion without the database 2026-09-19 12:29:54 -04:00
funkpower 339f402610 ported patterns mean in rust what they mean in python 2026-09-19 12:26:41 -04:00
funkpower 17a03b0087 cueseg: topic chapters from a transcript, and a worked pipeline in the readme 2026-09-19 12:21:35 -04:00
funkpower c7d0767376 cuekit and cuenorm: three subtitle formats, one cue stream 2026-09-19 11:54:36 -04:00
funkpower 33c2e40a1a pdftriage: text layer verdicts, including the reflected-font recovery 2026-09-19 11:46:34 -04:00
funkpower bd0ae11d01 mdscrub: decode character references, keep block boundaries, narrow the fence 2026-09-19 11:36:31 -04:00
funkpower 1b3c002b3d mdscrub: residual html, control characters, headings, page markers 2026-09-19 11:30:05 -04:00
funkpower e0473fb8ae chunkmd: page and chapter aware chunking, roles, footnote flag 2026-09-19 11:22:56 -04:00
funkpower acf8605d37 format 2026-09-19 11:12:23 -04:00
funkpower 6d9b7415dd corpus-core: make the stream contract hold under hostile input 2026-09-19 11:11:58 -04:00
funkpower 0208b14b5d textkit: token counting and the two segmenters 2026-09-19 11:04:27 -04:00
funkpower 00f4c38816 workspace, licence, and the three record types 2026-09-19 11:00:40 -04:00