docs(spinel): STATUS — live at c4b39d6

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Paul Campbell pushed by claude agent, operated by paul@keymail.dev 4256b95979efc4b0479f890f3d48abd1fee8bedd parent e2c772e
1 file changed, +38 −0
  • apps/spinel/STATUS.md +38 −0
diff --git a/apps/spinel/STATUS.md b/apps/spinel/STATUS.md
new file mode 100644
index 0000000..f4eabe6
--- /dev/null
+++ b/apps/spinel/STATUS.md
@@ -0,0 +1,38 @@
+LIVE https://todo-spinel.bfj.oncarlos.com c4b39d6
+
+## Where it stands
+
+- The shared suite passes on the live host: 67 passed, 3 skipped (the two
+ JS-only edit tests with JS off, and the screenshot test with JS off).
+ It passes locally too, against the x86-64 build and against the arm64
+ binary under qemu, both with `SPINEL_GC_STRESS=1`.
+- `make test` (test/run.sh, 72 curl checks of the contract, run plain and
+ again under GC stress) passes.
+- `scripts/boot-check.sh dist/app-linux-arm64` passes.
+- `dist/app-linux-arm64` is a static aarch64 ELF, 8.8 MB, no shared
+ libraries.
+
+## Worth knowing
+
+- **Build route.** The host Spinel compiles Ruby to C; only the C compile
+ and static link run in the emulated arm64 root (`scripts/spinel-cross`,
+ `scripts/arm64-cc`). Running the arm64 Spinel itself under emulation
+ also works but took 14 minutes for hello-world, against about 3 to 5
+ minutes this way. Both Spinels are the same commit (`abf54280`).
+- **A GC bug, fixed in the tep patch.** spinelkit's `Url.parse_query`
+ holds a decoded key in an unrooted temporary while it decodes the
+ value. On arm64 a collection in between dropped every todo title longer
+ than about a thousand characters (the first live deploy, 947e5fe,
+ failed the long-title test for this reason). On x86-64 it only shows
+ under `SPINEL_GC_STRESS=1`. `patches/2-tep-bakeoff.patch` decodes forms
+ in C instead. Worth reporting upstream to spinelkit/tep.
+- **tep rewrites words inside string literals.** Its translator turns
+ `request` into `req` even inside strings, so a 403 message reading
+ "cross-origin request refused" came out as "cross-origin req refused".
+ The app's strings avoid those words.
+- **The arm64 root** now has `libssl-dev` installed (tep's HTTP layer
+ links OpenSSL, and the static link needs `libssl.a`; it also pulls in
+ `-lz -lzstd`).
+- **One worker.** tep's server here is a single blocking process that
+ closes each connection after its response, with a 5-second read
+ timeout so an idle connection can't hold it.