kaldamus entity reference · SummaryReport · BreaksReport
Every make update-all run ends by asking two blunt questions of itself — what's in here, and what fell through the cracks — and answers both in pure Python, with no LLM call, no network, and no memory of the run before this one.
| Entity | Answers | Holds |
|---|---|---|
| SummaryReport | "what exists" | entity_counts · per-category / per-status breakdowns · factor_dedup_ratio · Timeliness block · stale_counts |
| BreaksReport | "what's missing, and why" | each gap split into _expected (a gate explains it) / _unexpected (nothing does) |
now — SummaryReport counts what exists, BreaksReport counts what's missing. Nothing on one row points at the other.id="current", no join_expected carries {id, category, reason}; _unexpected is a bare id list — a real drop no gate explains.
flowchart TD
classDef srcNode fill:#16233b,stroke:#5a8fd4,stroke-width:1.5px,color:#dfe7f5;
classDef reportNode fill:#241d0c,stroke:#c9a84c,stroke-width:1.5px,color:#f3e6bd;
classDef gateNode fill:#12151f,stroke:#5a6178,stroke-width:1px,color:#c9cbd6;
classDef writeNode fill:#161822,stroke:#e0e0e0,stroke-width:2px,color:#f0f0f0;
A["every upstream entity file
read via the canonical repos"]:::srcNode --> N["now = datetime.now(timezone.utc)
one timestamp for the whole run"]:::writeNode
N --> S["_build_summary()
counts, breakdowns, Timeliness"]:::srcNode
N --> B["_build_breaks()
one predicate per gap type"]:::srcNode
B --> G{"gate fires?
priority_score < min_score"}:::gateNode
G -- "yes — a policy explains it" --> EXP["_expected:
{id, category, reason}"]:::reportNode
G -- "no — nothing explains it" --> UNEXP["_unexpected:
bare id"]:::reportNode
S --> W["save_all(...)
id='current', overwrite, no history"]:::writeNode
EXP --> W
UNEXP --> W
W --> O["summary_report.json
breaks_report.json"]:::reportNode
Every run of update_reports.py. Blue = raw entity files coming in; gold = the two report files going out; the gate diamond is the whole design point of BreaksReport.
now threads through every age bucket and staleness check, so the whole report describes one consistent instant.datetime.now() captured onceEXCLUDED_RAW_CATEGORIES imported live--category / --id are accepted for CLI uniformity, then ignored — the reports are gen-config-scoped aggregates with no per-event variant.--id passed → no effectnow, from files this job doesn't own, against gates it doesn't define.(run_id, retain) shape — don't shoehorn a list of singletons.id="current", overwritten| SummaryReport / BreaksReport | EvalReport | |
|---|---|---|
| Shape | singleton — one row, id="current" | composite — one row per (entity_type, run_id) |
| History | none — every run overwrites the one row | append-only, bounded by a retain cap |
| Content | descriptive — counts, breakdowns, gaps | evaluative — check pass rates, judge dims, scores |
| Answers | "what's true right now?" | "is quality better or worse than last run?" |
_expected count is the pipeline working as designed; an _unexpected count is the only number here worth losing sleep over.max_items cap + settled-skip not in the gatemax_items → dropped, not broken