-
v0.2.0 — Phase 1 completion
Stablereleased this
2026-08-03 18:34:16 +00:00 | 50 commits to main since this releasePhase 1 is finished and verified. All 34 issues on the milestone are closed.
Exit criteria met: every Phase 1 acceptance criterion is verified by an automated test, projections are provably derivable from history, and no known silently-wrong-data path remains.
1109 backend tests · 58 component tests · 7 end-to-end journeys.
This tag also carries the v0.1.1 security milestone, which closed on 2026-07-30 and was never tagged separately — the unauthenticated-to-RCE chain, revocable sessions, the Pillow sandbox, rate limiting, and the audit ledger's append-only triggers. The changelog splits the two.
What landed
Things that had nothing behind them.
ai-rerunandocr-reruncreated jobs from v0.1.0 onward and the Jobs page rendered them, butapp/workers/held only an__init__.py— nothing ever claimed a job. The worker runtime, the Claude vision backend with its cost ledger and spend ceilings, and Tesseract OCR now make those buttons do something.Bugs that were writing wrong data. Scanner timestamps recorded as capture dates. A
review_versionguard that raced. Pagination that silently dropped photographs from a bulk-ingested collection. A filename parser that read a year as a sequence number and accepted3999-01-01as a day-precision date atmediumreliability — which is what puts a photo in front of a reviewer.Silent-failure paths closed.
patchNotesandpatchFlagshad no error handling at all, so a refused save left the reviewer's text on screen with nothing to say it had not been written. A failed evidence fetch rendered as "No evidence yet." — a claim about the archive that nothing had established.The contract. Every route returned an untyped dict; the frontend's types were hand-maintained and had drifted twice. Now Pydantic response models end to end, with
openapi.jsonand the generated TypeScript regenerated and diffed in CI.Security. Production now refuses to start on an insecure configuration, and
CIRCA_ENVIRONMENTdefaults toproductionso an unconfigured deployment fails closed rather than serving family photographs behind a cookie signed with the key printed in the README. Storage keys gained a containment check. A development login bypass exists, with three independent guards keeping it out of production.Performance, measured. The photo list went from 15.2 ms to 0.150 ms with the right index. Media was never cacheable — every revisit re-sent a multi-megabyte original. Ingest was the only
asyncdata handler in the codebase, blocking the event loop on every hash and copy.Tests. 1109 of them, including an isolation failure they were hiding: 257 scan files had accumulated in the real
backend/storage/because three suites calledingest_photo()without redirecting storage. Nothing had failed.Full detail in CHANGELOG.md.
Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
-
Source code (ZIP)