fix: unedited dashboard config preview reports zero changes - #693
fix: unedited dashboard config preview reports zero changes#693VijitSingh97 wants to merge 2 commits into
Conversation
Two phantom rows on the versioned deploy layout. The control runner's systemd unit invokes pithead from the version directory while .env was rendered through the `current` symlink, so every $PWD-derived path (CLEARNET_STATE_DIR visibly; CONTROL_DIR, CADDY_LOG_DIR and TARI_WALLET_SECRET_FILE silently) re-rendered under the other spelling and previewed as a change — and a commit rewrote .env to the versioned spelling, breaking the repoint-`current` rollback convention. The render now keeps the spelling already in .env whenever both resolve to the same physical directory (preserve_path_spelling); a real move still previews as before. migrate_dashboard_data gets the matching physical-equality guard so a preserved spelling can't trip its both-locations stop on one directory counted twice. Separately, the editor round-trip carries the config.reference.json default for every dashboard.energy key the live config omits (read_config merges the reference UNDER the sparse live copy), and the raw jq equality in control_preview/control_approval_gate read those spelled-out defaults as an energy edit. Both sides are now filled from the same reference defaults before comparing (energy_block_changed); the comparison still fails toward "changed" on an unreadable reference. Tier-1 coverage: control-rig case proving an unedited reference-merged round-trip previews zero changes and audits no DASHBOARD_ENERGY, and a versioned-layout sandbox (version dir + current symlink) proving a dry-run/apply from either spelling is a no-op that keeps .env spellings, while a genuine data-dir move still reports DEST. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ymlink-spelling case The sandbox case seeded no dashboard data, and its unedited apply short-circuited at "no changes" — the #455 guard was never reached, so reverting it changed nothing the test could see. Seed a live DB marker and apply a real change from the versioned dir: the guard must read the `current` and versioned spellings as one physical dir (apply exits 0, data stays put) instead of hard-stopping on data-at-both-locations. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Closing as superseded by #700, which fixes the same two root causes (#695's logical-vs-physical $PWD spelling flip and #696's reference-merged energy defaults firing a phantom change) with a smaller mechanism: SCRIPT_DIR is canonicalized once via pwd -P, making every render deterministic, instead of preserving whichever spelling .env happened to have. The two PRs rewrite the same jq lines and insert tests at the same points, so no merge order lands both. #700's regression tests were verified to fail on pre-fix code (34 asserts, both bugs by name). The migrate_dashboard_data double-count hazard this branch guarded against cannot arise once renders are deterministic. The physical-path ownership comparison landed separately in #692 still covers units written with the old spellings. |
Problem
On gouda v1.9.3, an unedited dashboard config preview (
POST /api/control/previewwith the config round-tripped from/api/config) reports two phantom INFO changes:CLEARNET_STATE_DIR: /srv/code/current/... → /srv/code/pithead-v1.9.3/...Root causes
Path spelling.
pitheadcd's to its own directory at startup and bash keeps the logical path, so$PWDis spelled via thecurrentsymlink from an operator shell but via the versioned install dir from the control runner's systemd unit. Every$PWD-derived path re-renders under the other spelling. OnlyCLEARNET_STATE_DIRwas visible (genericdescribe_changefallthrough), butCONTROL_DIR,CADDY_LOG_DIR, andTARI_WALLET_SECRET_FILEwere silently diffing too — a commit would rewrite.envto the versioned spelling and break the repoint-currentrollback convention. On an all-default install the chain data dirs would flip as DEST rows.Energy block. Not the #646 price feed (it never writes config — verified). The editor's
read_configmergesconfig.reference.jsondefaults UNDER the sparse live config, so an untouched save posts back every energy default spelled out whileconfig.jsonstays sparse; the raw jq equality incontrol_preview/control_approval_gateread that as an edit.Fix
preserve_path_spelling(+physical_path): the render keeps the spelling already in.envwhenever old and new resolve (pwd -P) to the same physical location, applied to all ten path keys at theparse_and_validate_config/render_envchokepoints. A real move (different physical dir) still previews and warns exactly as before.migrate_dashboard_datagets the matching physical-equality guard, so a preserved spelling can't trip the "data exists at BOTH locations" stop on one directory counted twice.energy_block_changed: both sides filled from the sameconfig.reference.jsondefaults before comparing, shared by the preview row and the commit gate's audit key. Fails toward "changed" on an unreadable reference — never toward hiding a real edit.Coverage (tier 1 per docs/dev/testing-strategy.md)
changes: [], still commits, and audits noDASHBOARD_ENERGY; the existing real-edit, bundling-refusal, and smuggling tests all still pass.currentsymlink): baseline apply through the symlink, then dry-run and apply from the versioned dir → zero porcelain rows and.envspellings intact (incl. the tari secret file); a genuinemonero.data_dirmove still reportsDEST.make lintandmake testpass (stack suite 1514 ✓ / 0 ✗). Changelog +docs/operations.mdlayout note updated. Ponytail review: lean, nothing to cut (energy_block_changeddedups a previously duplicated jq expression).Note for the deployed fleet: gouda's systemd unit still carries the versioned
WorkingDirectory/ExecStart— harmless now (either spelling renders identically); the unit self-updates on the next apply cycle.🤖 Generated with Claude Code