Skip to content

F3: enforce paper-folder completeness as a hard gate#42

Open
frastlin wants to merge 2 commits into
masterfrom
feat/f3-completeness-gate
Open

F3: enforce paper-folder completeness as a hard gate#42
frastlin wants to merge 2 commits into
masterfrom
feat/f3-completeness-gate

Conversation

@frastlin

Copy link
Copy Markdown
Collaborator

Resolves #35.

What & why

scripts/lint_paper_schema.py already implemented the substance of this feature — required-file presence, abstract.md with both an ## Original Text (Verbatim) and an ## Our Interpretation section, and exit 2 on any violation. The gap was enforcement and consistency, not logic. This PR is the hardening + wiring the spec called for (it deliberately does not re-implement the checks).

Changes

  • scripts/lint_paper_schema.py — add a PEP 723 block (pyyaml) so it is uv run-able as a gate; docstring now states it is the single source of truth for paper-folder completeness (F3).
  • Reconcile skills/lint-paper/SKILL.mdabstract.md and citations.md are now REQUIRED (were "recommended"), abstract.md must carry both sections, and a new Step 3 runs the mechanical linter as the authoritative exit-2 gate. This closes the drift loophole where the lenient grep linter disagreed with the mechanical one.
  • Wire the gate as a mandatory final step in process-new-papers, ingest-new-papers, and ingest-collection: a non-zero exit is a hard block — the wave is not done and drafting must not start.
  • tools/sync_skill_launchers.py — add lint_paper_schema.py launchers for those four skills; regenerated. Drift/parity tests stay green.

Tests (TDD)

Focused regression guards added to test_lint_paper_schema.py: ABSTRACT_MISSING, CITATIONS_MISSING, ABSTRACT_SECTIONS (abstract present but missing the interpretation section), and main() exits 2 on an incomplete paper.

Full suite green: 177 passed, 53 subtests. Verified the generated launcher exits 2 on an incomplete collection.

Scope notes

The optional stray-file allowlist / --strict flag from the spec were intentionally not added: the spec marks them optional and warns that new violation codes change what counts as a passing wave. The existing exit-2 behavior already provides "strict wave mode."

Dependencies

Second in build order F4 → F3 → F2 → …. Depends on #34 — F4's DIR_KEY_MISMATCH ships inside the same gate this PR wires, so the gate also enforces dir == cite_key.

🤖 Generated with Claude Code

frastlin and others added 2 commits June 30, 2026 13:55
Overturns the B5 dir/cite_key decoupling (signed off 2026-06-30): a paper's
directory name must now equal its cite_key.

- lint_paper_schema.py: new DIR_KEY_MISMATCH violation (exit 2) when a paper
  dir name != its derived cite_key.
- rename_to_cite_key.py: dry-run-by-default migration that renames mismatched
  dirs to their cite_key and rewrites every reference (index.md, _reader_done.tsv,
  keymap.tsv, ../<dir>/notes.md links and [[dir]] wikilinks in sibling files).
- paper-reader/SKILL.md: name new paper dirs from the cite_key so they are born
  compliant; metadata rule now requires dir == cite_key.
- build_keymap.py: docstring records the new invariant; keymap.tsv is now an
  identity cache.
- README: document rename_to_cite_key.py.

Tests: DirKeyMismatchTests (mismatch reported, match passes, year-differs-but-
key-matches, main() exits 2) + test_rename_to_cite_key.py (plan, dry-run touches
nothing, write renames + rewrites refs with no dangling links, idempotent).

Closes #34

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012MKtQ1Dfg5qYWhobNKk7jP
lint_paper_schema.py already implemented the substance (required files,
abstract.md verbatim+interpretation sections, exit 2). This is the hardening +
wiring the feature asked for.

- lint_paper_schema.py: add a PEP 723 block (pyyaml) so it is uv-runnable as a
  gate; docstring states it is the single source of truth for completeness (F3).
- Reconcile skills/lint-paper/SKILL.md: abstract.md and citations.md are now
  REQUIRED (not "recommended"), abstract.md must carry both sections, and a new
  Step 3 runs the mechanical linter as the authoritative, exit-2 gate so the two
  linters can never drift.
- Wire the gate as a mandatory final step in process-new-papers, ingest-new-papers,
  and ingest-collection: a non-zero exit hard-blocks the wave before drafting.
- sync_skill_launchers.py: add lint_paper_schema.py launchers for those four
  skills; regenerated (drift test green).

Tests: focused ABSTRACT_MISSING, CITATIONS_MISSING, ABSTRACT_SECTIONS
(missing-interpretation), and main()-exits-2-on-incomplete coverage.

Closes #35. Depends on #34 (F4 DIR_KEY_MISMATCH ships in the same gate).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012MKtQ1Dfg5qYWhobNKk7jP
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.

F3: Enforce paper-folder completeness as a hard gate

1 participant