press v2.2.0
Composability and proof. The typed adapter boundary closes over the whole
package, so a direct process, environment, or tool call is now refused
anywhere outside press.adapters; every public web surface a book publishes
carries one honest metadata contract; the packaged provider ledger becomes a
generated projection of its canonical source; and the two prose checkers a
book runs are held in step by a differential corpus. The repository's own
security baseline is proven end to end, limitations recorded rather than
claimed away. Compatible within v2: no typography or layout changes, and a
book with no site-url publishes byte-identically to before.
Added
-
Opt-in read-only registration lookups (#203).
press lookup lccn <number>andpress lookup issn <number>resolve a record from the
Library of Congress and the ISSN Portal through read-only adapters, off
by default: network access is explicit, response parsing is defensive
(ElementTree expands no external entities), and every failure resolves to
an honest UNAVAILABLE rather than a crash. Withregistrations.lccnor
registrations.issnconfigured, the number argument is optional. -
A jargon-parity contract between the packaged checker and the portable
skill copy (#201, INV-editorial-jargon-parity). A differential corpus
and fuzz prove the press's jargon checker and the standalone skill agree
case for case, and a source-identity check holds their shared logic
byte-identical, so the copy an author runs cannot drift from the one CI
enforces. -
Automatic roadmap reconciliation (#197). The
Roadmap integrity
workflow reconcilesroadmap/milestones.jsonand ROADMAP.md against the
live GitHub milestones after a merge tomain(and weekly), so the
registry cannot silently drift from the issues it tracks. -
One metadata contract across every press-built web surface (#158).
Canonical URLs, Open Graph, Twitter cards, and JSON-LD now cover the docs
site, the book landing page, the reader index, and every chapter page,
generated from the book model rather than duplicated in templates.
src/press/webmeta.pyis the single emitter, so the rule that an offline
or preview build omits everything URL-shaped -- canonical,og:url,
og:image, and the URL fields inside the JSON-LD node -- lives in exactly
one place: a book with nosite-urlships no falsely-canonical output.
The book site also gains asitemap.xmlandrobots.txt, emitted only
when asite-urlis configured.verify_pagesgainscheck_metadataand
check_book_sitemap, with eleven damage fixtures they must reject.
Changed
- The typed adapter boundary is now complete (#199). The last nine
legacy modules --__main__,booklib,scaffold,selftest, and the
verify_*/gen_coverwrapfamily -- route every process, environment,
and tool-probe call through the typed adapters. The boundary gate's legacy
allowlist is deleted, so a directsubprocess/os.environ/
shutil.whichcall is now refused anywhere outsidepress.adapters, and
the import-side-effect sandbox moved toadapters/import_guard.py. Every
migrated site is proven to drive its injected adapter under a recording
fake; deterministic composition, no behavior change. - The packaged provider ledger is now a generated artifact, not a
maintained duplicate (#200).quality/providers.yamlis the one
canonical source;src/press/data/providers.yamlis a deterministic
projection of it (a fixed banner, then the canonical bytes verbatim),
regenerated bypress selftest --write-docs. The selftest and the
distribution tests now compare the packaged copy byte-for-byte against
that projection, so a comment-only or whitespace edit — drift a semantic
compare missed — fails CI, and the wheel can no longer ship a hand-copied,
divergent record. The duplicated header and footer comment in the old
mirror are gone. The update/review workflow is documented in
docs/PROVIDER-DATA.md, linked from the print-format docs.
Fixed
- Collection-policy meta-tests are warning-clean across the supported
pytest and pytest-asyncio range (#202). The nested pytest runs disable
the asyncio plugin and the root suite pins the fixture loop scope, so a
version bump within the supported range no longer raises warnings.