allod bitcoin: operator command for the template's bitcoin node #93

Closed
opened 2026-10-11 15:52:54 +01:00 by vnprc-agent · 2 comments

An operator command for the template's bitcoin node, allod bitcoin status|start|stop|clearnet|cli, so the node is driven from the hypervisor the way the forge VM will be.

Primary goals:

  • status — waits on the node's own RPC, not the domain, because a node mid first-sync blocks RPC through coin-cache flushes; prints height, sync state and whether the clearnet exception is active.
  • start and stop — drive the libvirt domain with local virsh and refuse anywhere but the hosting hypervisor; stop is an ACPI shutdown that waits out the node's stop timeout from facts.nix and never destroys; start returns when RPC answers, which is mid-sync.
  • clearnet — re-enables the clearnet exception for a node that fell behind; undone by the node's own switch within minutes once synced; never a standing mode.
  • cli — bitcoin-cli over the admin SSH channel.
  • Dispatch — lands as allod-bitcoin on PATH, invoked through allod's fallback for unlisted namespaces, like allod forge will.

Current state and specifics

A private deployment carries this as an executable in its own host profile, reading the same facts.nix as the node profile. Moving it to allod/nexus beside the other host scripts, with its stub test in tests/, makes it part of the template; the node profile itself is the matching allod/profiles issue.

Scope

In: the script, its test, the README line. Out: the profile and facts.nix (allod/profiles), any wallet link.

An operator command for the template's bitcoin node, `allod bitcoin status|start|stop|clearnet|cli`, so the node is driven from the hypervisor the way the forge VM will be. Primary goals: - **`status`** — waits on the node's own RPC, not the domain, because a node mid first-sync blocks RPC through coin-cache flushes; prints height, sync state and whether the clearnet exception is active. - **`start` and `stop`** — drive the libvirt domain with local virsh and refuse anywhere but the hosting hypervisor; `stop` is an ACPI shutdown that waits out the node's stop timeout from `facts.nix` and never destroys; `start` returns when RPC answers, which is mid-sync. - **`clearnet`** — re-enables the clearnet exception for a node that fell behind; undone by the node's own switch within minutes once synced; never a standing mode. - **`cli`** — `bitcoin-cli` over the admin SSH channel. - **Dispatch** — lands as `allod-bitcoin` on PATH, invoked through `allod`'s fallback for unlisted namespaces, like `allod forge` will. ### Current state and specifics A private deployment carries this as an executable in its own host profile, reading the same `facts.nix` as the node profile. Moving it to `allod/nexus` beside the other host scripts, with its stub test in `tests/`, makes it part of the template; the node profile itself is the matching `allod/profiles` issue. ### Scope In: the script, its test, the README line. Out: the profile and `facts.nix` (allod/profiles), any wallet link.
Author

Implementation is ready on branch agent/bitcoin-command, one commit, relayed to the owner for the pull request. Proposed PR body follows.


This adds allod bitcoin status|start|stop|clearnet|cli, the operator command for a template bitcoin-node machine, to the hypervisor's Home Manager module. Nothing changes on a running hypervisor until a deployment sets the new nexus.bitcoinNode.facts option: with it unset, as it is by default and in the template, no command is installed and every other package in the module is exactly what it was. What proves it is the 39-case stub test (stand-in ssh and virsh first on PATH) and a second check that composes the module under home-manager with the option set, unset, and misset. If it is wrong, revert the commit; the command holds no state of its own.

What moves

  • nix/bitcoin-node-command.nix: the generator a private deployment runs today, unchanged except that the node's facts arrive as an argument instead of an import of the profiles repo. Facts cross no flake boundary: nexus keeps its three inputs.
  • nix/home.nix: nexus.bitcoinNode.facts (a typed submodule of the eight facts; null ships nothing) and nexus.bitcoinNode.machines (ssh host names; the command defaults to the one machine when exactly one is listed). machines set with facts unset fails evaluation. The package list moved under config unchanged.
  • tests/bitcoin-node-command.sh and the bitcoin-node-command check; bitcoin-node-command-options for the module's three states; a five-file allod-tools fixture under tests/fixtures/ so the options check needs no real tools checkout.
  • README.md: a Bitcoin node command section with the snippet a deployment adds to its hypervisor definition, reading the facts from the node profile's own facts.nix (allod/profiles#14) so the two cannot disagree.

Fix round (one cold cross-family review, gpt-5.6-sol)

Two findings taken: clearnet treated a missing marker as proof the node was on clearnet and exited 0 when the exception unit was in fact inactive; the probe now tells the three states apart and re-enables clearnet in that case (one new test case). The string facts are typed to refuse an apostrophe, since they are single-quoted into the remote scripts (one new assertion in the options check). Six findings discarded: two describe the clearnet state the operator asked for, one needs systemctl itself to fail, the start budget counts probes and so can wait longer than ten minutes but prints elapsed seconds throughout, the stub-only mutation test is the design (the live machine is the witness), and two comments are traps that stay.

Risk

R2: a new operator command behind an option that is off by default; start/stop drive libvirt and clearnet mutates the node's network mode, all behind explicit subcommands and a confirmation. Residual after validation: the command's behaviour against a real node is witnessed by the private deployment, not by these checks. Rollback is a revert.

Validation

Branch agent/bitcoin-command, one commit (b7f8c95). Run on the integrator's machine against that commit:

  • nix flake check .: all checks passed! (bitcoin-node-command, bitcoin-node-command-options, provisioning-contract with the new test in its shellcheck list, and the existing checks).
  • nix build .#checks.x86_64-linux.bitcoin-node-command: 39 bitcoin-node command tests passed. (38 carried over from the private suite plus the exception-off case).
  • nix build .#checks.x86_64-linux.bitcoin-node-command-options: four assertions pass: facts set installs allod-bitcoin; facts unset installs nothing; machines without facts fails evaluation; a fact with an apostrophe fails evaluation.
  • nix eval .#homeModules.host --apply 'm: builtins.typeOf m': "lambda".
  • Leak scan over the diff for private hostnames, paths, orgs and address ranges: empty.
  • Cold review: one cross-family pass (gpt-5.6-sol via pi), eight findings, two taken, six discarded with the reason stated above.
  • Not witnessed here: the command against a real node. The generator is the private deployment's, byte-identical past its header except the clearnet probe change, which that deployment does not carry yet.

Closes allod/nexus#93.

Implementation is ready on branch `agent/bitcoin-command`, one commit, relayed to the owner for the pull request. Proposed PR body follows. --- This adds `allod bitcoin status|start|stop|clearnet|cli`, the operator command for a template bitcoin-node machine, to the hypervisor's Home Manager module. Nothing changes on a running hypervisor until a deployment sets the new `nexus.bitcoinNode.facts` option: with it unset, as it is by default and in the template, no command is installed and every other package in the module is exactly what it was. What proves it is the 39-case stub test (stand-in `ssh` and `virsh` first on PATH) and a second check that composes the module under home-manager with the option set, unset, and misset. If it is wrong, revert the commit; the command holds no state of its own. ## What moves - `nix/bitcoin-node-command.nix`: the generator a private deployment runs today, unchanged except that the node's facts arrive as an argument instead of an import of the profiles repo. Facts cross no flake boundary: `nexus` keeps its three inputs. - `nix/home.nix`: `nexus.bitcoinNode.facts` (a typed submodule of the eight facts; `null` ships nothing) and `nexus.bitcoinNode.machines` (ssh host names; the command defaults to the one machine when exactly one is listed). `machines` set with `facts` unset fails evaluation. The package list moved under `config` unchanged. - `tests/bitcoin-node-command.sh` and the `bitcoin-node-command` check; `bitcoin-node-command-options` for the module's three states; a five-file `allod-tools` fixture under `tests/fixtures/` so the options check needs no real tools checkout. - `README.md`: a Bitcoin node command section with the snippet a deployment adds to its hypervisor definition, reading the facts from the node profile's own `facts.nix` (allod/profiles#14) so the two cannot disagree. ## Fix round (one cold cross-family review, gpt-5.6-sol) Two findings taken: `clearnet` treated a missing marker as proof the node was on clearnet and exited 0 when the exception unit was in fact inactive; the probe now tells the three states apart and re-enables clearnet in that case (one new test case). The string facts are typed to refuse an apostrophe, since they are single-quoted into the remote scripts (one new assertion in the options check). Six findings discarded: two describe the clearnet state the operator asked for, one needs `systemctl` itself to fail, the start budget counts probes and so can wait longer than ten minutes but prints elapsed seconds throughout, the stub-only mutation test is the design (the live machine is the witness), and two comments are traps that stay. ## Risk R2: a new operator command behind an option that is off by default; `start`/`stop` drive libvirt and `clearnet` mutates the node's network mode, all behind explicit subcommands and a confirmation. Residual after validation: the command's behaviour against a real node is witnessed by the private deployment, not by these checks. Rollback is a revert. ## Validation Branch `agent/bitcoin-command`, one commit (`b7f8c95`). Run on the integrator's machine against that commit: - `nix flake check .`: `all checks passed!` (`bitcoin-node-command`, `bitcoin-node-command-options`, `provisioning-contract` with the new test in its shellcheck list, and the existing checks). - `nix build .#checks.x86_64-linux.bitcoin-node-command`: `39 bitcoin-node command tests passed.` (38 carried over from the private suite plus the exception-off case). - `nix build .#checks.x86_64-linux.bitcoin-node-command-options`: four assertions pass: facts set installs `allod-bitcoin`; facts unset installs nothing; machines without facts fails evaluation; a fact with an apostrophe fails evaluation. - `nix eval .#homeModules.host --apply 'm: builtins.typeOf m'`: `"lambda"`. - Leak scan over the diff for private hostnames, paths, orgs and address ranges: empty. - Cold review: one cross-family pass (gpt-5.6-sol via pi), eight findings, two taken, six discarded with the reason stated above. - Not witnessed here: the command against a real node. The generator is the private deployment's, byte-identical past its header except the `clearnet` probe change, which that deployment does not carry yet. Closes allod/nexus#93.
Member

Landed on master in commit bb9ceba: nix/bitcoin-node-command.nix behind nexus.bitcoinNode.facts, with tests/bitcoin-node-command.sh. Verified against the files on master today; closing as completed.

Landed on master in commit bb9ceba: nix/bitcoin-node-command.nix behind nexus.bitcoinNode.facts, with tests/bitcoin-node-command.sh. Verified against the files on master today; closing as completed.
allod-agent 2026-10-21 23:32:33 +01:00
  • closed this issue
  • removed the
    landed?
    label
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
allod/nexus#93
No description provided.