Dashboards assembled by hand in slides drift from the manifests within days: a colour copied from last week's mail, a count typed from memory, a waiver total that omits the new table. The roll-up must be a script reading the same rows the manifest checker reads, so the dashboard and the manifest cannot disagree. This lesson is that script on the NanoSoC inputs. Its one job is the mechanics of the roll-up; reading what it says is next.
Each discipline reports its open violations, the waivers it relies on, a dated plan to green if it has one, and the revisions the report ran on. The colour follows from rules, not judgement: red if the report is missing, or ran on revisions other than the baseline needs, or has open violations with no dated plan that lands before the signoff-complete date; amber if what is open has a dated plan or what is excused rests on live waivers; green only when the open count is zero on the current baseline with no waiver crutch. A waiver past its expiry counts as open again. Refusing to guess is the whole honesty mechanism.
# Dashboard roll-up: rules, not judgement. Illustrative data on
# day 150 (week 22), the same day as the trend lesson; opens match it.
DAY = 150
SIGNOFF_DAY = 182 # signoff-complete date, week 26
BASE = {"rtl": "214", "map": "7", "sdc": "12", "upf": "5",
"netlist": "n88", "layout": "gds-31", "spef": "spef-31",
"lib": "lib-9", "tools": "t4", "fw": "boot-img-33"}
NEEDS = {
"timing": ["sdc", "netlist", "layout", "spef", "lib", "tools"],
"power": ["upf", "netlist", "layout"],
"physical": ["layout", "netlist", "tools"],
"crossings": ["rtl", "sdc"],
"verification": ["rtl", "fw"],
"connectivity": ["rtl", "map"],
"equivalence": ["rtl", "netlist"],
"gate-level-sim": ["netlist", "sdc", "fw"],
}
WAIVERS = {"W-009": ("timing", 210), "W-014": ("crossings", 240),
"W-021": ("timing", 320), "W-027": ("verification", 280)}
def snap(disc, **override):
ran = {k: BASE[k] for k in NEEDS[disc]}
ran.update(override)
return ran
def colour(disc, rep, waivers, day):
if rep is None:
return "red" # missing report
if any(rep["ran"].get(k) != BASE[k] for k in NEEDS[disc]):
return "red" # stale revisions
live = [w for w in rep["waivers"] if waivers[w][1] > day]
expired = len(rep["waivers"]) - len(live)
opened = rep["open"] + expired # expired = open again
if opened > 0:
plan = rep.get("plan")
return "amber" if plan is not None and plan <= SIGNOFF_DAY else "red"
return "amber" if live else "green"
reports = {
"timing": {"open": 1, "waivers": ["W-009", "W-021"], "plan": 170, "ran": snap("timing")},
"power": {"open": 0, "waivers": [], "plan": None, "ran": snap("power")},
"physical": {"open": 5, "waivers": [], "plan": 175, "ran": snap("physical")},
"crossings": {"open": 2, "waivers": ["W-014"], "plan": 178, "ran": snap("crossings")},
"verification": {"open": 4, "waivers": ["W-027"], "plan": 175, "ran": snap("verification")},
"connectivity": {"open": 3, "waivers": [], "plan": None, "ran": snap("connectivity")},
"equivalence": {"open": 0, "waivers": [], "plan": None, "ran": snap("equivalence")},
"gate-level-sim": {"open": 0, "waivers": [], "plan": None,
"ran": snap("gate-level-sim", netlist="n87")},
}
col = {d: colour(d, reports[d], WAIVERS, DAY) for d in NEEDS}
assert col == {"timing": "amber", "power": "green", "physical": "amber",
"crossings": "amber", "verification": "amber",
"connectivity": "red", "equivalence": "green",
"gate-level-sim": "red"}, col
# counter-examples: every rule must be able to change a colour
assert colour("power", None, WAIVERS, DAY) == "red" # missing report
quiet = {"open": 0, "waivers": ["W-014"], "plan": None, "ran": snap("crossings")}
assert colour("crossings", quiet, WAIVERS, DAY) == "amber" # live waiver
lapsed = dict(WAIVERS, **{"W-014": ("crossings", 149)})
assert colour("crossings", quiet, lapsed, DAY) == "red" # expired: open again
assert colour("crossings", dict(quiet, plan=190), lapsed, DAY) == "red" # plan too late
reds = sorted(d for d, c in col.items() if c == "red")
assert reds == ["connectivity", "gate-level-sim"], reds
print("PASS: 2 red, 4 amber, 2 green; missing, stale and expired all turn red")The dashboard page carries the baseline tuple and the generation date; anything else is a picture, not a report.
Every red names its owner and its plan; every amber names its dated plan or its waivers.
The roll-up ran after the manifest checker, green, on the same inputs.
When the dashboard surprises a discipline owner, believe the script first: check the report's baseline, then the waiver expiry, then the open count. Nine times in ten the owner read last week's report. The tenth time the report format changed under the script, which is why the script treats a report it cannot match to the baseline as stale, and so red, instead of carrying the old colour forward.
Red. Stale is red: the map grew a row since the report ran, and the reachability of the new logic is unknown. Rerun, then colour.