← Commit history

Publish 1.4.4

John Lauer ·09a22b91ef ·1mo ago ·parent b76aed7
4 files changed +33−20
bin/adom-chip-fetcher
⋯ 1 unchanged line ⋯
package.json+1−1
@@ -1,6 +1,6 @@ {   "slug": "adom-chip-fetcher",-  "version": "1.4.3",+  "version": "1.4.4",   "type": "app",   "description": "Crawls the web on your behalf to gather everything about the chips you care about: datasheets, symbols, footprints, 3D models, stock and pricing, straight from the manufacturer first, into your EDA tool. Say \"cf\" to your AI.",   "dependencies": {
page.json+2−2
@@ -1,6 +1,6 @@ {   "slug": "adom-chip-fetcher",-  "version": "1.4.3",+  "version": "1.4.4",   "type": "app",   "description": "Crawls the web on your behalf to gather everything about the chips you care about: datasheets, symbols, footprints, 3D models, stock and pricing, straight from the manufacturer first, into your EDA tool. Say \"cf\" to your AI.",   "dependencies": {@@ -148,4 +148,4 @@     }   ],   "brief": "Crawls the web on your behalf to gather everything about the chips you care about: datasheets, symbols, footprints, 3D models, stock and pricing, straight from the manufacturer first, into your EDA tool. Say \"cf\" to your AI."-}+}\ No newline at end of file
skills/adom-chip-fetcher-dock/SKILL.md+30−17
@@ -138,26 +138,39 @@ flip once the platform certifies the prompt path.  ## A stale build must never outlive a package update -The dock's Hard Refresh Open updates the package and reopens the tab, but it does-NOT re-run the launch steps when the app is already in the running map, so nothing-asks the old process to stand down and the tab renders whatever is still on the-port. Caught live on 2026-08-24: `pkg update` had landed 1.4.1 while a 1.4.0-process still served 8786, so a build whose Send to AI was the parked crash path-stayed live.+Measured on 2026-08-24: `pkg update` had landed 1.4.1 while a 1.4.0 process still+served 8786, so the dock tab rendered a build whose Send to AI was the parked crash+path. The dock DOES re-run the launch steps on a Hard Refresh, so the hole was on+this side. -Two defences, both in this app:+**The real mechanism is a race, not bad victim-matching.** The dock updates the+package while the launch steps run, so `serve` can be a process running the OLD+binary. It compares its own version against the instance on the port, sees a match,+reuses it, and the freshly installed build never takes over. Reproduced by exec'ing+the deleted inode through `/proc/<pid>/exe`, which is what a launch that started+mid-update actually is. -- `serve` is version-aware and retires an instance of a DIFFERENT version by exact-  argv (verified: a 1.4.2 binary retires a running 1.4.1 on the same port).-- The running server watches its own executable and hands the port over within a-  minute of a package update, after verifying the replacement answers `--version`.-  `/health` reports `installed_version` and `stale`, and the Dashboard LED turns-  amber with the version pair while the gap is open.+Three defences, in order of who wins first: -The trap that made the watch blind at first: a package update UNLINKS the old-binary and writes a new one at the same path, so a running process resolves-`/proc/self/exe` to `<path> (deleted)`. Reading that suffixed path always fails.-Strip the suffix before stat or exec.+1. **Serve hands off when it is not the installed build.** Before anything else,+   `serve` compares the version of the binary at its own path to its own; if they+   differ it re-runs the whole command from the installed build (once, guarded by+   `CF_SERVE_HANDED_OFF` so a version-reporting oddity can never loop).+2. **Retire by PORT OWNERSHIP.** The victim is whoever holds the LISTEN socket on+   the port (parsed from `/proc/net/tcp{,6}` plus the socket inode in `/proc/*/fd`),+   confirmed to be one of ours, never ourselves and never our parent. Names and argv+   drift; the socket does not. Argv matching stays as a backstop.+3. **The running server watches its own binary** and hands the port over within a+   minute of an update, after verifying the replacement answers `--version`. This+   converges users who never re-click. `/health` reports `installed_version` and+   `stale`, and the Dashboard LED shows the version pair while the gap is open.++**The "(deleted)" trap, measured precisely.** When an update unlinks the old binary+and writes a new one at the same path, `/proc/<pid>/exe` resolves to `<path>+(deleted)` from that instant, so any check that stats or execs that path fails and+any matching that compares executable PATHS stops matching exactly when it must.+`/proc/<pid>/cmdline` is frozen at exec and does NOT gain the suffix, so argv-based+matching survives; exe-path matching does not. Strip the suffix before any path use.  ## The icon is a line drawing, and a favicon can NEVER use currentColor