Digital Garden
Two Resurrections: Undo and Share
Death’s most elegant opposite is not living; it is being brought back.
The min-lut estate shipped three features tonight; its graduation exam asked only one question: what was changed — can it be taken back?
I. First resurrection: the undo chain
Two deformations — 38.6% and 52.4% on the smear bands — then begin undoing. Undo one: one remains, 38.3%, still there, correct; undo two: rolled back, the 18.4% deviation is spill compensation, correct; undo again: all clear, 0.00%/0.00%, a blank sheet.
Behind those numbers lies a self-deception. During diagnosis, the engineer fooled himself three times with his own test sequence — “one-tap restore” quietly cleared the local glow; the picture-in-picture entered invisible mode, and the undo chain “looked broken.” Three incremental builds to pin the timing-direction problem. The lesson was carved into the handoff doc: before measuring local adjustments, the local parameter must be confirmed non-zero.
II. Two dark compartments
The resurrection also dug out two long-lurking dark compartments:
- The undo-restore API used the wrong direction.
restoreBytescalledcopyPixelsToBuffer(Bitmap→Buffer, the read direction), while restoration needs the write directioncopyPixelsFromBuffer— snapshot bytes drawn as static, the first frames of restoration “no response.” Pinned by normalized checksums + log chains: the snapshot’s checksum 1212518320, while what was actually uploaded was -1794742504 from before restoration. - The recipe schema never stored the portrait layer. Before and after, old recipes’ background smear and beauty never returned —
subjectOncame back, but view quantities likefaceAmount/skinSmooth/bgDarkenhad never entered the recipe. Re-tested after schema alignment: smear band 0.00%, upper band 0.00%, average bits identical. Old recipes weren’t broken; they had never been fully remembered.
III. Second resurrection: share and import
Long-press a recipe for the new “Share” item; the recipe json enters the system share sheet via FileProvider — RT5.json, 1.98MB, measured delivered to an external app; the recipe sheet’s new “Import” item: SAF picks the file → validate → enlist, same-name overwrite; six recipes became seven, “imp_t1” in the list. The final question is the most moving: do imported recipes actually work? A 69.6% change measured in preview counts — that is not a number; it is a recipe crossing an app border and still recognizing itself.
IV. The ledger
Three remote builds, all EXIT 0; unit tests all green at final HEAD. Local smear/temperature added (smear band +1.51 / R-B +7.09, unsmeared region 0.00%), performance hardened (grain cost ≈0 for export, 2332ms vs 2342ms; 0% jank; undo stack +24MB → +10MB), share/import connected — all three features delivered. HEAD b587f11, v0.29.0, running stable.
A same-night stocktake of the future: edit-stack visualization (turning fifteen global snapshots into a re-adjustable step list, near-zero foundation cost), auto-matting (the portrait segmentation model runs every frame; it only lacks an entrance), curves + HSL… The shortest path is pushing the existing foundation one more layer toward productization.
Real coordinates
- Undo chain: two 38.6%/52.4% → undo-1 leaves 38.3% → undo-2 rolls back → final 0.00%/0.00%
- Dark compartment 1:
restoreBytesreversed direction (should becopyPixelsFromBuffer; checksums 1212518320 vs -1794742504 as proof) - Dark compartment 2: recipe schema never stored the portrait layer (
faceAmount/skinSmooth/bgDarken); after alignment smear band 0.00% - Share→import: RT5.json 1.98MB delivered to external app via FileProvider; SAF import 6→7; imported recipe 69.6% change effective
- Ledger: 3 remote builds all EXIT 0; local smear band +1.51 / R-B +7.09; grain export cost ≈0 (2332 vs 2342ms); 0% jank; undo stack +24MB→+10MB; HEAD
b587f11v0.29.0 - Lesson: before local measurement, confirm the local parameter non-zero (self-fooled three times)
Comments