release: zero-byte db files are corrupt and untouched; README describes 0.2.0 deliverables

- preflight now treats an existing zero-byte file as corrupt (retryable
  refusal, file left at zero bytes) instead of silently initializing
  over it; regression test added
- README overview updated for 0.2.0: database, schema, migrations,
  DAOs, append-only events, and corrupt-file startup behavior
This commit is contained in:
Joshua King
2026-09-14 09:33:02 -04:00
parent 1e1444d1a0
commit c90892f082
4 changed files with 30 additions and 3 deletions
+10 -1
View File
@@ -80,8 +80,17 @@ async def _preflight_existing_file(
def _probe() -> None:
# The file-state check and URI construction live inside the
# executor job: exists/stat/resolve are disk I/O.
if not db_path.exists() or db_path.stat().st_size == 0:
if not db_path.exists():
return
# A zero-byte file is neither missing nor a valid database: it
# is a corrupt (truncated-to-nothing) existing file, likely an
# interrupted first write. The leave-untouched contract applies
# to it too: refuse rather than silently initialize over it.
if db_path.stat().st_size == 0:
raise sqlite3.DatabaseError(
"existing database file is empty (zero bytes): file is "
"not a database"
)
# Properly escape the path: '#'/'?'/'%' in a directory or file
# name would otherwise be parsed as URI fragments/parameters/
# escapes. immutable=1: SQLite guarantees no writes and no