fix: dashboard and CLI agree on what is deployed - #46
Merged
Conversation
Usability-review finding 9. Three ways the dashboard contradicted reality:
1. monitor.py classified by substring, so ROLLBACK_COMPLETE counted as BOTH
deployed ("COMPLETE") and failed ("ROLLBACK"), and not_deployed was
computed by subtraction — five healthy stacks plus one rolled back
reported deployed=6, failed=1, not_deployed=-1. The browser classified the
same status differently, so terminal and UI disagreed.
2. The UI's denominator was Math.max(stackCount, 10), so a healthy greenfield
deployment read 6/10 and looked permanently incomplete.
3. Module labels differed three ways: monitor.py said "6a/S2", index.html said
"Module 1", deploy.sh's MODULE_MAP says E.
Fixes:
- Classification lives in monitor.classify() and ONLY there. Each stack
carries a `state`; the browser renders that field. Its local classifier
stays as a fallback for older status.json files, with identical rules.
- Scope comes from the deployment contract: expected_stacks() decides which
stacks this configuration promises (federation-aware — the account picks the
role). Anything else is state "not-applicable", rendered dimmed as "Not In
Scope" and never counted as missing or failed. The denominator is the
contract's count.
- Summary counts come from the emitted states, never by subtraction, so a
negative count is now unrepresentable.
- monitor.py carries the module/team labels (matching MODULE_MAP) and the
browser prefers them; STACK_META in the HTML is only a fallback.
- Cleared monitor.py's pre-existing lint debt while touching it (CI lints
whole changed files): sorted imports, no bare try/except/pass, no
datetime.utcnow(), logger instead of silent swallows.
tests/test_dashboard.py pins all three: rollback is failed and only failed,
states are mutually exclusive, the fake denominator floor is gone, the UI
prefers the emitted state, and the module labels are checked against
MODULE_MAP parsed out of deploy.sh (a real drift guard — it fails if either
side is renamed).
Verified live against the test rig: the deployed footprint now reports
total_stacks=6, deployed=6, failed=0, not_deployed=0, not_applicable=4, with
the in-scope states summing exactly to the total and no negative counts. That
same deployment previously displayed 6/10 with four stacks looking absent.
149 tests green, ruff clean.
|
Commit: Security Scan Results
|
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.
What
Usability-review finding 9: the dashboard contradicted reality three ways.
Arithmetic that could go negative.
monitor.pyclassified by substring, soROLLBACK_COMPLETEcounted as both deployed ("COMPLETE") and failed ("ROLLBACK"), andnot_deployedwas computed by subtraction. Five healthy stacks plus one rolled back reporteddeployed=6, failed=1, not_deployed=-1. The browser classified the same status differently, so the terminal and the UI disagreed with each other.A fake denominator. The UI used
Math.max(stackCount, 10), so a healthy greenfield deployment read 6/10 and looked permanently incomplete.Three sets of module labels.
monitor.pysaid6a/S2,index.htmlsaidModule 1,deploy.sh'sMODULE_MAPsaysE.Fixes
monitor.classify()and only there. Each stack carries astatefield and the browser renders it; the browser's own classifier remains as a fallback for olderstatus.jsonfiles, with identical rules.expected_stacks()decides what this configuration promises, federation-aware. Anything else isnot-applicable, shown dimmed as "Not In Scope", never counted as missing or failed. The denominator is the contract's count.monitor.pyowns the module/team labels and the browser prefers them.monitor.py's pre-existing lint debt while touching it (CI lints whole changed files): sorted imports, no baretry/except/pass, nodatetime.utcnow(), a logger instead of silent swallows.Verified live
Against the running test environment:
That same deployment previously displayed 6/10 with four stacks looking absent.
Tests
tests/test_dashboard.pypins all three defects: rollback is failed and only failed, states are mutually exclusive, the denominator floor is gone, the UI prefers the emitted state, and module labels are checked againstMODULE_MAPparsed out ofdeploy.sh— a real drift guard that fails if either side is renamed.149 tests green, ruff clean.