docs(start-sdk): document retiring a task's replay key - #3626
Open
MattDHill wants to merge 1 commit into
Open
Conversation
`createTask` derives its `replayId` from `[package-id]:[action-id]`, so renaming an action, retargeting a task, or pointing it at a different package writes a new key and abandons the old one. Nothing rewrites or reaps the abandoned key, and the guide never said so — `tasks.md` in fact claimed the opposite, that init could be re-run "without accumulating stale tasks". It bites in two ways. If the retired action still exists, both keys stay live and re-arm each other; where the demanded values diverged, the user ping-pongs between them with no way to settle. If the retired action is gone, `recheck_tasks` can no longer resolve its input, the task's `active` flag freezes, and a frozen active + critical task stops the package with no in-product remedy. Document the rule — clearing the retired key is the job of the package that created the task, in the migration for the version that changes it — along with why neither StartOS nor the SDK can do it automatically, the conditional-task case, and the CLI recovery path for boxes already stuck. Also correct the `severity` union in `dependencies.md`, which read 'critical' | 'high' | 'medium' | 'low' rather than the actual TaskSeverity of 'optional' | 'important' | 'critical'. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
A user updated StartOS, Knots, and DATUM Gateway and landed in an unrecoverable loop: two critical tasks on bitcoind's
blocknotify, each demanding a different URL, each re-arming the moment the other was satisfied. DATUM was stopped the whole time, and no sequence of UI actions could settle it.The cause is a documented-but-incomplete contract.
createTaskderives itsreplayIdfrom[package-id]:[action-id], so when Knots renamed its config actionother-config→autoconfig, DATUM's next release minted a new key rather than updating the old one. Nothing rewrites or reaps the abandoned key — it sat in the database still enforcinghttp://datum.startos:7152/NOTIFYfrom a pre-2.0 release, while the live key demanded the bridge address. The OS honors the legacy task shape (db/model/package.rs), so the orphan stayed fully functional.The guide covered
replayIdidempotency but never the flip side, andtasks.mdactively asserted the opposite:True only while the key itself is stable. That sentence is a fair part of why this went unnoticed.
An audit of the fleet found the same orphan in six other bitcoind dependents (lnd, fulcrum, mempool, public-pool, electrs, umbrel-bitcoin-ui). Those are currently harmless only because their demanded values happen to be unchanged — the next edit to any of those
accept/setblocks reproduces this bug. A second class exists where the retired action was deleted rather than renamed; those are worse, becauserecheck_taskscan no longer resolve the action's input, the task'sactiveflag freezes, and a frozenactive: true+criticalstops the package with no in-product remedy.What changed
tasks.mdfulcrum-bch-startos'sNODE_TASK_KEYS+clearTask, which already solves this), and thestart-cli package action clear-task … --forcerecovery path for boxes already stuck.dependencies.mdreplayIdnote and cross-linked the new section, since that's where someone wiring up a cross-service task is actually reading.severityunion in the API signature: it read'critical' | 'high' | 'medium' | 'low', butTaskSeverityis'optional' | 'important' | 'critical'. Unrelated to the incident, corrected in passing.Docs-only; no SDK surface change, so no version bump or changelog entry.
🤖 Generated with Claude Code