69 lines
4.0 KiB
Diff
69 lines
4.0 KiB
Diff
diff --git a/documentation/audits/sizing-2026-10-13/tools/build_sizing.py b/documentation/audits/sizing-2026-10-13/tools/build_sizing.py
|
|
index f198bcb4..4e3caf6a 100644
|
|
--- a/documentation/audits/sizing-2026-10-13/tools/build_sizing.py
|
|
+++ b/documentation/audits/sizing-2026-10-13/tools/build_sizing.py
|
|
@@ -10,6 +10,10 @@ Sources, per app, in the spec's order of preference (sizing-2026-10-13 TASK §7
|
|
(evidence/onboarding-peaks.json, collected 2026-10-13; per run, containers summed)
|
|
3 measured — this run's bench on the N100 (evidence/<batch>/summary.json)
|
|
4 unmeasured — the catalog's own mem_request / mem_limit
|
|
+ + hp-check — RAISE ONLY (operator ruling 2026-10-14, R-1009): the second machine's figures
|
|
+ (../sizing-check-2026-10-14/hp-figures.json, HP t740, `used` basis). For each app there,
|
|
+ each figure (typical, peak) becomes the higher of the figure above and the HP figure; nothing
|
|
+ goes down. The record names every raised figure in `raised_by_hp`.
|
|
Rules: telemetry under 7 days counts only when nothing better exists (`short-telemetry`). When two
|
|
sources' peaks differ by more than 50 %, both are reported and the HIGHER is used for mem_peak_mb.
|
|
mem_typical_mb is the chosen source's typical figure. CPU always comes from the N100 bench when it
|
|
@@ -136,8 +140,28 @@ def floor():
|
|
)
|
|
|
|
|
|
+HP = os.path.join(os.path.dirname(AUDIT), "sizing-check-2026-10-14", "hp-figures.json")
|
|
+
|
|
+
|
|
+def hp_check():
|
|
+ return json.load(open(HP))["apps"] if os.path.exists(HP) else {}
|
|
+
|
|
+
|
|
+def raise_only(typ, peak, h):
|
|
+ """The second machine can only RAISE a figure. Returns (typical, peak, raised) — raised = [(field, old, new)]."""
|
|
+ raised = []
|
|
+ if h:
|
|
+ if h.get("typical_mb") is not None and (typ is None or h["typical_mb"] > typ):
|
|
+ raised.append(("typical", typ, h["typical_mb"])); typ = h["typical_mb"]
|
|
+ if h.get("peak_mb") is not None and (peak is None or h["peak_mb"] > peak):
|
|
+ raised.append(("peak", peak, h["peak_mb"])); peak = h["peak_mb"]
|
|
+ if typ is not None and peak is not None and peak < typ:
|
|
+ raised.append(("peak", peak, typ)); peak = typ
|
|
+ return typ, peak, raised
|
|
+
|
|
+
|
|
def main():
|
|
- cat, tel, onb, ben = catalog(), telemetry(), onboarding(), bench()
|
|
+ cat, tel, onb, ben, hpc = catalog(), telemetry(), onboarding(), bench(), hp_check()
|
|
apps, table = [], []
|
|
for slug, c in cat.items():
|
|
t, o, b = tel.get(slug), onb.get(slug), ben.get(slug)
|
|
@@ -162,6 +186,7 @@ def main():
|
|
peak = typ # a peak below the typical figure is two sources' noise, never a real peak
|
|
else:
|
|
src, typ, peak, when, box, disagree = "unmeasured", mb(c["mem_request"]), mb(c["mem_limit"]), None, None, False
|
|
+ typ, peak, raised = raise_only(typ, peak, hpc.get(slug))
|
|
cpu_rest = b["cpu_rest_avg_pct"] if b else (round(t["cpu_avg_dockerpct"] / 4, 2) if t else None)
|
|
cpu_pk = b["cpu_peak_1m_pct"] if b else (round(t["cpu_max_15min"] / 4, 1) if t else None)
|
|
rec = dict(
|
|
@@ -170,11 +195,13 @@ def main():
|
|
cpu_class=cpu_class(cpu_rest, cpu_pk), cpu_note=CPU_NOTES.get(slug, ""),
|
|
source=src, measured_on=box, date=when,
|
|
)
|
|
+ if raised:
|
|
+ rec["raised_by_hp"] = [dict(field=f, was=o, now=n) for f, o, n in raised]
|
|
if c["lifecycle"] != "active":
|
|
rec["lifecycle"] = c["lifecycle"]
|
|
apps.append(rec)
|
|
table.append(dict(rec, catalog_request_mb=mb(c["mem_request"]), catalog_limit_mb=mb(c["mem_limit"]),
|
|
- sources_disagree=disagree, cpu_rest_pct=cpu_rest, cpu_peak_1m_pct=cpu_pk,
|
|
+ sources_disagree=disagree, cpu_rest_pct=cpu_rest, cpu_peak_1m_pct=cpu_pk, hp=hpc.get(slug),
|
|
telemetry=t, onboarding=o, bench=b))
|
|
power = json.load(open(os.path.join(EV, "power.json"))) if os.path.exists(os.path.join(EV, "power.json")) else None
|
|
out = dict(
|