Repository navigation
Upgrade guide covers every release up to the current one #707
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
The upgrade guide stops at 0.15 while the package is at 0.25.0, and one recipe subclasses ferro.Ferro, which does not exist. Each release from 0.16 to the current one gets a section listing what an upgrade asks of the user (from CHANGELOG.md and the release PRs), and every before/after recipe uses real classes, shows both declaration styles, and runs. The implicit-routing removal is attributed to the release CHANGELOG.md records (0.14).
Pages: howto/upgrade-guide.md
Acceptance criteria
- Every fact on the page matches the code at the time of the PR; each High finding in the audit rows below is fixed, and each Medium/Low finding is fixed or answered in the PR body with the reason it was left.
- Each page is one kind (tutorial, how-to, reference or explanation) and opens with one sentence saying what it covers, then an example on the first screen (writing-for-humans rules 1–2).
- Each page uses one running example, declared once near the top and reused; each section shows only what changed (rule 3).
- Every code block has a lead-in sentence ending in a colon and a result sentence after it, and shows its result: printed output, or the asserted value inside the embedded snippet range (rules 7–8). Snippet
end:markers sit below the assert or print that holds the result. - Every copyable block either shows the
async with engines.session():wrapper or sits under a sentence that says it runs inside one and links to Connections › Sessions; the page's first block shows the wrapper. - Every inline Python block that does real work runs under the harness (
{test=run prelude=<name>}) or moves into an example script; a block left compile-only says why in its fence marker. - Every lambda passed to a query method names its parameter after the model in lowercase singular (AGENTS.md I-8);
python -m tests._docs_checksreports no violation for the owned files. - Every error check in an owned example fails when the expected error is not raised (
try/except/else: raise AssertionError, or the harness helper). - Field-declaring examples show both declaration styles as tabs, each backed by a runnable script (AGENTS.md I-7), and the twins use the one Annotated idiom recorded in the docs conventions.
- Headings are short sentence-case noun phrases naming the feature (rule 5); how-to titles name the goal (rule 24); no minimising words (rule 17); admonitions follow rule 20.
- No ADR numbers, issue numbers, codenames, dated or release-bound notes, or contributor-only references in page text; version markers are self-contained blocks at the end of a section.
- Reference material that has a home in Reference is linked, not repeated; each topic ends with a pointer to its reference entry (rule 4).
- Every version from 0.16.0 to the version in
pyproject.tomlhas a section, or a one-line note that it needs no action.
Files owned
- Create:
docs/examples/upgrade_*.py(one pair per recipe that declares fields) - Modify:
docs/pages/howto/upgrade-guide.md
Interfaces
- Consumes: I-8, I-14, docs conventions (AGENTS.md ticket (AGENTS.md: rewrite I-8 for the lambda-only query API, add a docstring invariant, record the docs conventions #703))
- Consumes:
{test=run prelude=<name>},tests._docs_checks(harness ticket (Docs harness: run inline blocks with a prelude, run docstring examples, and check lambda names and error checks #704)) - Produces: nothing other tickets rely on
Test scenarios
- Happy path: the strict site build succeeds and every snippet range on the owned pages renders without leading indentation.
- Happy path: every owned example script runs to completion under
tests/test_docs_examples.py, and every inline block marked{test=run ...}runs. - Error path: deleting the
raisean owned example's error check expects makes that example's test fail. - Edge case:
python -m tests._docs_checksover the owned files exits 0; renaming one lambda parameter totmakes it exit 1 naming the file and line.
Verify
uv run --no-sync zensical build --clean --strict
uv run --no-sync pytest tests/test_docs_examples.py -q --no-cov -p no:cacheprovider -n 8
uv run --no-sync python -m tests._docs_checks docs/pages/howto/upgrade-guide.mdBlocked by
- Docs site config: Zensical features, Markdown extensions, API reference options and a strict build #701, 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
Audit findings
Rows from the docs audit this ticket covers (file, line, rule, fix)
docs/pages/howto/upgrade-guide.md
- Kind (rule 1): how-to (correct), with per-boundary agent prompts.
- Running example (rule 3): none (one per boundary, which is fine for this kind of page).
- Verdict: Its structure works (boundary sections, before/after tabs, a prompt per boundary). It stops
at 0.15 while the package is 0.25.0, it has a brokenclass Event(Ferro)example, and it uses
lambda t:throughout. Grade: C.
Version check: every version named (0.11–0.15) exists in CHANGELOG.md. pyproject.toml is 0.25.0.
Nothing on the page covers 0.16–0.25.
| Sev | Line | Rule | Finding | Suggested fix |
|---|---|---|---|---|
| H | 20–29, 49 | fact | Coverage ends at 0.15. The current version is 0.25.0 (pyproject.toml:3, CHANGELOG.md:4). A reader on 0.15 → 0.25 finds no row and cannot tell "nothing to do" from "not written". Several 0.16–0.25 changes can bite: query literals canonicalised against save() (0.16, can change SQLite after()/equality results), multi-PK models rejected at class definition, retired enum labels refusing writes, and connect(auto_migrate=…) refused on a migrations-tracked database. |
Add a row "0.15.x or later → 0.25" and either a short "Upgrading to 0.16–0.25: no breaking changes, but note …" section or explicit per-boundary sections. Let the maintainer comment require a row even when nothing breaks. |
| H | 336, 359 | 9, fact | class Event(Ferro): / class Account(Ferro):. There is no ferro.Ferro (hasattr(ferro, "Ferro") → False). The keep-recipes do not run as written. They also omit imports and use FerroField where every other page uses Field. |
class Event(Model): with from ferro import Field, Model and Field(db_type="timestamp"). Same for Account. |
| H | 333–361 | I-7 | The keep-recipes declare fields with Field() options (db_type=, db_check=) in assignment style only. |
Add an Annotated twin, e.g. tabs "Keep (assignment)" / "Keep (Annotated)", or nest Assignment/Annotated tabs inside "Keep". |
| H | 150, 164–165, 184, 194, 487; prompts 111, 445 | I-8 | Lambda parameters are t / m, not the model name: User.where(lambda t: t.age >= 18), order_by(lambda t: t.created_at, …). |
lambda user: user.age >= 18, lambda user: user.active == True, lambda event: event.created_at. The table cell becomes where(lambda user: ...). |
| M | 168–177, 488 | fact | The page says implicit routing was "removed in 0.13" (the runtime error says the same). CHANGELOG.md has no such entry under v0.13.0. "single-handle routing" (#201) is recorded under v0.14.0 (line 879). The table row at line 29 ("stopping at 0.13 … plus the connection-routing note") depends on this. |
Confirm the release that removed it and align the page, the runtime message and the table. |
| M | 37–47 | fact | "This catches every deprecation-based change." A reader jumping from 0.11 straight to 0.25 hits removed APIs (AttributeError, RuntimeError), not DeprecationWarnings, so the gate catches nothing. |
Add: "If you are skipping past 0.14, the deprecated APIs are already removed and fail with AttributeError/RuntimeError; run the suite on 0.13 first, or apply the prompts before upgrading." |
| M | 340, 363, 376, 132 | fact (stale) | The convert recipes say "reviewed Alembic migration" only. Ferro now ships its own migrations door (ferro migrate new, hand-written steps). |
"a reviewed migration (a hand-written step in ferro migrate, or an Alembic revision)". |
| M | 154–166, 179–196, 205–227, 269–282 | 7 | Before/after tab groups have no result sentence. Readers are not told what the "After" returns or raises. | One sentence after each group, e.g. "Both queries return the same rows; only the predicate spelling changed." |
| L | 9, 198, 229, 262, 284 | 5 | "Upgrade Guide" is in title case. Several H3s are sentences ("create() no longer overwrites on primary-key conflict"), and identifiers in headings lack code font. | Title "Upgrade guide"; "create() on a primary-key conflict", "save() and upserts", "limit()/offset() on mutations", "Typed exceptions". |
| L | 22–29 | completeness | The table lacks "0.11.x or earlier → 0.15" (all three sections) and "0.14.x → 0.15" is the only 0.15 single-hop row. |
Generate the table as "from X: read sections X+1…current". A range rule reads better than enumerated pairs. |
| L | 90, 320 | 22 | "ADR-0005" and the repo path docs/solutions/patterns/derived-type-and-naming-decision-table.md point at files not on the site. |
Link to GitHub, or drop them. |
| L | 58, 101, 436 | ext | ??? example collapsible prompts are a good use of details. Keep them. |
— |
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
docs: schema pages fixed against the generator, quoted step files pin…
0x054 commentedon Oct 19, 2026
Status: verify-passed
Worker: worker-707
Branch:
sdd/707-upgrade-guidePR: #741
Verify: passed e27d99a (and on trial merge into
feat/docs-rewriteacd1127)Re-review of the fix round: spec PASS, quality PASS. The 4 dead anchors, the stale v0.13 output in
guide/connections.mdand the mislabelled 0.14 tab are all addressed. The only red on the merge is 3tests/test_docs_migrations.pyRLS tests, already on the base (fixed by #744).docs(guide): upgrade guide covers 0.16 to 0.25 (#707) (#741)
0x054 commentedon Oct 19, 2026
Merged in #741 into
feat/docs-rewritedocs: split the migrations guide into the loop, renames and retiremen…