Repository navigation
Enforce the docs guards: rendered-site checks, inline blocks run by default, lambda and error-check lint in the suite #724
Copy link
Copy link
Closed
Labels
documentationImprovements or additions to documentationImprovements or additions to documentationready-for-agentUnblocked and fully specified; an agent may claim itUnblocked and fully specified; an agent may claim itsize:MNeeds a plan; one or two local workersNeeds a plan; one or two local workers
Description
Parent
What to build
With every page and docstring fixed, the opt-in checks become gates so the rot cannot return:
tests/test_docs_site.pyfails on literal Sphinx roles,Returns:/Attributes:tables with sentence-fragment rows, droppedArgs:/Attributes:sections, Markdown lists merged into paragraphs (a<p>containing a line that starts with-or1.), and unresolved cross-references.- Every inline Python block runs unless its fence says why it is compile-only.
tests._docs_checksruns overdocs/pages,docs/examplesandsrc/ferroas a test.- The four many-to-many tests skipped with a reason pointing at a page that no longer exists run or are deleted;
tests/test_documentation_features.pykeeps only what the docs harness does not cover. # noqacomments are kept out of rendered examples by a ruff per-file ignore fordocs/examples/*.- CI runs the docs tests in the docs job.
Acceptance criteria
- Each defect class above has a test that fails on a seeded example of it.
- No inline block is compile-only without a stated reason.
-
python -m tests._docs_checks docs/pages docs/examples src/ferroexits 0 and runs in the suite. - No test is skipped with a stale reason.
Files owned
- Create:
tests/test_docs_lint.py - Modify:
tests/test_docs_examples.py,tests/test_docs_site.py,tests/test_documentation_features.py,tests/_docs_checks.py,.github/workflows/ci.yml,pyproject.toml,docs/pages/**(fence markers only),docs/examples/**(noqa comments only)
Interfaces
- Consumes: everything the earlier tickets produce
- Produces: nothing other tickets rely on
Test scenarios
- Error path: seeding
:class:into a docstring fails the site test. - Error path: seeding
lambda t: t.idinto a page failstests/test_docs_lint.py. - Error path: a list without a blank line before it fails the site test.
- Happy path: the whole docs suite passes in CI.
Verify
uv run --no-sync zensical build --clean --strict
uv run --no-sync pytest tests/test_docs_site.py -q --no-cov -p no:cacheprovider
uv run --no-sync pytest tests/test_docs_examples.py -q --no-cov -p no:cacheprovider -n 8
uv run --no-sync pytest tests/test_docstring_examples.py -q --no-cov -p no:cacheprovider
uv run --no-sync pytest tests/test_docs_migrations.py -q --no-cov -p no:cacheprovider -n 8
uv run --no-sync pytest tests/test_docs_lint.py tests/test_documentation_features.py -q --no-cov -p no:cacheprovider
uv run --no-sync python -m tests._docs_checks docs/pages docs/examples src/ferroBlocked by
- Docs site config: Zensical features, Markdown extensions, API reference options and a strict build #701, CLI help keeps its placeholders:
ferro migrate --helpprints<name>,<migration>:<step>and the rest #702, AGENTS.md: rewrite I-8 for the lambda-only query API, add a docstring invariant, record the docs conventions #703, Docs harness: run inline blocks with a prelude, run docstring examples, and check lambda names and error checks #704, Get started pages: home page and README, Why Ferro, installation and quickstart #705, Project pages: FAQ, roadmap, contributing and changelog #706, Upgrade guide covers every release up to the current one #707, Models and fields page with a generated field type table #708, Queries guide and the typed predicates concept page: lambda-only story, results shown, one running example #709, Aggregations guide: real data without ties, results shown, error checks that can fail #710, Mutations, transactions and connections guides, and the multiple-databases how-to #711, Relationships and raw SQL guides #712, Schema management pages: fix stale facts and pin every quoted generated step file #713, Split the migrations guide: tutorial loop, how-tos, a squash page, and reference tables in Reference #714, Split the row-level security page and fix its example #715, How-tos: testing, pagination, timestamps and soft deletes #716, Migrating from SQLAlchemy: show sessions, make every block run #717, Concepts pages: architecture, identity map, type safety, backends and performance #718, Docstrings: Model, Query and relations #719, Docstrings: connect, fields, checks, row security, raw SQL, sessions, settings and exceptions #720, Docstrings: the migrations API, PassReport and the CLI commands #721, API reference completeness: every public object has an entry, pages named after their objects #722, Navigation: six tabs, sentence-case labels that match page titles, moved pages redirected #723
Audit findings
Rows from the docs audit this ticket covers (file, line, rule, fix)
Cross-cutting patterns
- I-8 one-letter lambda parameters in four embedded examples: 66 lambdas (
aggregations24,partial_selects16,populated_relations15,existence_tests11), plus 6 in their twins' bodies and 57 lines in inline page blocks.predicates.py,traversal.py,relationships.pyandquickstart.pyshow the correct form. Fix the four files and add a lint test (an AST check ofdocs/examples/*.pyand inline blocks: a lambda passed towhere/select/order_by/include/existstakes a parameter of at least two characters, ideallysnake_case(Model)). - Error checks that cannot fail: 12
try/exceptblocks assert only insideexcept, with noelse(aggregations ×5, populated_relations ×3, partial_selects ×1, mutations ×3). The "loud limits" the pages advertise are untested.table_checks.py:38shows the fix. - Results hidden below the section marker in about 50 sections across 9 files. The reader sees a query, never its answer (rule 8). Only three snippets print anything, and no page shows printed output from an example.
- Placeholder data (rule 10) in 5 files:
"a1"/"b1"/"o1"/"ledger-a"/"Pair left/right", with tied totals that make a top-N example nondeterministic.relationships.py,predicates.pyandmigrations_backfill.pyshow the real-looking alternative. - No equivalent SQL beside any example (rule 13). Comments describe the SQL ("renders NOT EXISTS", "COUNT(column)") in 6 files, and the query pages show 5 SQL blocks for 101 Python blocks.
- 184 inline page blocks are compile-only (rule 9). The
{test=run}/{lint=check}opt-ins exist and are used 0 times. Five pages hold 83 of them (models-and-fields24,migrate-from-sqlalchemy18,upgrade-guide17,row-level-security13,connections11).tests/test_documentation_features.pytests hand copies, not the docs, and 4 of its tests are skipped with a stale reason. - Running-example models the page never shows (rule 3) in 4 files:
Customer(mutations),Account(transactions),Event(raw_sql),Metric(multiple_databases). The models sit outside any section, so the I-7 twin is also skipped. - Two Annotated idioms across twins:
Field(default=None, …)insideAnnotatedin 11 pairs, againstFerroField(…)] = Nonein 7 pairs. Plus 18# noqa: E711/E712comments rendered on pages, avoidable with a ruff per-file ignore fordocs/examples/*.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
documentationImprovements or additions to documentationImprovements or additions to documentationready-for-agentUnblocked and fully specified; an agent may claim itUnblocked and fully specified; an agent may claim itsize:MNeeds a plan; one or two local workersNeeds a plan; one or two local workers
Activity
5 remaining items
ferro migrate --helpprints<name>,<migration>:<step>and the rest #702feat(docs): docs examples harness — prelude fences, docstring example…
0x054 commentedon Oct 19, 2026
Status: verify-passed
Worker: worker-724
Branch:
sdd/724-enforce-guardsPR: #750
Verify: passed ccc1616
Review by reviewer-724: Spec PASS, Quality PASS, with no Critical or Important findings. The four seeded defects each failed their test (
:class:, a merged list,lambda t: t.id,{compile-only=}). The full suite passed: 3514 passed, 338 skipped, 2 xfailed. Trial merge not run (base unchanged).Many-to-many
clear()and reverse-side reads are tested on both backends:tests/test_auto_migrate.py:173,182,339,348(backend_matrix). The PR body's claim that no such Postgres test exists is wrong (Minor).test(docs): enforce the docs guards as gates (#724) (#750)
0x054 commentedon Oct 19, 2026
Merged in #750 into
feat/docs-rewrite