v1.1: harden recovery and control boundaries
WP-D and WP-E complete the planned v1.1 implementation packages. WP-D — recovery honesty: - backups verify the completed copy with PRAGMA integrity_check - corruption missed by quick_check is detected by the full check - existing good backups remain protected - oversized exports are still delivered but declare whether this version can import them, while the 20 MB import limit remains unchanged - backup was exercised through the real browser UI on both the normal campaign database and a campaign-shaped database over 100 MB WP-E — control-boundary contrast: - interactive control boundaries meet the WCAG 1.4.11 3:1 target - the contrast audit is now a failing gate rather than an advisory - rendered browser measurements pass for the composer, controls, tabs and nav - text contrast and focus visibility remain intact - owner reviewed and approved the before/after screenshots Reports: - planning/reports/v1.1/V1.1-WP-D-REPORT.md - planning/reports/v1.1/V1.1-WP-E-REPORT.md All planned v1.1 work packages A-E are now complete. Release validation has not yet begun.
This commit is contained in:
+20
-9
@@ -39,8 +39,9 @@ turn is blocked.
|
||||
never leaves a half-written file wearing a backup's name. `os.replace` is
|
||||
atomic on the same filesystem, which is why the temporary sits in the
|
||||
destination's own directory rather than in `/tmp`.
|
||||
3. `PRAGMA quick_check` runs against the finished copy, opened as its own
|
||||
database, before it is renamed. A backup nobody verified is a belief.
|
||||
3. `PRAGMA integrity_check` runs against the finished copy, opened as its own
|
||||
database, before it is renamed. A backup nobody verified is a belief. v1.1
|
||||
WP-D made this the full check rather than `quick_check`; see `_verify`.
|
||||
4. An existing file is never overwritten. Each run writes a new name stamped
|
||||
with the time, so yesterday's backup survives today's mistake — which is most
|
||||
of what a backup is for.
|
||||
@@ -189,18 +190,28 @@ def _copy(source_path: Path, working: Path) -> int:
|
||||
|
||||
|
||||
def _verify(working: Path) -> str:
|
||||
"""Runs `PRAGMA quick_check` against the finished copy.
|
||||
"""Runs `PRAGMA integrity_check` against the finished copy.
|
||||
|
||||
Opened as its own connection, so what is checked is the file on disk rather
|
||||
than any page cache the copy left behind. `quick_check` rather than
|
||||
`integrity_check` because it does the structural work — every page reachable,
|
||||
every record readable — without the full index cross-check, which on a large
|
||||
database is minutes rather than moments. A backup nobody verified is a
|
||||
belief; a backup verified slowly enough that nobody takes one is worse.
|
||||
than any page cache the copy left behind.
|
||||
|
||||
**v1.1 WP-D: the full check, not `quick_check`.** M9 chose `quick_check` for
|
||||
its speed, on the argument that a backup verified slowly enough that nobody
|
||||
takes one is worse than a fast one. The measurements say the trade was not
|
||||
needed here: `quick_check` omits the cross-check between a table and its
|
||||
indexes, and that is a real class of damage it reports as `ok`. A copy whose
|
||||
index disagrees with its table restores into a database that answers queries
|
||||
with rows that are not there — the failure a backup exists to prevent.
|
||||
|
||||
The cost is small at the sizes this application produces: on the 100-turn
|
||||
evidence campaign both checks are a few milliseconds, and on a synthetic
|
||||
database two orders of magnitude larger the difference is still short of a
|
||||
second (WP-D report §E). A backup nobody verified is a belief; this is the
|
||||
check that makes it a fact.
|
||||
"""
|
||||
connection = sqlite3.connect(f"file:{working}?mode=ro", uri=True)
|
||||
try:
|
||||
rows = connection.execute("PRAGMA quick_check").fetchall()
|
||||
rows = connection.execute("PRAGMA integrity_check").fetchall()
|
||||
finally:
|
||||
connection.close()
|
||||
result = ", ".join(str(row[0]) for row in rows) if rows else "no result"
|
||||
|
||||
Reference in New Issue
Block a user