Repository navigation
feat(kaos): Keep a fetch's card up for the install it announces - #123
Conversation
A host that installs an app over the air sends `appdata_get` and then `install`, and the glass shows the gap between them: the fetch's card closes when the folder is written and opens again when the install reports its 0 %, so the person watching sees the board go back to the launcher for a moment, as if nothing were coming. `appdata_get` takes `install=on` to say the install comes next. The fetch is then the first step of that install, and its card is the install's: whatever the fetch's end, neither the done nor the failure goes out, and AO_AppMgr holds the card at 0 % in its idle state, saying it again every second so the LED stays up. The install that begins takes it over with the fetch's face still on it; one refused before it begins, anything else AO_AppMgr turns to, or KODE_APPMGR_HOLD_MS with no install, ends it with the unnamed done. A fetch that fails leaves no failure sheet, since the app's data is what the install looks like, never what lets it happen. The answer to the fetch is the same with or without the key, and a fetch without it is unchanged. An older board refuses the key with `code=3 msg=install`, so a host asks again without it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A terminal install took the card over like an install from a URL, with nothing published. It announces itself only at its ready, so one that ended before it - the console refused to arm, no plan, no room - owed the glass no failure: the card stayed up, locked, with nobody to end it. A terminal install now ends the held card like any other request, before anything it publishes, and raises its own card at its ready as it always did. Only an install from a medium or a URL takes the card over.
The held card had a timer of its own beside the beat that says its 0 % every second, and a private signal for it. Idle already wakes on that beat while the card is up, so the beat counts the wait and the last one ends the card: one timer and APP_HOLD_SIG go, and AO_AppMgr's static gets back the 24 bytes the timer took. KODE_APPMGR_HOLD_MS stays the one place the wait is set, checked at build time to be a whole number of beats.
The house style spells a choice out with an if; the answer to a low-power round over a held card was the one new ternary in the file.
APP_BEAT_SIG was described as the second gone by while waiting on the network. It is also what says a held card again and counts its wait.
No case asked a held card for its answer to a low-power round, nor sent it a run, an erase, a keep-only or an install from a medium refused in idle: each ends the card, and only another fetch was covered. The case of the take-over now also says what its first report names: nobody, until the image is read, which is what the interface keeps the fetch's face through.
A held card had a flag and a count beside it, and with the fetch's own flag they took AO_AppMgr's static four bytes past what it measures on develop, in a struct that must stay under 2048 bytes of internal RAM. The count now runs down, and a count of zero is no card held: one field where there were two. The fetch's flag sits in a hole ahead of the fetch's other fields. The struct measures what it does without the hold.
…69) An app's report that named no project dropped the face of the card it arrived on. A card can carry two transfers: the fetch of an app's data folder and the install it announced (kodediy/kode-sdk#123), or an install that starts again once its copies are on the card. The later one names nobody until its image is read, so the face went for the time a download takes to open and came back at the first chunk. The card now keeps its face through such a stretch and asks its folder again, once: the transfer before may be the one that wrote it, and the folder was last asked when the card rose. That is also what puts a freshly fetched icon on the card from the install's first report.
|
Thank you for this. The idea is right, the change reads well, and the cases made it easy to see what each way out of the hold does. We kept your commit as it is and added the following on top, so you can see exactly what changed and why:
One thing in the description did not hold, and it is fixed on the other side: kgui did need a change. The install's first reports name no project until its image is read, and kgui dropped the card's face on a report that names nobody, then took it again at the first chunk. It also asked the data folder only once, when the card rose, which is before the fetch has written it. So the card stayed up, as you intended, but its face went away while the download opened, and a newly fetched icon only showed at the first chunk. KodeOS now keeps the face through such reports and asks the folder again at that moment, so the fetched face is on the card from the install's first report: kodediy/KodeOS#69. Left as you had it: a held card whose install is refused or never comes ends with the unnamed done. Seen on a board: after Thanks again. |
Description of Change
A host that installs an app over the air sends
appdata_getand theninstall, and the glass shows the gap between them. The fetch's card closes when the folder is written and opens again when the install reports its 0 %. For a moment the board is back at the launcher, as if nothing were coming.appdata_gettakes an optionalinstall=on(aKARG_BOOL,offby default, likeinstall'srun) to say the install comes next. The fetch is then the first step of that install, and its card belongs to the install:beat, so the LED stays up too.FLASH_REQ_SIGorAPP_RECV_REQ_SIGleaves idle): it takes the card over with nothing published. The glass goes from the fetch's 0 % to the install's, and the face the fetch just wrote stays on it.appdata_get, an erase, a run, keep-only): the card ends before that request publishes anything. Otherwise a second fetch's 0 % would reach the glass under the old face, and the done after it would close the new card. The remaining ways out of idle end it on idle's exit.KODE_APPMGR_HOLD_MS(15 s,kqp_config.h): the unnamed done ends it.install announced.The answer to the fetch (
>|appdata …,>ok,>err …) is the same with or without the key, and a fetch without it is unchanged. An older board refuses the key withcode=3 msg=install, so a host asks again without it.The API change is one argument:
appmgr_appdata_get_request(project, url, install, who)andAppDataGetReqEvt.install. There is one new private signal,APP_HOLD_SIG.kgui needs nothing. The card already follows the
APP_FLASH_*family alone, and keeps its face whilewritingstays true. KodeOS needs only the submodule move once this lands.Test Scenarios
tools/host_tests.sh: 5501 cases across 8 suites, all passing (5490 ondevelopbefore the change; 11 new).tools/host_tests.sh --sanitize: the same 5501 under ASan and UBSan, all passing.tools/check_layers.sh: all layer rules hold.New cases:
test_appmgr_ao.c[appdata_get][hold]: a fetch without the key still ends its card; the held card keeps saying 0 %; an https install and a terminal install each take it over without a done, and the hold does not outlive them; the deadline ends it; a refused install ends it at once; another fetch ends it before its own 0 %; a failed fetch leaves no failure sheet and the deadline still ends the card; the request carries the flag.test_console_appdata.c: absent,offandonreach AO_AppMgr as they should;install=yesis refused withcode=3 msg=installand nothing is asked.Related links
code=3):appdata_gettheninstall src=https…over the Kode channel.