Skip to content

TEST ONLY: package and managed-library acceptance on dev - #92

Closed
jeremymanning wants to merge 70 commits into
ContextLab:devfrom
jeremymanning:cdlbib-core-package
Closed

jeremymanning wants to merge 70 commits into
ContextLab:devfrom
jeremymanning:cdlbib-core-package

Conversation

@jeremymanning

@jeremymanning jeremymanning commented Oct 4, 2026 •

Copy link
Copy Markdown
Member

This temporary test PR exercises the installable cdlbib package, managed library and entry completion against dev. Current candidate: d9ef0c1.

The package downloads and updates a managed bibliography, preserves backups and unsent edits, proposes metadata using the existing formatter, and sends checked changes through the user's fork. The CI setup now supplies a shared public Crossref contact for fork PRs and uses isolated fixtures for colored output, Git identity and headless keyring discovery.

Five local installed-package configurations passed at b3c5fd5; application source and package metadata are unchanged since that checkpoint. Subsequent fixture/configuration repairs passed focused checks and review. Final validation passed at d9ef0c1: both complete Linux suites report 2,629 passed and 33 environment-dependent skips (Python 3.11: 1001.00s; Python 3.13: 937.73s). All nine installation tests now run. Autocheck/build: https://github.com/ContextLab/CDL-bibliography/actions/runs/37230904915. Citation verification: https://github.com/ContextLab/CDL-bibliography/actions/runs/37230904898. The shared contact is nonempty and masked in all consuming jobs. Fresh final wheel/sdist builds and strict Twine checks also passed; unpacked wheel contents match the locally validated wheel exactly.

Owner-authorized acceptance test completed; closing without merge. The implementation branch is preserved for the final contribution. Separate bibliography-only PR93 successfully exercised installed-package send and update of the same PR with exact pushed-byte comparisons; it is closed unmerged and its disposable branch is deleted.

jeremymanning and others added 30 commits October 1, 2026 19:23
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FYjLZgb3AH6E7FDc4fRmjQ
…tests import the package

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FYjLZgb3AH6E7FDc4fRmjQ
…nd numpy

Ranges replace exact pins; requirements*.txt removed. compound_acronym docstring made raw (SyntaxWarning on 3.13). Ignore src/*.egg-info, dist, build.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FYjLZgb3AH6E7FDc4fRmjQ
…dir in the package

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FYjLZgb3AH6E7FDc4fRmjQ
…n ledger per command run

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FYjLZgb3AH6E7FDc4fRmjQ
…y; CI uses the package

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FYjLZgb3AH6E7FDc4fRmjQ
…b.research_forms)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FYjLZgb3AH6E7FDc4fRmjQ
… api failures are CdlbibErrors

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FYjLZgb3AH6E7FDc4fRmjQ
… rule in verification; CLI no-login tests

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FYjLZgb3AH6E7FDc4fRmjQ
…t 60 s; unreadable keychain is reported by type

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FYjLZgb3AH6E7FDc4fRmjQ
…ers the install; Ctrl-C at the prompt aborts cleanly

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FYjLZgb3AH6E7FDc4fRmjQ
…nt or the keychain

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FYjLZgb3AH6E7FDc4fRmjQ
api.send: other changed files refuse, then the gate, the GitHub login and the fork;
only then a commit of cdl.bib and verification/ on cdlbib/<login>/<date>-<slug>, a push
to the user's fork and a pull request. A fork is created only after --yes or a Yes at
the prompt. cdlbib commit and magic go through it; the local commit is gone.

tests/test_machinery_2026_09_25.py::test_commit_refuses_an_unresolved_entry_and_commits_only_the_bib
asserts the replaced local commit and now fails; left unedited for the owner's decision.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FYjLZgb3AH6E7FDc4fRmjQ
…est; resolve a fork checkout to its parent

A failed commit puts the checkout back; a failed push or pull request names the branch
and the resume. A branch whose pull request is merged or closed is refused before git is
written to. A checkout cloned from the user's own fork sends to the fork's parent; only
github.com URLs parse; a failed gh call is never read as 'no fork'; a fork of a fork is
never created. Nothing to send is refused before any login or fork lookup. A change is
never pushed to the upstream. commit --outfile and its two messages are back; the
committed files are listed.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FYjLZgb3AH6E7FDc4fRmjQ
… a detached HEAD; sign-in hint; more origin forms

A commit that fails on a branch that already existed returns the checkout to the branch
it came from and unstages only what the send staged. A checkout on no branch is refused up
front. A push that cannot sign in names gh auth setup-git. Origin URLs: http, git:// and
ssh with a port, github.com only. A branch whose pull request is merged or closed is
refused whether or not the checkout is on it; the steps name the upstream. The fork-only
test route is keyword-only and named _test_inside_own_fork. Tests cannot reach a fork
creation or a push outside the guarded fork.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FYjLZgb3AH6E7FDc4fRmjQ
… permission; no branch suggested that nobody named

The unasked-fork test uses the tester's own fork as its upstream and checks that the
account gained no repository. A failed push says once how to resume; a push refused for
want of permission points to gh auth status. A detached checkout is told to switch to a
branch, and master is named only when the caller gave it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FYjLZgb3AH6E7FDc4fRmjQ
…nd, package paths and current options

Factual updates only: bibcheck.py/bibverify.py -> cdlbib, requirements files ->
pyproject.toml, --reviewer/--by removed (GitHub login from gh), the key-file
route replaced by environment variable then keychain, module paths under
src/cdlbib/, commit now sends a pull request, autocheck jobs test and build.
No policy wording changed. Not to be pushed before the owner approves the text.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FYjLZgb3AH6E7FDc4fRmjQ
…ist, screencast script

docs/tutorials.md (check the library; contribute a pull request; setting an API
key), docs/releasing.md (manual checklist), scripts/make_screencasts.sh with its
two vhs tapes, and one README line pointing to the tutorials. No media is
committed. Not to be pushed before the owner approves the text.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FYjLZgb3AH6E7FDc4fRmjQ
…moves what it created and refuses a ContextLab checkout

The check cast replaces OUTPUT_DIR/library only when it carries the script's
marker file; OUTPUT_DIR may not be empty, / or the home folder. The commit cast
refuses a checkout whose origin is owned by ContextLab or is not on GitHub, and
needs --i-understand-this-opens-a-real-pull-request. Not to be pushed before
the owner approves the text.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FYjLZgb3AH6E7FDc4fRmjQ
The command is named send (it matches api.send); commit is gone. A send commits and
pushes only cdl.bib and changed files under verification/. Every other modified, staged
or untracked file stays exactly as it was and is listed after a successful send; it is
no longer a reason to refuse. A send branch git cannot switch to is refused whole.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FYjLZgb3AH6E7FDc4fRmjQ
…ls reports a bad key in one line; verify help; SPDX licence field

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FYjLZgb3AH6E7FDc4fRmjQ
The commit command is now send in the README, CONTRIBUTING, the tutorials and
the screencast script and tape. send commits and pushes cdl.bib and changed
files under verification/; other files with uncommitted changes are left as
they are. The README test paragraph names the test files that need the
network, a contact address, a GitHub login or the local paper library instead
of counts.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FYjLZgb3AH6E7FDc4fRmjQ
docs/media/check.gif (130,310 bytes) is embedded in docs/tutorials.md.
scripts/make_screencasts.sh writes to docs/media by default, refuses any other
folder inside the repository, /, the home folder and an empty value, and works
on a mktemp copy of the library outside the repository that it removes when it
ends. The send cast stays unrecorded and keeps its guard.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FYjLZgb3AH6E7FDc4fRmjQ
…yPI page (docs/pypi.md)

Not wired in: pyproject.toml still has readme = "README.md". Written for a
reader who has not seen the repository; nothing in it says the package is on
PyPI today. Not to be pushed before the owner approves the text.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FYjLZgb3AH6E7FDc4fRmjQ
…; used as the package description

docs/pypi.md is cut to a short page with the owner's two introduction
paragraphs verbatim, and pyproject.toml's readme now points to it. Usage
material stays in README.md and docs/tutorials.md.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FYjLZgb3AH6E7FDc4fRmjQ
…ge is published)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FYjLZgb3AH6E7FDc4fRmjQ
…a terminal, adapter commands, Python usage

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FYjLZgb3AH6E7FDc4fRmjQ
jeremymanning and others added 28 commits October 2, 2026 16:34
… skipped-check line names the retry; pseudo-ref branch names refused

- An old backup that cannot be deleted no longer turns a completed undo or
  backup into a PermissionError traceback: pruning never fails the operation,
  and a note names the backup folder that was left (also for the update).
- "update check skipped: ..." says what happens next: tried again automatically
  in about an hour, and `cdlbib update` tries now (or, after `cdlbib update`
  itself, to run it again).
- A backup whose recorded branch is `@`, HEAD, AUTO_MERGE or a *_HEAD pseudo-ref
  is refused before anything is changed.
- `cdlbib update --undo STAMP` for a backup that is there but unreadable says
  so, with the reason; `--list` counts readable and unreadable backups apart.
- `gh api user` runs with the same scrubbed environment as every git call; a
  test reads the rule from the source.
- The tests that guard against a stalled transport left running now record the
  PIDs they saw while it ran and assert they are gone.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FYjLZgb3AH6E7FDc4fRmjQ
…ranch and updates

On a branch a send made, the daily check and cdlbib update ask GitHub for that
branch's pull request (read-only, with the fetch's time limit): open or none
changes nothing; merged with nothing else on the branch takes a backup, switches
to the default branch, fast-forwards and deletes the branch with git branch -d
(kept, and said so, after a squash merge); closed, or changes that were not in
the pull request, raise the existing question. cdlbib send from the managed
library after a merge returns to the default branch with the changes kept and
goes on, on a new branch; a library the user chose keeps the refusal.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FYjLZgb3AH6E7FDc4fRmjQ
…ted update is announced; a merge that duplicates a key is refused

Also: the count of changed entries is made from the text; a rewritten upstream
with no local work is worded as that; working copies are made in the data
folder; binary data is named; whole words are answers.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FYjLZgb3AH6E7FDc4fRmjQ
…cord

cdlbib.complete.build takes the typed fields, a Crossref record and, when there is
one, the DOI-linked PubMed record, and returns a Proposal: the proposed entry text,
each field's change and source, and the fields that could not be filled with the
helper's reason. Pure: no network, no file writing, no prompting. Values come from
the existing house helpers; a typed value no source contradicts is kept as typed; a
surname respelling is a question; a DOI that resolves to a different work fills
nothing. Fixtures are saved real records copied from the existing case files.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FYjLZgb3AH6E7FDc4fRmjQ
…es are questions; full page range from PubMed; retractions flagged; issue numbers compared by the house rule

Also: non-ASCII letters are written in the library's LaTeX form (owner decision
2026-10-02); a typed year the sources leave open is kept as a question; malformed
record parts are unfilled fields with a reason; helper exceptions other than
ValueError are no longer swallowed; typed values the format checker would rewrite
are shown in house form; a DOI is written as the record gives it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FYjLZgb3AH6E7FDc4fRmjQ
…uthor

Query (a DOI, a PMID, an arXiv id, or a title with an author and a year), identify
(the DOI's own Crossref record, never a search result; one strict title match is the
record, several are candidates), build_arxiv (the house form most arXiv entries of the
library have), checked (format check and verifier on the built entry) and propose.
A preprint that names its published version is answered with the published record,
offered as a decision. A source that does not answer gives a proposal that says so.

Tests replay 23 real responses, fetched once on 2026-10-02, through the real client
over a real cache with the offline transport; three live tests make real requests.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FYjLZgb3AH6E7FDc4fRmjQ
…y library title; accents that do not survive the formatter are questions; one LaTeX brace style; retraction banners, prefixed pages and compound surnames

A corpus test builds every article title of the frozen library from a sentence-case
and two Title Case feeds: no unflagged capitalisation error. Proposal.complete says
whether the key and the required fields are there; an incomplete entry always needs
a decision. helpers.remove_non_letters is memoised (same results; format_title
called it once per list word).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FYjLZgb3AH6E7FDc4fRmjQ
…hecked; conference abstracts are never taken as the record; PubMed-only papers are built

A typed preprint DOI stays in the proposed text and the offered published DOI is a
question. A PMID's DOI is used only when the Crossref record is the same work as the
PubMed record. A title match must be a journal article with no sign of a conference
abstract (venue, supplement issue, no page range or article number; PubMed's pages
count); a DOI that was given is still the record, with the note and a decision. A PMID
with no DOI is built from the PubMed record alone and says so. A status that is not
accepted says it comes from the first check. Trailing punctuation after a DOI is cut and
said; more identifier forms are read; the caller's client is not changed.

13 more real responses, fetched once on 2026-10-02.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FYjLZgb3AH6E7FDc4fRmjQ
… asked about; disagreeing sources and mangled names are questions

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FYjLZgb3AH6E7FDc4fRmjQ
…catalogue journal names are questions; one rule for a complete entry

In a list of several matches the note says what the Crossref record states (a single
page, no pages, a supplement issue), not that the work may be a conference abstract. On
the PubMed-only path the catalogue's place and date qualifier is removed and a journal
name neither the library nor the house list has is a question. build, build_arxiv and
propose share _set_complete. A DOI the person gave is the given value of the question
when a published version is offered; a typed DOI with punctuation after it is looked up
without it and kept as typed, as a question. The first-check note is one plain sentence.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FYjLZgb3AH6E7FDc4fRmjQ
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant