Releases: prasadtalasila/chitragupta
Release list
v5.39.0
v5.39.0 -- 2026-08-19
Summary
- Zotero collection scoping now reaches the drafting skills. #195 built
the machinery and #227 completed the input side, but no skill used any of
it -- every skill-driven search was corpus-wide by construction, and the
feature was reachable only by a human typing--collectionon each call.
A genre skill now offers the choice once, records it in the draft's
scope.md, and threads it through the whole run. - A revision no longer silently widens a scoped draft.
draft-reviser
inherits the recorded collection instead of re-asking. This was the
sharpest edge: a draft grounded in one curated shelf, revised against the
whole library, changes what it is made of in a way that is invisible in
the diff -- every citekey is still real and the citation gate still
passes. deep-researchis deliberately exempt, and says so rather than
staying silent.- The feature is now measured rather than assumed, across three
benchmark runs shipped inbench/.
What's Changed
- Make collection scoping reachable from the genre skills (#229) by
@prasadtalasila in #257
Full Changelog: v5.38.1...v5.39.0
In Detail
What scoping buys, and what it does not
Measured over a 642-item corpus against a 19-item shelf, each condition
drafted by an isolated agent (bench/RESULTS.md):
| whole corpus | curated shelf | |
|---|---|---|
| Surfaced -> cited | 154 -> 47 (0.31) | 18 -> 16 (0.89) |
| Retrieval payload per query | 7,400 chars | 7,375 chars |
| Index cost | -- | zero |
Three findings worth knowing before turning it on:
- It does not reduce retrieval cost. At a fixed
--kthe filter still
returnskresults, drawn from a smaller pool. It changes which papers
reach the drafting context, not how many characters do. Nothing here
promises a token saving. - A shelf is not a subset of the library's ranking. The 19-item shelf
surfaced ten papers the whole-corpus search never returned, because a
small pool promotes what a large pool's competition buries. Scoping is a
genuine trade, not a free narrowing -- which is also whydeep-research,
whose deliverable is a contradiction map, does not scope at all. - Narrow-then-widen is not cheaper. Drafting against a shelf and then
runningcorpus-revisercost 65,674 output tokens against 41,573 for
drafting wide once. It buys a different artefact, not a cheaper one.
bench/bench_collection_scope.py
A parameterised harness for this comparison: retrieval payload from each
dossier's retrieval.md, surfaced/selected/rejected by replaying each
arm's own logged queries, index cost by md5 across three checkpoints,
per-arm token pools, and both arms' verbatim scans.
It publishes a self_check beside its token figures, after the naive
reading of a subagent transcript under-reported by 5x for an entire run
without anything noticing.
Three runs' pre-registrations, hashes and measurements ship under
bench/results/, including the first run's contamination -- two arms
written in one session, Jaccard 0.483 with a 487-word shared passage --
recorded rather than deleted, because the re-run with isolated agents
reversed one of its conclusions.
Upgrading
Nothing to change. A library exported without collections -- which is every
plain Zotero BibTeX export -- behaves exactly as it did in 5.38.1: no new
prompt, no warning, and identical retrieval results. docs/ZOTERO.md
covers keeping collections if you want them.
Known gaps
retrieval.md does not record which collection a search ran against, so a
scoped call and an unscoped one write identical rows, and dossier status
reports drift for a scoped draft against the whole corpus. Tracked as
#254; it only
affects drafts that are scoped, which this release is what makes common.
v5.38.1
v5.38.1 -- 2026-08-19
Summary
acronyms-suggestproposedFMI = "Interface"for a chapter whose prose
correctly said "Functional Mock-up Interface (FMI)". The inline
definition pattern could not carry the hyphenated "Mock-up", so the capture
restarted at the hyphen and kept only the last word.- That is worth a release on its own because the next step is
--apply, which writes the suggestion into the author's own
[style].acronymsvocabulary -- where a wrong expansion would then make
src.draft stylereport correct prose as drifted from it.
What's Changed
- Keep a hyphenated word in a suggested acronym expansion by @prasadtalasila in #255
Full Changelog: v5.38.0...v5.38.1
In Detail
before: FMI = "Interface"
after: FMI = "Functional Mock-up Interface"
One group: a name word may now carry (?:-[a-z]+)*. Lowercase after the
hyphen only, so "Digital Twin-Based" keeps its existing reading as two words.
The other ten acronyms the same 15-chapter book suggests -- DT, DM, DS,
DTA, DTI, DTP, DES, ROM, RTF, UQ -- are unchanged, and no draft
or glossary needed editing: the book was right and the detector was not.
Upgrading
Nothing to do. If you have already run acronyms-suggest --apply on prose
containing a hyphenated definition, check that entry in your own
[style].acronyms file -- this release does not rewrite what an earlier run
recorded.
v5.38.0
v5.38.0 -- 2026-08-19
Summary
- Every chapter of an assembled book now carries its own numbered IEEE
reference list, rendered by pandoc's citeproc against the vendored
assets/csl/ieee.csl-- the same notation every other genre skill
produces. The book-level bibliography is gone, and with it natbib and the
bibtex/biberpass: there is no\citeleft for either to answer. python -m src.draft render --fragmentemits an\input-able LaTeX
fragment instead of a standalone document, and--output-dirputs it where
the book'sbook.texexpects it. Those two flags are what let the assembly
skill reuse the pipeline's citation handling instead of restating a pandoc
invocation of its own..gitignoreis now blanket overcontent/, keeping the two tracked
worked examples visible. The enumerated list it replaces had gone stale the
momentcontent/specs/landed in 5.34.0.- docs/BOOKS.md
is rewritten as an eight-step guide, in the order you run it, with a real
book's output at each step.
What's Changed
- Give each chapter its own IEEE bibliography, fix the assembler, and blanket-ignore content/ by @prasadtalasila in #253
Full Changelog: v5.37.0...v5.38.0
In Detail
Everything here was found by assembling a real 15-chapter book for the first
time -- which is also why v5.37.0's assembly skill needed correcting rather
than extending.
- The conversion step named the wrong command.
render --format tex
emits a standalonearticlewith its own\begin{document};\inputthat
into a book and LaTeX refuses it.--fragmentis the flag that exists for
it now, and it carries--no-highlightwith it, because pandoc's
Shaded/Highlightingenvironments are defined only by the standalone
template. - A citekey containing
--was silently truncated. Three keys in one
corpus, ten citations, each of which would have rendered as[?]in a
finished book with nothing failing. Going throughrenderfixes it by
construction: the aliasing that handles it already lives there. - pandoc's citeproc macros fail the citation gate if inlined. The block
contains\cite{#1}and\citeproc{mm}; the real book FAILed on@mm,
@#1,@#2. They now go inciteproc-defs.def-- LaTeX's own extension
for a definitions file. - Margins are a third of the
bookclass's own (94pt inner, 143pt outer,
measured). The real book went from 546 pages to 326. book.mdis written besidebook.tex, hyperlinking the chapter files,
for anyone not building LaTeX.
scripts/install_full_pipeline.sh gains texlive-binaries (which owns
/usr/bin/bibtex) and texlive-publishers (IEEEtran.bst), named explicitly
for a document that genuinely wants a LaTeX-side bibliography.
Upgrading
Nothing to do. The two render flags are additive and default to the previous
behaviour. If you keep your own .gitignore fork, note that content/ is now
ignored wholesale rather than directory by directory.
v5.37.0
v5.37.0 -- 2026-08-18
Summary
- The book-scale track is complete.
book-assembler, the ninth skill,
composes accepted, gate-passed units into one LaTeX book -- front matter,
parts, chapters, back matter -- and stops at the second of the track's two
human gates. - It writes no prose. A unit that is missing, unaccepted or stale sends you
back to a genre skill or todraft-reviser; assembly is deterministic
composition, and this skill never drafts or edits. - With v5.34.0's outline, v5.35.0's generation unit and v5.36.0's registries,
a document larger than a context window is now tractable end to end:
docs/BOOKS.md.
What's Changed
- Assemble accepted units into a LaTeX book, as a genre skill by @prasadtalasila in #252
Full Changelog: v5.36.0...v5.37.0
In Detail
Conventions as data. The whole composition is one table: ## becomes
\part, ### becomes \chapter, #### becomes an \input of that unit --
and the outline's {#id} becomes the LaTeX label unchanged. That last part
is what makes the cross-references registry check verified actually resolve
in the built PDF, so the outline, the registry and the document all name the
same thing.
Where the consistency check gets its force. registry check exits 0
whatever it finds, because a machine's reading of prose may not block. What
is enforced instead is that it ran and that its findings were seen: this
skill must run it and print every finding, in full, before composing
anything, and a test pins both halves.
It does not say the book is finished. Every check in this pipeline
establishes that a book is grounded, consistent and complete. None of them
establishes that it is any good, and that judgement stays the author's.
Two smaller things: the bibliography stack is probed rather than assumed
(biblatex/biber where installed, natbib/bibtex otherwise), and
docs/GENRE.md now speaks for nine skills -- with the one exception the
non-drafting skill needs, since it writes no dossier.
Upgrading
Nothing to do. The skill is additive and is invoked only when you ask for a
book to be assembled.
v5.36.0
v5.36.0 -- 2026-08-18
Summary
- Cross-chapter consistency is now an artefact, not a memory. Three
registries -- terminology and notation, a claim register, and a
cross-reference graph -- are built by a deterministic pass over a book's
accepted units, and say how much of the book they could actually read. python -m src.draft registry checkreports what they disagree on:
a term defined in two units, the same claim made twice, a reference that
points at nothing.- Third piece of the book-scale track (#135), after the outline (v5.34.0)
and the generation unit (v5.35.0).
What's Changed
- Add terminology, claim and cross-reference registries over accepted units by @prasadtalasila in #251
Full Changelog: v5.35.0...v5.36.0
In Detail
check exits 0 whatever it finds, and that is the release's one
substantive design decision. spec status and unit status exit non-zero
because they report whether a human decided something -- approved an
outline, accepted a unit. This reports a machine's reading of prose, which
is judgement however mechanical the arithmetic, and
ARCHITECTURE.md's
"Layer 4" is explicit that such a check reports and never blocks, whichever
layer it lives in. What may be enforced is that it ran, which is what the
assembly step will guarantee.
What it cannot see, stated rather than implied: contradiction. Two
chapters asserting opposite things is not deterministically decidable;
duplication is, and that is what the claim register flags.
Two smaller things worth knowing:
- Nothing here is written by an LLM. The registries read accepted prose
through conventions this repository already had: the dossier glossary's
definition bullet, the shared sentence splitter, and the## References
cut-off measured against the real 15-chapter book. - A cross-reference is never spelled
@id-- that is a citekey
position. Markdown[text](#id)and LaTeX\ref{}/\cref{}are the two
supported shapes, and a test pins that the citation gate reads neither as
a citekey.
Upgrading
Nothing to do. The new command is additive and writes only under
content/specs/.
v5.35.0
v5.35.0 -- 2026-08-18
Summary
- The generation unit is now the section, and it has a contract.
python -m src.draft unitsays exactly what one section is generated
from -- its slice of the outline, the sources it is grounded in, and
(from the next release) the registry excerpts -- and hashes those inputs
so an unchanged unit costs nothing to re-run. - Acceptance is recorded rather than asserted.
unit acceptwrites a
record only after the project's one gate has passed on the draft, and
unit statusre-derives every digest, so a book's state is a fact on
disk rather than a memory. - Second piece of the book-scale track (#135), on top of v5.34.0's outline.
What's Changed
- Fix the generation unit at the section, with a hashed input contract by @prasadtalasila in #250
Full Changelog: v5.34.0...v5.35.0
In Detail
python -m src.draft unit contract content/drafts/twins sec-model --source smith_2024
python -m src.draft unit accept content/drafts/twins sec-model --source smith_2024
python -m src.draft unit status content/drafts/twins- The input digest covers the inputs only -- never the unit's own prose,
its sign-off state, or its path. A digest that moved when the output moved
could not answer "does this need regenerating?", which is the only question
it exists for. acceptinvokes the citation gate; it is not a second gate. A unit the
gate refuses cannot be accepted, and nothing new blocks a write.
python -m src.draft gateremains the only gate in the project.statustells five states apart --unwritten,drafted,accepted,
stale: inputs changed,stale: draft changed since accepted-- each
re-derived rather than trusted, and an unreadable record reads as
drafted.
Records live at content/specs/<book>/units/<unit-id>.json and carry no
timestamp, so accepting an unchanged unit twice is byte-identical.
Upgrading
Nothing to do. The new command is additive and writes only under
content/specs/.
v5.34.0
v5.34.0 -- 2026-08-18
Summary
- Book-scale drafting starts here. A book does not fit in a context
window, so its structure cannot live in a model's memory of an earlier
call. This release adds the artefact it lives in instead: an outline per
book on disk, approved by a human before any prose is generated. python -m src.draft specwrites, shows, signs and reports on that
outline.spec show --unit <id>prints exactly the slice a genre skill
should generate one section from, rather than having it invent structure
per invocation.- New document: docs/BOOKS.md,
which will grow one section per piece of the track as the rest lands.
What's Changed
- Add a signed-off outline artefact books are generated from by @prasadtalasila in #249
Full Changelog: v5.33.0...v5.34.0
In Detail
The outline is four heading levels -- book, part, chapter, section -- and the
section is the generation unit. Three decisions are worth knowing about:
- Every part, chapter and section needs an explicit
{#id}. A slug
derived from the heading would change the moment someone reworded it,
silently orphaning every unit written against the old spelling. At chapter
scale a person notices; across 300 pages nobody does. - Sign-off lives in a sibling
signoff.md, as a digest ofspec.md.
Writing the digest into the file it measures would guarantee no later read
ever matched. It carries no timestamp, so two sign-offs of an unchanged
outline are byte-identical. spec status's non-zero exit is not a new gate. It reads back a record
of a person's decision -- did a human approve this outline? -- rather than
judging any draft's content.python -m src.draft gateremains the only
gate in the project.
src/spec/ is stdlib-only, so a genre skill can read a unit slice under bare
python with no venv, like the citation gate.
Upgrading
Nothing to do. The new command is additive, writes only under
content/specs/, and no existing command, output format or config key
changed.
v5.33.0
What's Changed
- Add a CPU-only torch build variant for docker/Dockerfile by @prasadtalasila in #248
Full Changelog: v5.32.0...v5.33.0
v5.32.0
v5.32.0 -- 2026-08-18
Summary
- A user's acronym vocabulary now has a stable, gitignored home at
content/acronyms.toml, alongsideconfig.toml, instead of an
undocumented "wherever". acronyms-suggest --applycan now write proposed entries straight to
that file, mining candidates from both a draft's glossary and its own
prose.draft stylegains a new finding for a glossary acronym whose
expansion has drifted from the vocabulary, with a matching
draft-reviserrealignment mode.
What's Changed
- Give a user's acronym vocabulary a stable home, a write path, and a
drift check by @prasadtalasila in
#246
Full Changelog: v5.31.0...v5.32.0
v5.31.0
What's Changed
- Make a Markdown draft's ASCII figure a file, matching thesis-chapter-writer's pair by @prasadtalasila in #247
Full Changelog: v5.30.2...v5.31.0