feat(admin): schedule and spend on the graph, and the HTML honesty carry-through (issue #175) - #178
Merged
Merged
Conversation
…rry-through (issue #175) The third insights slice: the facts the graph computed and never said. - Trigger nodes gain cost (the typed spend foldTriggerCosts maps onto the node id) -- a node FACT beside runs/lastOutcome, no new edge kind, no new flag, the closed vocabularies pinned unchanged. The assemblers wire it with one extra file read and two pure folds over the scan they already paid for; the GRAPH view's entry-plus-r-only refresh policy is untouched and the real-poll pin proves it. - Cron rows finally render next/overdue: next as a countdown against the model's own generatedAt (never a live clock; a stale model shows its stale countdown honestly), overdue in the error color. Both in the TUI and in /dispatch graph text. - Spend renders only through fmtCost/styler.fmtCost, so a plan-covered trigger reads plan:<id> on the graph too, never $0.00. - graph.html: normalizeModel carries meta.chainRefusals, meta.injectedUnreachable and observed-edge lastEndedAt; the legend states the two counters the text and TUI always stated; an observed wire's label says how fresh it is beside its count. Node cost is deliberately NOT allowlisted there: the page cannot use the from clause, and a hand-copied money formatter is a parity liability the insights artifact avoids by taking the real formatter. Specs in the same PR: REQ-TOPOLOGY-GRAPH gains (h); REQ-GRAPH-HTML-EXPORT amended (honesty counters, edge recency); DES-GRAPH-EDGE-DERIVATION and DES-ADMIN-VIA-PI-EXTENSION amended; REQ-COST-ANALYTICS UNCHANGED, checked; DES-COST-FOLD-BY-SCAN UNCHANGED, checked. docs/graph.md updated. Suite green in the CI posture: 2197 tests, 0 skipped, live Valkey. Signed-off-by: Rob Boerman <robboerman@live.nl>
edgehero
force-pushed
the
feat/graph-spend-schedule-badges
branch
from
August 12, 2026 07:49
41691eb to
f224260
Compare
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.
Third slice of #175, stacked on #177: the facts the graph computed and never said, plus the honesty counters the HTML page dropped. The diff collapses to this slice once #177 merges.
What
buildGraphModelgainstriggerCosts(thefoldTriggerCostsmap from feat(admin): spend per trigger and per repo, and the COSTS table cycle (issue #175) #177, keyed by this module's own node ids) and trigger nodes carrycost— a node FACT besideruns/lastOutcome. No new edge kind, no new flag: the closed vocabularies are pinned unchanged by a new test. Both assemblers wire it with one extra file read (subscriptions) and two pure folds over the scan they already paid for, so the GRAPH view's entry-plus-r-only refresh policy is untouched — the real-10ms-poll pin proves it.next/overdueMswere computed by the model's first slice and rendered by nothing (the design-to-data gap class the Show triggers and flows as a graph on the admin panel #54 delivery lesson names). TUI rows and/dispatch graphtext now saynext 4h— a countdown against the model's owngeneratedAt, never a live clock, so a stale model shows its stale countdown honestly — oroverdue 2hin the error color, the money backstop's own signal.fmtCost/styler.fmtCost, so a plan-covered trigger readsplan:<id>, never$0.00(pinned).normalizeModelgainsmeta.chainRefusals(sorted, clipped),meta.injectedUnreachable(sorted, capped) and observed-edgelastEndedAt; the legend states the two counters the text and TUI surfaces always stated, and an observed wire's label carries recency beside its count ((3× · 2d ago)) via the injected-nowrelTime, so byte-determinism holds. Nodecostis deliberately NOT allowlisted into graph.html: the page may not use thefromclause, and a hand-copied money formatter pinned by parity test is a liability the insights artifact (next slice) avoids by taking the real shared formatter.◷/¤twins, but plain words plus fmtCost's own shapes carry the facts with zero ambiguous-width risk, and the ASCII-purity pin stays as it was.Specs
REQ-TOPOLOGY-GRAPHAMENDED with (h): schedule and typed spend as node facts, fmtCost-rendered, vocabularies closed.REQ-GRAPH-HTML-EXPORTAMENDED: the artifact states the same honesty counters as the other two surfaces; observed-edge recency.DES-GRAPH-EDGE-DERIVATIONandDES-ADMIN-VIA-PI-EXTENSIONAMENDED (one clause each, rationale recorded).REQ-COST-ANALYTICSUNCHANGED, checked (foldTriggerCostsgained consumers, not semantics).DES-COST-FOLD-BY-SCANUNCHANGED, checked.docs/graph.md: the trigger-line example and the schedule/spend reading guide.Tests
Suite green in the CI posture (2197 tests, 0 skipped, live Valkey). New pins:
triggerCostspass-through with vocabularies unchanged, TUI rows saying next/overdue/plan:kimi(and never$0.00), no-claim-when-no-scheduler, text renderer twins, the page carrying refusals/unreadable-dirs, and the observed label's recency grammar (the one amended pin — the old(N×)regex predates the suffix and the amendment keeps its "a potential wire never carries a count" claim).Stacked on #177.