chore: sync develop into develop-v2 (32 commits) - #1031
Closed
VijitSingh97 wants to merge 33 commits into
Closed
Conversation
The fixture drift guard compared only top-level build_state() keys, so nested payload growth (a new field under an existing section) left tests/frontend/fixtures/state.json stale and every component gated on the new field rendering its empty state across the frontend suite and the visual harness. The guard now reruns _gen_state.py (deterministic) as a subprocess to a temp file and diffs sorted dotted key paths — the Python mirror of CONFIG_KEY_PATHS_JQ in tests/integration/lib.sh — in both directions. Shape only, never values, so payload value tweaks do not churn the test. Subprocess, not import: the generator patches time.time process-wide. _gen_state.py takes an optional output-path argv for this. Closes #974. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
After the restore brings the baseline back up, the run no longer trusts "healthy": a stack recreated with harness-rendered creds is internally consistent, mines fine, and 401s every host-side RPC probe — the 2026-08 incident. Two checks now bind in the EXIT-trap epilogue: - env bake: the MONERO_NODE_PASSWORD line baked into the running dashboard container (docker inspect) must equal the on-disk .env line in RESTORE_DIR. The compare is env_bake_verdict in lib.sh — whole KEY=VALUE lines in, a verdict word out, values never printed — pinned by selftest.sh fixtures (match/mismatch/no-disk-value/not-baked). - host RPC: monerod must answer get_info with the on-disk creds (the exact probe the incident broke). The probe script travels over ssh stdin (bash -s) so creds stay on the box and the remote command string stays paren-free; only .status==OK is required, polled 60s. A failed proof — including a failed baseline apply/up, which previously could exit 0 on a passing run — warns RESTORE NOT PROVEN, names the docker-compose-up-from-disk recovery, and exits 1 from the trap. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
build_xvb_calc no longer collapses to {"enabled": false} when XvB is off:
the tier table, draw odds, and study-prior band are computable from local
config plus the cached public feeds, and the table is the enable/don't-
enable decision aid — hiding it behind the flag defeated its purpose
(#938). The flag still stops every xmrvsbeast.com fetch (the #726 egress
rule), so a never-enabled box honestly degrades to tier costs only and a
just-disabled box ages out through the existing staleness rules; the
live-credit context goes quiet on its own because build_state computes
realization only while enabled and Metrics reports "Disabled" tiers.
Client: computeXvbTier and xvbDecisionRows drop their enabled gates (the
what-if runs from local hashrate), XvbTierBlock renders when disabled
minus the Current/Target live-credit cards plus an off-explainer line,
and the earnings card keeps the XvB tab whenever the payload carries
tiers — enabled:false still keys every live-donation surface (stats
card, header split, Overview tiles, hero KPIs) off, unchanged.
Closes #938
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
testing-strategy.md's "What runs where" table promised a per-PR test-inventory drift check, but #414 deleted the drift machinery along with the committed file — tests/inventory.sh only generated, and always exited 0. The drift that can still exist is the generator drifting from the codebase: the gathering is grep-based, so a suite that moves or changes shape enumerates as zero without erroring. Make that failure real: after gathering, exit 1 if any suite count is zero (with :-0 defaulting, since grep -c on a deleted file emits nothing rather than 0). Run the script in the existing `shell` CI job, output discarded — the generated file stays git-ignored per #414. Reword the doc's table row and "test code is real code" bullet to claim exactly this check and no more. Not touched here: the diff-cover vacuous pass on shell-only diffs and the push-trigger branch list, both named in #981 as adjacent gaps. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ct, mixed time registers Expected-vs-actual pct: build_earnings_vs_actual withholds pct past 999% instead of publishing the raw ratio — a box idle for most of the window divides normal confirmed payouts by a near-zero expectation and renders five digits that read as a bug. pct=None with available+enabled both true happens only on this path, so ExpectedVsActualCard appends the explanation to the row tooltip without a new payload flag. Tari per-block reward: computeEarnings gated tariRewardPerBlock on tari_available (and on a positive what-if hashrate via the early return), while TariCard prints metrics.tari_reward unconditionally on the same page. The reward is a chain fact, so it now passes through whenever p2pool reported it; time-to-block and the per-day averages keep their channel/hashrate gates. The fiat '≈ per Block' follows since it derives from the same field. Last-block register: Global P2Pool Stats showed format_time_abs — a bare HH:MM:SS with no date or timezone cue — two cards from the cadence card's relative duration. last_blk (its only consumer) now renders '<duration> ago' from the same format_duration, 'Never' before the pool's first block; the cadence tooltip keeps the absolute anchor. Closes #992. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…#904) xmrig-proxy, dashboard, caddy, docker-proxy and docker-control reported Up with no health signal, so a dead-inside service (the v1.8.1 incident: the dashboard serving 502s behind an Up container) was invisible to `pithead status` and the container-health alert (#337). Each probe uses only tooling its image already ships and reflects readiness, not process-up: - xmrig-proxy: in-image script TCP-connects to the HTTP API port (bash /dev/tcp, port from env per the #90 no-creds-in-compose rule). The API is the honest probe: a failed stratum bind kills the process outright, while the API — what the dashboard polls — can die quietly. - dashboard: in-image script HEADs /api/state on the fixed 127.0.0.1:8000 bind with the venv's python3/urllib (slim image has no curl/wget); a 200 proves the server answers where Caddy proxies AND state assembly works. - caddy: busybox wget against the admin API's default localhost:2019 — 200 from /config/ means running with a loaded config. Not a vhost probe: scheme/port/auth vary with config and busybox wget can't speak the internal-CA TLS. - both socket proxies: busybox wget GET /_ping THROUGH HAProxy to the Docker daemon — proves the proxy brokers the socket. /_ping is in the image's default-allow set (PING=1), independent of the POST gating, so the rulesets stay untouched. No flapping or gating changes: none of the five has dependents, `pithead up` and the one-click upgrade never wait on health (`compose up -d`, no --wait), `pithead status` counts "starting" as pending rather than a problem, and the #337 alert already debounces 120s of continuous unhealthy. The dashboard's start_period covers app start plus a SQLite auto-heal rebuild so a warmup blip never false-fails a one-click upgrade's status view (the #622 lesson). All five probes verified against the real pinned images (healthy under cap_drop ALL + read_only + no-new-privileges; closed port / stopped app fails). Tier-1 coverage: tests/stack/test_compose.sh now asserts every rendered service carries a healthcheck, pins the five new probe commands, and checks no probe interpolates the proxy auth token. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
#972) A tor container restart/recreate kills every SOCKS connection, and monerod keeps the dead peer sockets: bench-observed at 0 in / 0 out peers for ~6h, get_info synchronized:false, height creeping, every healthcheck green. A plain monerod restart re-dials through the fresh tor and recovers in under a minute — so couple the restart to everything that cycles tor, and alert on the strand for the paths that can't be coupled. Recovery (root cause — tor cycling strands monerod): - compose: monerod's tor dependency gains restart: true, so every compose operation that restarts/recreates tor (up/apply/upgrade recreation, 'pithead restart tor') restarts monerod right after tor is healthy again (verified against compose v2.40: both the restart and the recreate path propagate, health-gated). Guarded by new test_compose.sh invariants. - tor_heal (#424 auto-heal) bypasses compose, so a successful tor heal now cycles monerod itself when the node is local (stop timeout 60s matches monerod's stop_grace_period; HTTP timeout outlasts it per #234). A failed monerod cycle warns and never refunds the tor budget slot. - new 'pithead restart monerod' leg: the manual re-dial for tor restarts that happened outside the stack (docker daemon restart, manual restart). Detection (for whatever still slips through): - MoneroClient.get_sync_status passes the raw get_info `synchronized` flag through — required because a stranded node can report a stale target_height of 0, which the height math reads as "synced". Only the RPC path carries the key; log-scrape/remote paths stay verdict-free. - data_service debounces it with the existing NodeHealthMonitor (down_after=NODE_STALE_AFTER_SEC, 600s env-tunable): ever_up doubles as "ever synchronized", so initial sync never alarms. Surfaced as monero_sync.stale in the snapshot and fed to the alerter. - alert_service emits the out-of-sync/back-in-sync edges through the existing node_down/node_recovered toggles (no new config surface, no reference.json change) and tallies the incident for the daily digest. - doctor: new Monero sync check probes get_info from the host with the .env digest creds (monerod image has no curl) and WARNs on synchronized:false, naming 'restart monerod' as the fix. WARN not FAIL: initial sync reads identically. Tier 1 covers all decision logic (pytest client/data/alert/tor_heal, tests/stack doctor + restart + compose invariants), tier 2 the flag over the wire; the real strand + re-peer remains bench-only (tier 4). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…blast radius, unify the node_down story The docker-control comments documented the start/stop surface as p2pool/xmrig-proxy + tor while tor_heal now also cycles monerod after a heal; both comment sites name it. telegram.md's overview table still described node_down as unreachable-only while its event-key table covered the out-of-sync strand — the two now tell the same story. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…r-loss fix: restart monerod whenever tor restarts, and notice when it strands (#972)
…althchecks feat(compose): healthchecks for the five services that had none (#904)
…ble-when-disabled fix(dashboard): keep the XvB decision table visible while XvB is off (#938)
…e-proof test(e2e): prove the restored stack runs the on-disk config (#971)
…ift-nested test(dashboard): fixture drift guard pins every depth, not just top-level keys (#974)
…drift-ci test(ci): the inventory drift check now exists — and inventory.sh can actually fail (#981)
…ities fix(dashboard): three display honesty fixes — pct cap, known reward shown, one time register (#992)
dashboard.js ran its side effects at import, so it was the only frontend module node --test could not even load. Wrap the whole client in an exported initDashboard() whose parameters name the browser seams (DOM, storage, fetch, history, timer, render) with the real facilities as defaults, and guard the boot call on `document` — the browser runs exactly the same statements in the same order; under Node the import is side-effect-free. windowFromUrl/loadSeries take their inputs as arguments and are exported alongside REFRESH_MS/FETCH_TIMEOUT_MS. dashboard.test.mjs (22 tests) drives the real loop through fakes and observes it via the props handed to renderApp: the pre-tick abort invariant and the hung-poll/inflight recovery (#382), disconnected state keeping the last snapshot, boot sequencing and preference seeding, zoom/range/avg query building, and every App handler's state transition + persistence + fetch/no-fetch contract. Render output stays components.test.mjs's job; normalizer semantics stay logic.test.mjs's. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… an overlap check (#1000) diff-cover exits 0 with 'No lines with coverage information' whether the diff is shell/docs-only (fine) or changed dashboard Python a stale coverage.xml never measured (a green gate that proved nothing). make test-patch-coverage now runs scripts/patch-coverage.sh: diff-cover as before, then a file-level overlap check on its green paths. A diff with nothing under build/dashboard/mining_dashboard/ passes loudly and says the gate is not applicable; a changed measured file absent from coverage.xml fails, naming the file. Comment-only changes to measured files still pass — the file is present in the XML, so diff-cover's no-measurable-lines verdict stands. Overlap logic is fixture-tested via --self-test, driven from the stack suite like the operator-strings guard. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…js-tests test(frontend): the client entry point gets its tier — 22 tests via the issue's own seam refactor (#903)
…-vacuous test(ci): the patch-coverage gate can no longer pass vacuously (#1000)
…ary (#1001) RigForge writes noop (already on target) and throttled as first-class terminal statuses since rigforge#320 (v1.12.0), and control-apply can end terminal failed — but the upgrade poll matched only applied|rolled_back| failed and the apply poll only applied|rejected|rolled_back. A noop or throttled upgrade burned the full 90s poll cap and recorded "accepted — upgrade still running"; a failed apply burned the 20s deadline and recorded "accepted". - Upgrade poll: noop and throttled are terminals now, recorded with the rig's own reason (the frontend already renders both statuses). - Apply poll: failed is a terminal now (the rig could not restore its rollback backup), recorded with its reason and audited as failed. - The legacy failed+"throttled…" remap stays for pre-v1.12.0 rigs (v1.11.2 is the supported floor) but is anchored to the leading word: a modern rig's genuine failed can mention the throttle too ("throttle state unavailable", rigforge#321's fail-closed refusal) and must stay a fault. Drop the remap when the fleet floor reaches v1.12.0 — the v2 appliance bakes v1.15.0. Stack suite gains 7 assertions across both polls, fail-first-proven: exactly those 7 fail against the old poll cases (1704+7=1711 green). Dashboard doc outcome lists updated to match. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ll-vocab fix(control): the worker pollers speak RigForge's full terminal vocabulary (#1001)
The Tari chain on the live reference deployment measured 149 GiB on 2026-08-15 (du -sh, gouda). The repo's own figure history makes the growth rate linear: ~135 GB (2026-06-12, #232) -> ~139-140 GB (2026-07-02, #334) -> 149 GiB, i.e. ~6.6-6.8 GiB/month over two independent intervals. The 170 GiB budget's remaining headroom is ~21 GiB — about three months. 200 GiB restores ~51 GiB of headroom (~8 months at the observed rate). The summed minimums move with it: ~330 GB pruned / ~530 GB full across setup preflight, doctor, and every doc that cites them. Touched doc lines adopt the develop-v2 reconciled measured figures (#1005: Monero ~270 GB full / Tari ~150 GB) so both branches read identically and the develop -> develop-v2 sync merges clean. Mirrors PR #1011 (develop-v2). Upstream's integration guide still advises "50GB+ SSD" for a base node — a third of the live archival chain — so live measurement stays the budget's source of truth. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…abulary (#1009) parse_worker_control_status filtered rigforge.control's mirrored outcome to {applied, rejected, rolled_back} — a subset that predates rigforge#320's noop/throttled terminals and #1001's own failed addition to the apply poll. RigForge v1.15.0 now ships the #346 control mirror in its enriched feed for the first time, so this stale filter is live: a mirrored failed outcome drops silently, leaving a #185 change-history row "accepted" forever in exactly the slow-terminal case the mirror exists to close. - xmrig_client._CONTROL_TERMINAL: applied/rejected/rolled_back/failed/ noop/throttled — the same six statuses pithead's own control_worker_apply/ control_worker_upgrade poll cases accept (#1001). started (rigforge#320's in-flight upgrade marker) stays non-terminal alongside this dashboard's own accepted/running placeholders. - storage_service.reconcile_worker_config_status: the same six-status allowlist (module constant _RECONCILE_TERMINAL, mirroring the client's _CONTROL_TERMINAL) gates the accepted-row UPDATE. status is recorded verbatim — the frontend's STATUS_META (workerview.mjs) already renders every member of this vocabulary, added for the #597 upgrade badge. - docs/workers.md: the reconcile vocabulary list now enumerates all six outcomes, and the stale "RigForge does not ship this mirror yet" note is replaced with the v1.15.0 floor. Dashboard suite gains 3 assertions, fail-first-proven against the old allowlist (1703+3=1706 green). Patch coverage 100% on the 3 changed lines. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The two tuples are declared separately on purpose (parser with the client, allowlist with the store, neither importing the other for six strings) — so nothing stopped them diverging. A status the parser accepts but the store does not act on silently stops reconciling and freezes history rows at accepted: precisely the bug the pair was just widened to fix. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…dget-develop fix: raise the Tari disk budget to 200 GiB
…ncile-vocab fix(dashboard): the enriched-feed reconciler speaks RigForge's full terminal vocabulary (#1009)
…#942, #1002) #942 adds five rows to the live e2e matrix, each following the existing axis/scenario idioms in scenarios.sh + assert_running_state: - tari.mode=remote (remote-tari-main-secure): the bundled tari container/onion absent, the sync gate proven against a remote target — needs --remote-tari-host, mirrors monero's own remote-mode handling. - p2pool.stratum_tls=true (local-pruned-main-stratum-tls): a live TLS handshake on the published stratum port, and the served cert's fingerprint matches the one operators are told to pin. - network.tor_egress_firewall=false (local-pruned-main-firewall-off): no pithead-tagged rule installed AND a real clearnet dial from a mining_net container succeeds — the mirror of the fail-closed default assert_egress_posture/fault_firewall_rollback already prove elsewhere. - payout confirmation (local-pruned-main-payout-confirm): a "payout_confirm=env" marker resolves to a real monero.view_key (+ optional tari pair) from IT_MONERO_VIEW_KEY/IT_TARI_VIEW_KEY/ IT_TARI_SPEND_PUBLIC_KEY; asserts PAYOUT_CONFIRM_ENABLED and the dashboard's own earnings.confirmed.enabled read true (a real confirmed payout needs days no e2e run has). - dashboard.secure=false + p2pool.pool=main (local-pruned-main-insecure): decouples insecure mode from its previously nano-only pairing. expected_services/absent_services now gate tari on tari.mode (was hardcoded always-on) and wallet-rpc/tari-wallet on view_key presence. #1002 adds two legs to run_rigforge_control: (a) --rigforge-upgrade: POSTs the rig's own already-installed version through /api/control/worker-upgrade and asserts noop — exercises the dashboard->host-runner->rig /upgrade chain (or its client-side shortcut, depending on the dashboard's poll-cache freshness) without ever rebuilding the rig, including the noop/throttled/failed vocabulary #1001 taught control_worker_upgrade's poll loop. The host independently re-derives "latest" and refuses any mismatch before dialing, so this can only ever land on noop or a safe rejected. (b) a second writable-key edit, pools, beside the existing max_temp_c one. The enriched feed exposes no live readback for writable config values, so the restore target is the dashboard's own last_applied.pools record — the same source Worker Inspect's real editor prefills from — and the probe value is operator-supplied (IT_RIG_POOLS_PROBE) since pithead treats pools as opaque passthrough. selftest.sh: 165 -> 201 assertions, all passing (36 new, pinning the pure resolve_overrides/expected_services logic + scenario existence). The live-only proofs (TLS handshake, firewall dial, payout wiring, pools/upgrade legs) have no unit tier, same as every other --rigforge-control leg in this file — they need bench validation. docs/dev/integration-testing.md and docs/dev/testing-strategy.md updated for the new axes/legs/flags; the "insecure + main matrix row" known gap is marked resolved. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ing upgrade history (#1013-#1015) Three issues sharing one data plumbing seam (per-rig hashrate history + per-rig change records), implemented together on one branch. fix (#1014): a one-click rig upgrade left no per-rig record. handle_worker_upgrade returns 202 immediately (a rebuild can take minutes) and never awaited a result the way handle_worker_apply does, so nothing ever called _record_worker_result for it. Now a tracked background task (server.py's _finalize_worker_upgrade, referenced in app["_bg_tasks"] so it can't be GC'd mid-flight, cancelled on app shutdown) waits for the host runner's terminal result and records it — one row per upgrade attempt, worker + target version + terminal status + reason — independent of whether the operator's tab stays open to see it land. worker_config gains a `type` column ('apply' | 'upgrade', migrated forward for existing installs) so get_last_applied_worker_config can exclude an upgrade's {"version": ...} marker from the config-editor prefill, while get_worker_hashrate_by_config's existing status=='applied' boundary logic picks up an applied upgrade as a version boundary for free — hashrate no longer misattributes a build change to whatever config happened to be active. The recordable-status set widens to include the upgrade-only noop/throttled terminals. The change-history table's "Changed" column now reads "upgrade → vX.Y.Z" for an upgrade row instead of the literal key name "version". feat (#1013): Worker Inspect gets the fleet chart's range-selectable hashrate view, sized to what a single rig's data can honestly support. /api/worker takes range=/from=/to= (mirroring /api/state) and feeds get_worker_history through the existing _downsample_gauge_rows via _gauge_series — no new table, no new collector. The client reuses chart.mjs's palette/gradient idioms in a new WorkerChartCard, not a second charting approach: 24 Hr/1 Wk/All only (worker_history samples ~5 min, so "1 Hr" would be dishonest; retention is 30 days, so "All" already means what "1 Mo" would), no avg-window toggle (only h15 is stored). A rig with no samples yet renders an explicit empty-state message instead of an empty axis. Read access rides the existing DASHBOARD_CONTROL_ENABLED gate unchanged — deliberately deferred, see below. feat (#1015): config applies and rig upgrades mark the chart, a fourth instance of the hidden-0-1-axis scatter pattern Events/Raffle/Payouts already use. One marker dataset, per-point pointStyle (diamond for a config apply, triangle for an upgrade) and colour (accent for an applied outcome, muted for rejected/rolled_back/failed/throttled/noop/accepted — shown, not dropped, so "we tried and it bounced" still explains a flat stretch). Markers are the same range/window slice of worker_config as the hashrate line, so nothing renders outside the chart's own visible window. Deliberately deferred, with reasons: - Read-gating: #1013 raises whether viewing a rig's own telemetry should require the control channel. Left riding the existing gate — widening a read boundary is a separate access-model decision, not a rider on a charting change. - Accepted/rejected share-delta series on the worker chart: #1013 marks this optional ("out of scope unless it's cheap"); no per-poll differencing path exists for worker-level counters today, so it isn't. - control_audit's `keys` sanitizer (naming the rig in a worker-upgrade audit row): #1014 itself flags this as "changed carefully or not at all" — a JSONL-injection chokepoint in the host bash script, out of scope for this Python/JS change. - RigForge's own /status mirror for upgrades (the "second bug" #1014 flags as unverified): the worker_config row this change now writes would close that gap by construction if RigForge mirrors upgrades the same way it mirrors applies, but RigForge's source isn't in this repo to confirm the premise. make lint: clean (sh/py/js/yaml/md/docs-voice/operator-strings/proto/toml). make test-dashboard: 1717 passed, 97.01% coverage (gate 80%). make test-frontend: 317 passed, 0 failed. make test-patch-coverage: 100% on all 4 changed Python files (gate 90%). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… key (#1023) The runner's pre-download guard tested the LOCAL cosign.pub, so it was blind to the one upgrade that needs it: an install cut before signing engaged moving to a signed release. Prod hit this on v1.18.1 — the guard passed, the bundle downloaded and extracted, and the abort landed inside the new CLI's image gate after a full config re-render, leaving the operator to finish from a shell. Every release bundle ships cosign.pub (make_bundle copies the committed key unconditionally), and control_upgrade already refuses source checkouts up front, so cosign is a flat precondition of a one-click upgrade. Check it beside the source-checkout refusal: before the throttle claim and before the GitHub dial, so a refusal costs nothing and the operator can install cosign and retry at once. Tier 2 covers both halves of the widened condition — key-less and key-holding — each asserting the refusal lands with nothing dialled, nothing extracted and no throttle claimed. The $UPG fixture gains a cosign stub so the paths that are meant to proceed no longer depend on whether the host happens to have one. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…grade-precheck fix(upgrade): require cosign before the one-click download, key or no key (#1023)
Routine sync, 32 commits. Five conflicts, all resolved against the code rather than by preferring a side: - pithead / control_upgrade: UNION. The appliance refusal (v2) and the cosign precondition (#1023, develop) are independent preconditions and both belong. Appliance is checked FIRST: an appliance cannot take a tarball upgrade whatever the host holds, so that is the informative answer. - docker-compose.yml / caddy: UNION. v2 added the appliance TLS mount, develop added the config-loaded healthcheck (#904). - Makefile / test-patch-coverage: took develop. #1000 replaces the bare diff-cover call with scripts/patch-coverage.sh, which closes the vacuous pass where diff-cover exits 0 on "No lines with coverage information". - web/server.py: UNION. v2 added the backup handlers (#908), develop added _RECORDABLE_WORKER_STATUSES and the change_type parameter (#1014). Verified no duplicate definition results and that the new parameter defaults, so existing 4-arg callers still work. - docs/dev/testing-strategy.md: kept develop's new #972 row AND v2's wording of the double-outage row. The wording was decided by the code, not by branch preference: data_service readmits on monerod alone and test_readmit_ignores_tari_state_entirely pins it. Gates on the merge result: make lint 0 errors (docs voice + operator strings clean), stack 2333/0, dashboard 1818/0 at 96.78% coverage, frontend 375/0. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This was referenced Aug 16, 2026
Collaborator
Author
|
Superseded by the fresh sync — this one went stale when #1035 landed on develop-v2. |
VijitSingh97
added a commit
that referenced
this pull request
Aug 16, 2026
…v2-0816b chore: sync develop into develop-v2 (supersedes #1031)
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.
Routine sync so the v2 wave PRs open against a current base. 32 commits from
develop.Conflicts, and how each was decided
Five conflicts. None was resolved by preferring a branch — each was decided against the code.
pithead/control_upgradedocker-compose.yml/caddyMakefile/test-patch-coveragediff-covercall withscripts/patch-coverage.sh, closing the vacuous pass where diff-cover exits 0 on "No lines with coverage information". Strictly better; confirmed the script exists in the merged tree.web/server.py_RECORDABLE_WORKER_STATUSESand thechange_typeparameter (#1014). Verified: no duplicate definitions result, and the new parameter defaults so existing 4-arg callers still work.docs/dev/testing-strategy.mddata_servicereadmits on monerod alone, andtest_readmit_ignores_tari_state_entirelypins exactly that.Gates on the merge result
make linttests/stackMerge first, before the v2 wave PRs, so they open against a current base.