The user's drafts in rough_drafts/ are real in-progress academic
work. Project discipline (per memory) is to keep them untracked,
but a single accidental `git add -A` could leak unpublished
scholarship into git history. Adding the pattern to .gitignore
makes the protection structural rather than discipline-based.
Scoped to .txt only (the docx->txt converted form the project
actually consumes); does not affect sample.md, .gitkeep, or any
other extensions that might land in rough_drafts/ later.
Without `if __name__ == "__main__": sys.exit(main())` at the bottom
of cli.py, `python -m cmos.cli format <path>` imports the module
but never invokes main(), so the process silently exits 0 with
empty stdout — indistinguishable from a successful run that
produced no output. Discovered during real-draft testing on
2026-04-11.
Adds a regression test that subprocesses the CLI with --help and
asserts on stdout content. argparse --help exits 0 in both broken
and fixed states; stdout content is the only discriminator.
Both invocation paths now work:
- uv run cmos format <path> (pyproject script entry)
- uv run python -m cmos.cli format <path> (module invocation)
Two new real-draft-derived journal exemplars locking down prompt
rule 29 from the preceding commit. Follows the Hasanah precedent
for promoting real-draft failures into the canary corpus, per the
"defense in depth" feedback in project memory.
- journal_preposition_huttunen.toml exercises "among" mid-title,
plus four other CMOS 8.159 lowercased words ("on", "in", "a",
and implicitly "among"). Real article: Huttunen and Kortelainen,
JASIST 72, no. 7 (2021). The messy_input uses the ASCII hyphen
in "Meaning-Making" for clarity — the source draft actually had
a U+2010 non-breaking hyphen from docx->txt conversion, but
mixing Unicode hyphen normalization into this exemplar would
have conflated two independent failure modes. The U+2010 issue
is noted in the exemplar comment for a separate iteration.
- journal_preposition_mehra.toml exercises "beyond" mid-title,
plus mid-title exclamation-point preservation (rule 25) and
leading-"The" drop from "The Library Quarterly" (rule 17).
Real article: Mehra, Library Quarterly 91, no. 2 (2021).
Both are canary-enabled and will block any future prompt iteration
that regresses on these patterns via the exact-match canary axis.
The canonical dicts additionally lock them down via the field-
level diff, per the upstream-refinement feedback in project
memory.
Canary corpus size: 15 -> 17.
Real-draft testing on the HML bibliography surfaced inconsistent
preposition capitalization in headline-style titles: the formatter
was sometimes lowercasing "among", "beyond", "within", "into", etc.
and sometimes capitalizing them, violating CMOS 8.159. The behavior
was nondeterministic across similar entries — smoking-gun evidence
of GPT-5 judgment drift on a rule the existing prompt only
implicitly covered via rule 6's "headline-style capitalization".
Rule 29 makes the carve-out explicit and instructs the model to
apply CMOS 8.159 independently of the source's casing, with:
- a substantial but illustrative preposition list including "as"
(which CMOS 8.159 calls out as always lowercased)
- an explicit scope restriction to PREPOSITIONS, with subordinating
conjunctions (If, That, Because, Although, Unless, etc.)
capitalized
- a CMOS 8.161 carve-out for hyphenated compounds: the first
element is always capitalized (so "In-School" stays, not
"in-School")
- a first/last-word exception covering "last word of the main
title immediately before a subtitle colon", which the model
was treating as mid-title
Verified on the 134-entry HML draft: ~17 entries now produce more
CMOS-correct forms, and two consecutive re-runs show no new rule-
29-related regressions. Observed GPT-5 drift on orthogonal axes
(multi-author inversion, inner-quote style, periodical
italicization) washed out across re-runs, consistent with the
~5% single-run variance documented in project memory.
Rule count: 28 -> 29. No linter version bump required.