diff options
| author | Agando <roduccomm@gmail.com> | 2026-10-23 16:16:39 +0200 |
|---|---|---|
| committer | Agando <roduccomm@gmail.com> | 2026-10-23 16:16:39 +0200 |
| commit | 0c01cf48e83eecca953d0c6cc2dc949aed552f2f (patch) | |
| tree | d56068f1e0c0729db2aec8f4ca989d8f87fd20ac /api/debug/dashboard.php | |
| parent | 8d00c6949d19338e949618ddae4f1aef592cf58b (diff) | |
feat(newos4): fix ledger + norm clustering — the loop now knows what a fix was worth
Lifetime counts ranked an 8-day-old outage above today's live crash, and nothing asserted that a
shipped fix actually held: a regression of a fixed bug looked exactly like a new bug.
- api/debug/ingest.php: norm_key() stores `norm` (host/port/scheme/`?v=`/`//` stripped) — the client
hash covers the raw URL, so one outage became two signatures (`/ollama//api/tags` 18 203x and
`/ollama/api/tags` 16 540x). PHP + Python implementations verified byte-identical on 5 real
messages.
- scripts/newos4-ledger.py: data/maintenance/fixes.json maps norm -> {commit, fixed_at, note}, and
verify() returns REGRESSED / WATCHING / CLOSED / UNSEEN. "Seen after the fix" alone is not a
regression (a fix shipped 10d ago with one sighting 9d ago has been silent since) — regressed means
seen after the fix AND recent; otherwise the silence wins.
- scripts/newos4-triage.py: clusters (grouped by norm, recency-ordered), active<24h / stale>7d counts,
FIX| verdict lines; digest gains clusters + fixes and active/stale/cluster/regressed counters.
- api/debug/dashboard.php: Clusters / Active<24h / Stale>7d / Regressed columns and a red REGRESSED
detail line, so a regression is visible without reading JSON.
Seeded with the two fixes whose signatures exist: 2855c63 (pipe crash, WATCHING 69.3h silent) and
563a9be (emptyTrash, UNSEEN). Verdict logic proven on fixtures: recurrence 5m after fix -> REGRESSED,
silent 9d -> CLOSED, last seen 2d -> REGRESSED, fixed 5m ago/last seen 3d ago -> WATCHING.
Loop verified end to end: triage via newos4-maintenance.sh prints ACTIVE/CLUSTER/FIX lines,
maintain OK, skill audit 7/7, dashboard ALL VIEWPORTS OK.
Diffstat (limited to 'api/debug/dashboard.php')
| -rw-r--r-- | api/debug/dashboard.php | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/api/debug/dashboard.php b/api/debug/dashboard.php index 9b717c8..a20271f 100644 --- a/api/debug/dashboard.php +++ b/api/debug/dashboard.php @@ -203,14 +203,15 @@ if (is_array($rawChecks)) { <?php else: ?> <div class="table-scroll"> <table> - <tr><th>Signatures</th><th>Occurrences</th><th>Real</th><th>Noise</th><th>Self-ref</th><th>New reports</th><th>Generated</th></tr> + <tr><th>Signatures</th><th>Clusters</th><th>Active <24h</th><th>Stale >7d</th><th>Occurrences</th><th>Regressed</th><th>Generated</th></tr> <tr> <td><?= (int)($tri['records'] ?? 0) ?></td> + <td><?= (int)($tri['clusters'] ?? 0) ?></td> + <td><?= (int)($tri['active_records'] ?? 0) ?></td> + <td><?= (int)($tri['stale_records'] ?? 0) ?></td> <td><?= (int)($tri['occurrences'] ?? 0) ?></td> - <td><?= (int)($tri['real_records'] ?? 0) ?></td> - <td><?= (int)($tri['noise_records'] ?? 0) ?></td> - <td><?= (int)($tri['self_referential_records'] ?? 0) ?></td> - <td><?= (int)($tri['reports_new'] ?? 0) ?></td> + <td><?php $rg = (int)($tri['fixes_regressed'] ?? 0); ?> + <?php if ($rg > 0): ?><span class="status-pill degraded"><?= $rg ?> regressed</span><?php else: ?><span class="status-pill ok">none</span><?php endif; ?></td> <td><?= htmlspecialchars(substr($triage['generated_at'] ?? '', 5, 11)) ?>Z</td> </tr> </table> @@ -221,6 +222,13 @@ if (is_array($rawChecks)) { <div class="thread"><div class="body" style="font-size:.82em;"><?= (int)($t['count'] ?? 0) ?>× <span class="tag"><?= htmlspecialchars($t['type'] ?? '?') ?></span> <?= htmlspecialchars(mb_substr($t['message'] ?? '', 0, 110)) ?></div></div> <?php endforeach; ?> <?php endif; ?> + <?php foreach (($triage['fixes']['regressed'] ?? []) as $fx): ?> + <div style="color:var(--error);font-size:.85em;margin-top:8px;"> + <b>REGRESSED</b> <?= htmlspecialchars((string)($fx['commit'] ?? '?')) ?> — + <?= htmlspecialchars(substr((string)($fx['message'] ?? ''), 0, 90)) ?> + <span style="color:var(--muted)">(<?= htmlspecialchars((string)($fx['detail'] ?? '')) ?>)</span> + </div> + <?php endforeach; ?> <?php if ($triChecks): ?> <div style="margin-top:10px;font-size:.82em;color:var(--warn);"> <?php foreach (array_slice($triChecks, 0, 4) as $c): ?><div class="body"><?= htmlspecialchars($c) ?></div><?php endforeach; ?> |