The miner and node are now private forks on this Gitea (quantus/miner, quantus/chain) that will follow their own main branches, with the miner built as one fat binary carrying cubins for every card in the fleet. Each fork gains a deploy workflow (quantus/miner#8 and quantus/chain#2). Two deployers for one host is not acceptable: this repo pins a release version, the forks deploy main, and every run of either would flip the binary and restart the service. So this repo's deploy-node and deploy-miner jobs retire, and the fetch job with them.
What moves out
To quantus/miner
To quantus/chain
deploy-miner job and its matrix (host, node, gpu_devices), unchanged in shape
deploy-node job and its matrix (inner_hash, public_addr, rpc_expose, miners)
the miner role of script/infra-setup.sh (sudoers quantus-miner_gitea_ci)
the node role (quantus-node_gitea_ci, network key, credential read grants)
the miner sections of CLAUDE.md and readme.md (traps, measured facts)
the node sections
The sudoers preflight in each deploy compares grants against the infra-setup.sh in the same repo, which is the reason the roles split rather than staying here: the deployer and its grant list must not be able to drift.
What stays
This becomes the fleet-level repo for the things that are not one component:
deploy-metrics: Prometheus scrape drop-in, Grafana dashboards (quantus.json, gpu.json), arena exporter. Gains the recording rules and the "Performance by build" row from quantus/miner#9.
nvidia-power-limit and nvidia-textfile units and the gpu role. Fleet-general, already noted in infra-setup.sh as belonging in a monitoring repo that does not exist yet.
The edge role (wss://quantus.internal), operator-run.
infra-setup.sh for the roles above, plus the shared gitea_ci user creation (idempotent, so all three repos creating it is harmless).
doc/wormhole-rewards.md and the reward-address guidance; the inner_hash values themselves move with the node matrix.
SCRAPE_NODES / SCRAPE_MINERS remain here and must agree with the two forks' matrices. validate metrics already asserts every quantus-* target is up, which is the drift check; note in each fork's matrix that adding a host means a scrape-target change here.
Sequence
Fork repos land their deploy workflows in validate-only mode and run green against the hosts this repo deployed. No change here yet.
On one day: disable fetch, deploy-node, deploy-miner here (remove the jobs, keep deploy-metrics and re-point its needs:), and flip both forks to deploy mode. Version pins NODE_VERSION / MINER_VERSION go with the jobs.
After one clean cycle of both forks, delete the moved assets and script roles here and update readme.md / CLAUDE.md so the "source of infra truth" statement names the three repos and what each owns.
Re-run the reduced infra-setup.sh here and the new ones in each fork so every host's sudoers matches its new deployer.
Not changing
The gitea_ci runner key, the RSYNC_SSH_KEY secret (copy it to the two forks, never regenerate), firewall scoping rules, the no-op-when-unchanged discipline, and the validate checks. All of that moves as-is; the point of this issue is ownership, not behaviour.
The miner and node are now private forks on this Gitea (`quantus/miner`, `quantus/chain`) that will follow their own `main` branches, with the miner built as one fat binary carrying cubins for every card in the fleet. Each fork gains a deploy workflow (quantus/miner#8 and quantus/chain#2). Two deployers for one host is not acceptable: this repo pins a release version, the forks deploy `main`, and every run of either would flip the binary and restart the service. So this repo's `deploy-node` and `deploy-miner` jobs retire, and the `fetch` job with them.
## What moves out
| To `quantus/miner` | To `quantus/chain` |
| --- | --- |
| `deploy-miner` job and its matrix (`host`, `node`, `gpu_devices`), unchanged in shape | `deploy-node` job and its matrix (`inner_hash`, `public_addr`, `rpc_expose`, `miners`) |
| `asset/systemd/quantus-miner.service`, `.sysusers.conf` | `asset/systemd/quantus-node.service`, `.sysusers.conf` |
| `asset/firewalld/quantus-miner-metrics.xml` | `asset/firewalld/quantus-node*.xml` |
| `asset/config/miner.env.tmpl` | `asset/config/node.env.tmpl` |
| the miner role of `script/infra-setup.sh` (sudoers `quantus-miner_gitea_ci`) | the node role (`quantus-node_gitea_ci`, network key, credential read grants) |
| the miner sections of `CLAUDE.md` and `readme.md` (traps, measured facts) | the node sections |
The sudoers preflight in each deploy compares grants against the `infra-setup.sh` in the same repo, which is the reason the roles split rather than staying here: the deployer and its grant list must not be able to drift.
## What stays
This becomes the fleet-level repo for the things that are not one component:
- `deploy-metrics`: Prometheus scrape drop-in, Grafana dashboards (`quantus.json`, `gpu.json`), arena exporter. Gains the recording rules and the "Performance by build" row from quantus/miner#9.
- `nvidia-power-limit` and `nvidia-textfile` units and the `gpu` role. Fleet-general, already noted in `infra-setup.sh` as belonging in a monitoring repo that does not exist yet.
- The `edge` role (`wss://quantus.internal`), operator-run.
- `infra-setup.sh` for the roles above, plus the shared `gitea_ci` user creation (idempotent, so all three repos creating it is harmless).
- `doc/wormhole-rewards.md` and the reward-address guidance; the `inner_hash` values themselves move with the node matrix.
- Issues #1, #2, #3 here are unaffected.
`SCRAPE_NODES` / `SCRAPE_MINERS` remain here and must agree with the two forks' matrices. `validate metrics` already asserts every `quantus-*` target is up, which is the drift check; note in each fork's matrix that adding a host means a scrape-target change here.
## Sequence
1. Fork repos land their deploy workflows in `validate`-only mode and run green against the hosts this repo deployed. No change here yet.
2. On one day: disable `fetch`, `deploy-node`, `deploy-miner` here (remove the jobs, keep `deploy-metrics` and re-point its `needs:`), and flip both forks to deploy mode. Version pins `NODE_VERSION` / `MINER_VERSION` go with the jobs.
3. After one clean cycle of both forks, delete the moved assets and script roles here and update `readme.md` / `CLAUDE.md` so the "source of infra truth" statement names the three repos and what each owns.
4. Re-run the reduced `infra-setup.sh` here and the new ones in each fork so every host's sudoers matches its new deployer.
## Not changing
The `gitea_ci` runner key, the `RSYNC_SSH_KEY` secret (copy it to the two forks, never regenerate), firewall scoping rules, the no-op-when-unchanged discipline, and the validate checks. All of that moves as-is; the point of this issue is ownership, not behaviour.
One more reason to finish this cut-over promptly: while this repo's deploy still owns quantus-miner.service, any run of it (push to main, manual dispatch) that lands during a bench measurement on quantus/miner will find the unit stopped, conclude "nothing changed but the miner is down", and start it mid-window. That corrupts the measurement rather than breaking anything, and the harness's utilisation check only guards the start of a run. Until deploy-miner retires here, do not run this workflow while a bench run is in flight on the same host. After the cut-over the miner repo owns both the deploy and the bench and can serialise them under the same host lock.
One more reason to finish this cut-over promptly: while this repo's deploy still owns `quantus-miner.service`, any run of it (push to `main`, manual dispatch) that lands during a `bench` measurement on quantus/miner will find the unit stopped, conclude "nothing changed but the miner is down", and start it mid-window. That corrupts the measurement rather than breaking anything, and the harness's utilisation check only guards the start of a run. Until `deploy-miner` retires here, do not run this workflow while a bench run is in flight on the same host. After the cut-over the miner repo owns both the deploy and the bench and can serialise them under the same host lock.
Step 2, miner half, done 2026-09-03: #6 merged after quantus/miner's deploy went green on both hosts from its main (quantus/miner actions/runs/19). This repo no longer ships the miner. SCRAPE_MINERS still lists benjy and quadbrat and the deploy triggered by #6 must show both miners up in validate metrics.
The mid-benchmark restart hazard noted above is gone with it: nothing here touches quantus-miner.service any more.
Remaining for this issue: the node half (quantus/chain#2), and step 3 (readme.md still carries the stale 4090 hashrate table; see quantus/miner#2 for the measured numbers).
Step 2, miner half, done 2026-09-03: #6 merged after quantus/miner's deploy went green on both hosts from its `main` (quantus/miner actions/runs/19). This repo no longer ships the miner. `SCRAPE_MINERS` still lists benjy and quadbrat and the deploy triggered by #6 must show both miners up in `validate metrics`.
The mid-benchmark restart hazard noted above is gone with it: nothing here touches `quantus-miner.service` any more.
Remaining for this issue: the node half (quantus/chain#2), and step 3 (`readme.md` still carries the stale 4090 hashrate table; see quantus/miner#2 for the measured numbers).
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
The miner and node are now private forks on this Gitea (
quantus/miner,quantus/chain) that will follow their ownmainbranches, with the miner built as one fat binary carrying cubins for every card in the fleet. Each fork gains a deploy workflow (quantus/miner#8 and quantus/chain#2). Two deployers for one host is not acceptable: this repo pins a release version, the forks deploymain, and every run of either would flip the binary and restart the service. So this repo'sdeploy-nodeanddeploy-minerjobs retire, and thefetchjob with them.What moves out
quantus/minerquantus/chaindeploy-minerjob and its matrix (host,node,gpu_devices), unchanged in shapedeploy-nodejob and its matrix (inner_hash,public_addr,rpc_expose,miners)asset/systemd/quantus-miner.service,.sysusers.confasset/systemd/quantus-node.service,.sysusers.confasset/firewalld/quantus-miner-metrics.xmlasset/firewalld/quantus-node*.xmlasset/config/miner.env.tmplasset/config/node.env.tmplscript/infra-setup.sh(sudoersquantus-miner_gitea_ci)quantus-node_gitea_ci, network key, credential read grants)CLAUDE.mdandreadme.md(traps, measured facts)The sudoers preflight in each deploy compares grants against the
infra-setup.shin the same repo, which is the reason the roles split rather than staying here: the deployer and its grant list must not be able to drift.What stays
This becomes the fleet-level repo for the things that are not one component:
deploy-metrics: Prometheus scrape drop-in, Grafana dashboards (quantus.json,gpu.json), arena exporter. Gains the recording rules and the "Performance by build" row from quantus/miner#9.nvidia-power-limitandnvidia-textfileunits and thegpurole. Fleet-general, already noted ininfra-setup.shas belonging in a monitoring repo that does not exist yet.edgerole (wss://quantus.internal), operator-run.infra-setup.shfor the roles above, plus the sharedgitea_ciuser creation (idempotent, so all three repos creating it is harmless).doc/wormhole-rewards.mdand the reward-address guidance; theinner_hashvalues themselves move with the node matrix.SCRAPE_NODES/SCRAPE_MINERSremain here and must agree with the two forks' matrices.validate metricsalready asserts everyquantus-*target is up, which is the drift check; note in each fork's matrix that adding a host means a scrape-target change here.Sequence
validate-only mode and run green against the hosts this repo deployed. No change here yet.fetch,deploy-node,deploy-minerhere (remove the jobs, keepdeploy-metricsand re-point itsneeds:), and flip both forks to deploy mode. Version pinsNODE_VERSION/MINER_VERSIONgo with the jobs.readme.md/CLAUDE.mdso the "source of infra truth" statement names the three repos and what each owns.infra-setup.shhere and the new ones in each fork so every host's sudoers matches its new deployer.Not changing
The
gitea_cirunner key, theRSYNC_SSH_KEYsecret (copy it to the two forks, never regenerate), firewall scoping rules, the no-op-when-unchanged discipline, and the validate checks. All of that moves as-is; the point of this issue is ownership, not behaviour.One more reason to finish this cut-over promptly: while this repo's deploy still owns
quantus-miner.service, any run of it (push tomain, manual dispatch) that lands during abenchmeasurement on quantus/miner will find the unit stopped, conclude "nothing changed but the miner is down", and start it mid-window. That corrupts the measurement rather than breaking anything, and the harness's utilisation check only guards the start of a run. Untildeploy-minerretires here, do not run this workflow while a bench run is in flight on the same host. After the cut-over the miner repo owns both the deploy and the bench and can serialise them under the same host lock.Step 2, miner half, done 2026-09-03: #6 merged after quantus/miner's deploy went green on both hosts from its
main(quantus/miner actions/runs/19). This repo no longer ships the miner.SCRAPE_MINERSstill lists benjy and quadbrat and the deploy triggered by #6 must show both miners up invalidate metrics.The mid-benchmark restart hazard noted above is gone with it: nothing here touches
quantus-miner.serviceany more.Remaining for this issue: the node half (quantus/chain#2), and step 3 (
readme.mdstill carries the stale 4090 hashrate table; see quantus/miner#2 for the measured numbers).