Closed general

apply that fails on its second app launch records no _applied entry (0.7.7); Unload then refuses without --force

Colby Knox · 1mo ago ·closed by Colby Knox

adom-cli 0.7.7, Colby's cloud container (gallia), 2026-09-15. Unload of the drone bench fails from Hydrogen's button with exit 2, and from the shell adom-cli hydrogen workspace teardown adom/drone-layout-dc-00 refuses:

{"error": "no recorded apply for 'adom/drone-layout-dc-00' (teardown removes only what apply created; recorded sources: /tmp/claude-1001/-home-adom-project/ee80a05e-.../scratchpad/bench.json). To undo a bench that never got a ledger entry, re-run with --force ..."}

What happened, from ~/.adom/launch-logs and ~/.adom/launches.json:

  1. 14:35:47 UTC apply of adom/drone-layout-dc-00#hydrogen/workspace.json launched adom/mjpeg-stream-viewer (pid 514039, http://127.0.0.1:46071/) and RECORDED it in launches.json under "46071" with bench: "adom/drone-layout-dc-00#hydrogen/workspace.json".
  2. 14:35:49 the second app, adom/drone-rf, failed to launch (its Wall exited: Port 8131 is unavailable (EADDRINUSE), a stale supervisor from Sep 14, now fixed on Aditya's side in drone-rf 0.1.2 and drone-rf#1 closed).
  3. apply aborted. _applied in launches.json has NO entry for the bench; the only _applied key is the CLI thread's Sep 11 scratchpad bench.json.
  4. Two more applies at 16:35 and 16:36 did the same (same failure, same missing entry).
  5. Result: one registered app (46071, still alive) belonging to the bench, tabs on the layout that apply created, and a teardown that will not touch either without --force.

#14 (closed against 0.7.5) said _applied is written as soon as the launches settle, apps recorded, tabs empty, and again after every tab. On 0.7.7 that did not happen on the "second app fails to launch" path: the first app is in the launch table but the bench never reaches _applied, so the ledger and the launch table disagree with each other.

Asks:

  • Write the _applied entry BEFORE the first launch attempt (apps: [], tabs: []) and update it after each launch and each tab, so an abort at any point leaves a truthful entry. A failed launch is still part of the apply and must be undoable without a flag.
  • teardown without --force: when the ledger has no entry but launches.json holds apps whose bench matches the source, treat that as the entry (the launch table is the CLI's own record) and tear those down plus the bench's named tabs. Keep --force for the truly unrecorded case.
  • Exit code: the shell run exits 1 with the JSON error; Hydrogen's Unload reported exit 2. If the button wraps the call, the two should agree, and the button should show the JSON error text (HC already has the Details block for this).

Repro on a throwaway bench: two app tabs where the second app's start script exits 1; apply; then teardown <ref> --dry-run. Do not use adom/drone-layout-dc-00 on gallia for the repro.

1 Reply

Colby Knox · 1mo ago

Fixed in adom-cli 0.7.8 (GH v0.7.8, wiki package 4.3.8). Reproduced on a throwaway bench only, as asked; adom/drone-layout-dc-00 on gallia was not touched.

Why 0.7.5's fix did not cover your case: the ledger write was placed after the launches and after the first Hydrogen read of the live tree. Your applies launched the viewer, then drone-rf failed, and the process ended before that point (the launch table got the viewer, the ledger got nothing), which is exactly the disagreement you dumped.

What 0.7.8 does, in your order:

  1. The _applied entry is written BEFORE the first launch attempt (apps listed, tabs empty), refreshed after every launch (and the registry row of each launched or reused app is stamped with the bench identity at that moment), then after every created tab as before. An abort anywhere leaves a truthful entry.
  2. teardown <ref|file> without --force: when the ledger has no entry but launches.json holds apps stamped with the source's identity, that is the record: the bench file names the tabs (only those actually live), the launch table names the apps, and the result reports recovered_from: "launch table". --force stays for the truly unrecorded case, and the refusal now says both conditions were absent.
  3. Exit code and text: the CLI exits 1 and prints the JSON { "error": ... } on stderr for every failure; HC's launch route runs adom-cli hydrogen workspace teardown <source> with no extra flags, so an exit 2 reported by the button is the extension's own mapping of a failed process (2 only ever came from a clap usage error, e.g. a --json the verb did not accept; export/apply/teardown now accept it and answer JSON + exit 1). For the Details block, the text is on stderr.

Repro (throwaway bench: adom/adom-lbr + a second app whose page does not exist, applied with Hydrogen deliberately unreachable so the apply aborts right after the launches, the #17 shape):

  • apply exited 1 on the Hydrogen error; the ledger already held kcknox/ztest-bench#hydrogen/workspace.json with both apps, and the adom-lbr registry row carried that bench stamp.
  • ledger key deleted by hand to reproduce 0.7.7's state; teardown hydrogen/workspace.json --dry-run answered recovered_from: "launch table" with the plan stop adom/adom-lbr (port 8785); the real teardown stopped it, removed no tabs (none had been created), left the drone bench's viewer row (stamped with the drone identity) and every tab alone.
  • a source with nothing stamped still refuses and names --force.

On gallia today: once 0.7.8 is on the box (adom-wiki pkg update), a plain adom-cli hydrogen workspace teardown adom/drone-layout-dc-00 recovers from the launch table (the viewer row 46071 carries the drone bench's identity) and takes the bench's tabs and that viewer down; I left that for you to run.

Log in to reply.