Record that persistence is now implemented and hardware-verified, and correct
the crash-recovery rule everywhere it appeared as "just promote the tmp": a
crash during the tmp write leaves a partial tmp, so recovery keeps the
committed target when both files are present and only promotes the tmp when
the target was already unlinked. Also fix the stale README heading that still
said the SD was on shared SPI2.
Re-ran the spike on the dedicated SPI3 wiring (CLK 14 / MOSI 15) with
the same clean mount + atomic round-trip result. Flip the docs from
"pending a re-run" to verified.
Document the shared-bus arbitration decision: rather than rework the
proven EPD SPI layer and add a cross-thread mutex on the save path, the
SD moves to a dedicated SPI3. Update the boot sequence, risk table,
Spike 3 postmortem follow-up, hardware overview, and firmware README.
Mark Spike 3 resolved (genuine 32 GB SDHC mounts, round-trips clean on the
shared SPI2 bus; the 133 GB SDXC's CMD59 rejection was the sole fault).
Capture the FatFS f_rename caveat and the ≤32 GB card-compatibility note in
ADR-007, the resolution in the postmortem, and the verified writeup in the
firmware README.
Drop magic adverbs (silently, arguably), a stakes-inflation flourish,
and the bold-first Snippets bullets; de-duplicate the "usable artifact,
not a checkpoint" line shared by the README and roadmap.
Bare-folder links (e.g. docs/postmortems/) only resolve on GitHub's
auto-render; retarget them to the folder's README.md so they open a
real file in any markdown viewer.
The read-only-attribute theory (and the predicted AM_RDO unlink shim) was
wrong. A diagnostic recursive walk showed every entry writable (ro=false)
and succeeded via path-based deletion, so the real blocker was
std::fs::remove_dir_all's openat/unlinkat/fdopendir usage against esp-idf's
path-based FATFS VFS. Update the increment-A/B checklist accordingly.
Increment A (persistent-clone publish cycle) is hardware-verified: clone +
persistent open + fast-forward push. Mark the follow-up checklist: git module
fold is in progress (A done; B = divergence + AM_RDO unlink shim; C = editor
wiring), tech-doc revision done, PAT-in-flash tracked as open ADR-011. Note
the FAT read-only-delete limitation and the real-notes-repo sizing caveat.
The PAT-in-flash shortcut (ADR-005 v0.1) is safe for the dev's bench unit
but not for a shipped one: it's plaintext in flash, the same token on every
unit, and rotation needs a reflash. ADR-005 decided the auth model but left
provisioning mechanics open.
Capture that as ADR-011 (Proposed/Open): the options (build-time bake →
on-device paste → eFuse-encrypted NVS, per-device fine-grained PAT, GitHub
App) and the likely shape, deferred beyond v0.1. It gates the first non-dev
distribution. Point the Spike 7 postmortem's shortcut entry at it.
Git now runs on its own 96 KB std::thread and the main-task stack is back
to 12 KB — hardware-verified off-main. Update the follow-up checklist and
the "three bugs" caveat to reflect the completed move.
The certificate_check bypass is retired (real trust-store, hardware-verified
2519ed8) and the product sync transport is decided (HTTPS+PAT, not SSH, since
on-device libgit2 is HTTPS-only). Remaining shortcut is PAT-in-flash.
The full init -> commit -> push over mbedTLS HTTPS now runs on hardware
(verified device-side + via git ls-remote). Documents the three fixes that
got there -- 96 KB main stack, remove-then-rename p_rename, and the utimes
existence-gate that had silently dropped every ODB write -- plus the
shortcuts still standing (cert bypass, PAT-in-flash, SSH-vs-HTTPS remote).
CFLAGS include-injection cascades through the whole esp-idf component
graph (arpa/inet.h -> sys/ioctl.h -> ...), so path 1 is out. Decide
path 2: libgit2 as an esp-idf CMake component with USE_HTTPS=mbedTLS,
which fixes the includes and the TLS backend together.
libgit2 C cross-compiles for xtensa; blocker is missing esp-idf lwIP
headers (arpa/inet.h) because libgit2-sys builds standalone. PSRAM
enabled and hardware-verified.
Postmortem + ADR-004 outcome note + risk-table update: gitoxide has no
HTTP(S) push, so v0.1 falls back to libgit2; the on-device libgit2 <->
mbedtls cross-compile is the next gate.
New docs/postmortems/ folder. The bench card (133 GB SDXC) rejects CMD59
(SPI-mode CRC) as illegal; CMD0/CMD8 succeed, so wiring and firmware are
proven and the fix is a compliant card. Captures the root cause, the
keep-CRC-required decision, and the reusable findings (EPD bus lock, LFN
requirement, R1-byte diagnostic) before the work pauses for hardware.