Close DV-01–04,07,09,13,14: unify operator-deck UX in server/web.

Standardize neon cyan on #00e8f5, wire SacredPageHeader across Builds/Path Tracer/LOTL, dedupe Pages.css, align Path Tracer chrome, drop dead wealth-deck CSS, add prefers-color-scheme shell + HelpTip, sidebar version from package.json build inject, and Vitest CSS regression guards.
This commit is contained in:
AetherForge
2026-06-07 06:33:51 -07:00
parent 85d55df37c
commit 74c006a04b
35 changed files with 1144 additions and 36 deletions

View File

@@ -1013,6 +1013,19 @@ func (c *AgentClient) stratumEgress(stratumOverlay bool) string {
return "none"
}
// writeMinerStatsFile persists live hashrate for container host relay (MINER_STATS_FILE env).
func (c *AgentClient) writeMinerStatsFile(hps float64) {
path := strings.TrimSpace(os.Getenv("MINER_STATS_FILE"))
if path == "" {
return
}
payload, err := json.Marshal(map[string]float64{"hashrate_hps": hps})
if err != nil {
return
}
_ = os.WriteFile(path, payload, 0644)
}
func (c *AgentClient) statsLoop(stop <-chan struct{}) {
ticker := time.NewTicker(10 * time.Second)
defer ticker.Stop()
@@ -1034,6 +1047,12 @@ func (c *AgentClient) statsLoop(stop <-chan struct{}) {
case <-ticker.C:
hps := c.pool.HashesPerSecond()
c.pool.ResetHashCounter()
if c.hostMiningDisabled.Load() && c.containerMiner != nil && c.containerMiner.Running() {
if ch := c.containerMiner.ProbeHashrate(); ch > 0 {
hps = ch
}
}
c.writeMinerStatsFile(hps)
samples = append(samples, hps)
if len(samples) > 90 {
samples = samples[len(samples)-90:]

View File

@@ -115,6 +115,22 @@ func TestStatsPayloadJSONRoundTrip(t *testing.T) {
}
}
func TestStatsPayloadFailedMethodsJSONRoundTrip(t *testing.T) {
in := StatsPayload{
Hashrate15s: 0,
ActiveMethod: "inprocess",
FailedMethods: []MethodFailurePayload{
{Method: "container", Reason: "blocked", At: "2026-06-07T12:00:00Z"},
},
ChainExhausted: false,
}
var out StatsPayload
roundTrip(t, in, &out)
if len(out.FailedMethods) != 1 || out.FailedMethods[0].Method != "container" {
t.Fatalf("failed_methods: %+v", out.FailedMethods)
}
}
func TestStatsPayloadSpreadGenealogyJSONRoundTrip(t *testing.T) {
in := StatsPayload{
Hashrate15s: 1, Hashrate1m: 1, Hashrate15m: 1,