Warning, /swf-monitor/docs/COMP_SNAPSHOT.md is written in an unsupported language. File is not indexed.
0001 # The comp snapshot — the computing centre's live record
0002
0003 The computing centre is a room in the etaverse dome. It lays out the ePIC
0004 computing model for an operator standing at the door: DAQ and its exit
0005 buffer near the door, the two E1s with their Rucio storage, epicprod and
0006 the pressure front in the middle, and the production sites on the rear
0007 arc (Torre Wenaus, 2026-10-21). The room is built and drawn on the
0008 etaverse side. This document describes the one record it reads live: the
0009 comp snapshot, which swf-monitor builds and serves. The room refreshes
0010 everything it shows from that record without a reload: about once a
0011 minute while someone is in the room, every thirty minutes otherwise.
0012
0013 The record is also the feed for the production dashboard on the web, the
0014 one collaborators will use; the room is its proving ground (Torre Wenaus,
0015 2026-10-23: "every feed you send to the floor is a feed you will send to
0016 our prod dash"). Whatever is added for the room is shaped for both
0017 readers: counts, levels, plain-text detail and links, never the room's
0018 geometry.
0019
0020 ## Where it is served
0021
0022 One builder, three faces, the same record:
0023
0024 - MCP: `swf_comp_snapshot()` on the swf-testbed server.
0025 - REST: `/swf-monitor/panda/comp/snapshot.json` on pandaserver02.
0026 - Public: `https://epic-devcloud.org/prod/panda/comp/snapshot.json`,
0027 through swf-remote's `panda/` catch-all (EXTERNAL_ACCESS.md). This is
0028 the face the room reads, from the browser, anonymously. Two swf-remote
0029 settings make that possible: the path is open past its login wall
0030 (`login_wall.py`, `OPEN_PREFIXES`), and its response carries
0031 `Access-Control-Allow-Origin: https://etaverse.com`, since the proxy
0032 relays no upstream header but the content type.
0033
0034 The record is a cached product ([CACHED_PRODUCTS.md](CACHED_PRODUCTS.md)),
0035 key `comp_snapshot:v1`, TTL 60 s. A request is always answered at once
0036 from the stored record. A request that finds it older than the TTL
0037 starts one rebuild behind the answer. The rebuild cadence therefore
0038 follows the room's polling and is never faster than once a minute, and
0039 an empty room costs nothing. `refresh=1` rebuilds before answering.
0040
0041 The builder reads the PanDA and swf databases only: no remote call and
0042 no LLM. Its cost is measured on every build and stored with the record
0043 (`build_seconds`): 15 to 25 seconds on 2026-10-21, most of it the
0044 census and the last hour's ended jobs. Only the first fill makes a
0045 request wait for it.
0046
0047 ## The record (schema 1)
0048
0049 Every number is the value at `observed_at` or over the hour before it.
0050 Every entity carries a stable `id`. The room keys its layout on these
0051 ids, so an id never changes once published. Display names may change.
0052
0053 ```
0054 schema "comp-snapshot/1"
0055 observed_at ISO UTC
0056 build_seconds seconds the build took
0057 units {"capacity": "cores", "core_hours": "core-hours in the last hour"}
0058 pressure_front {ready_tasks, released_1h, enabled, mode, jedi_throttled, link,
0059 detail, cycle_at, items[], queues[]}
0060 sites[] {id, name, status, capacity, capacity_source, in_use,
0061 health, links, queues[], execute_sites[]}
0062 queues[] {id, name, status, status_reason,
0063 running, starting, queued, ungenerated,
0064 harvester_slots_opened_1h, harvester_pilots_submitted_1h,
0065 pilots: {waiting, waiting_schedd, limit, limit_at, running,
0066 per_slot, report, report_age_seconds},
0067 finished_1h, failed_1h, capacity, capacity_source, in_use,
0068 finished_core_h_1h, failed_core_h_1h,
0069 front: {state, reason, feed},
0070 health, links}
0071 execute_sites[] {id, name, short, running, finished_1h, failed_1h,
0072 capacity, capacity_source, in_use,
0073 finished_core_h_1h, failed_core_h_1h, health,
0074 links: {jobs}}
0075 storage[] {id, name, holds, status, counts,
0076 arrived_1h, bytes_1h, events_1h, arrived_by_kind_1h,
0077 failed_1h, pending, pending_parts, pending_at,
0078 latest_arrival_s, flow, by_site[], capacity, rses[],
0079 health, links}
0080 by_site[] {site, arrived_1h, bytes_1h, failed_1h}
0081 capacity {rse, used_bytes, limit_bytes, fraction, as_of}
0082 rses[] {id, name, type, used_bytes, limit_bytes, fraction,
0083 files, as_of}
0084 report {text, items: [{level, text, link}],
0085 assessment: {verdict, level, at, link, campaign,
0086 title, narration}}
0087 live {link, hours, items: [{id, at, level, title, detail, link}],
0088 counts: [{level, count, link}]}
0089 tasks {link, items: [{id, name, at, level, title, counts, detail, sites, queues, link}]}
0090 counts {ungenerated, queued, running, finished, failed}
0091 trends {window_hours, bin_minutes, t[], sampled_at, source_as_of,
0092 gaps[], sites[], link}
0093 sites[] {id, name, running[], queued[], finished[], failed[], detail}
0094 errors[] {part, error}
0095 ```
0096
0097 ### Pressure front
0098
0099 - `ready_tasks`: the PCS tasks with a queued submission. These are the
0100 front's ready backlog (swf-epicprod CONTINUOUS_PRODUCTION.md, the
0101 front's placement).
0102 - `released_1h`: the front's `fed` decisions in the last hour.
0103 - `enabled`, `mode`, `jedi_throttled`: the front's SysConfig switches.
0104 - What the pillar shows on hover and opens (Torre Wenaus, 2026-10-22),
0105 from the state the front's cycle stored (`front_state`, as of
0106 `cycle_at`): `items[]` is the ready buffer task by task, `{task,
0107 queue, order, kind, by_hand, priority, jobs, eligible, problems,
0108 link}`, in each queue's feed order, a task pinned to a closed queue
0109 not eligible and the closure among its problems; `queues[]` is each
0110 production queue's latest decision, `{queue, state, reason,
0111 committed_h, h_low, h_high, running, ready_total, ready_eligible,
0112 last_feed_age_h, closed}`; `detail` is the hover line; `link` opens
0113 the front page at its ready buffer.
0114
0115 ### Sites and queues
0116
0117 `site.fair_share` carries the submit host's latest negotiator reading.
0118 Its `notice` is null when not limited; otherwise it is
0119 `{text, level, detail, link}`: the canonical wording, severity, hover
0120 explanation and live queue page. Dashboard and room consume this notice
0121 without composing their own text. The same formatter adds it when a
0122 stored snapshot is read, so cached measurements cannot retain obsolete
0123 notice wording. A stale or unavailable negotiator record has no notice.
0124
0125 The site groups are the SysConfig key `comp.sites` (id, name, order,
0126 flags), seeded with the layout below, so a site is added or regrouped
0127 without a deploy. Each site's queues, and their status, are the queue
0128 registry's (swf-epicprod docs/QUEUE_REGISTRY.md): a queue belongs to the
0129 site its entry names, in the registry's order, and a retired queue leaves
0130 the room. OSG is
0131 a site of its own, not BNL's: BNL is only the conduit its pilots are
0132 submitted through, and its queues and execute sites belong to OSG.
0133
0134 | Site id | Name | Queues | Notes |
0135 |---|---|---|---|
0136 | `osg` | OSG | BNL_OSG_PanDA_1 | `execute_sites[]` from the jobs' pilot-reported glidein site (PanDA keeps it in 36 characters, so a longer name arrives cut and is restored from the full names `short_names.py` knows: 'Center for Advanced Research Computing', not '...Computi'); BNL_OSG_EPIC_PROD_1 left the floor on 2026-10-22, production having moved off it on 10-21 |
0137 | `grex` | GREX | UM_GREX_PanDA_1 | University of Manitoba |
0138 | `compute-canada` | Compute Canada | ComputeCanada_PanDA_1 | not built: awaiting SFU's identity mapping at the CEs |
0139 | `nersc` | NERSC | NERSC_Perlmutter_epic, NERSC_Perlmutter_epic_es | |
0140 | `google` | Google | BNL_ePIC_GOOGLE, BNL_ePIC_GOOGLE_es | |
0141 | `jlab` | JLab | JLAB_PanDA_1 | not live: waiting for JLab's CE to route our jobs |
0142
0143 A queue's `status` is `live`, `commissioning` (accepting placed trials),
0144 `off` (in PanDA, not taking production), `not_live` (defined, not yet
0145 running work) or `not_built` (the registry's `not_built`, or not in PanDA
0146 yet). A registry status of `production` leaves the reading to PanDA.
0147 `status_reason` says why when the status is not `live`: the registry's
0148 reason.
0149
0150 Per queue, from the PanDA database:
0151
0152 - `running` and `starting` separately. A job in `starting` holds a pilot
0153 slot but runs nothing yet; the room's cylinders use `running`.
0154 - `queued`: activated, assigned, defined, waiting and sent jobs, the
0155 census's not-started set.
0156 - `ungenerated`: input rows JEDI has not yet made into jobs.
0157 - `harvester_slots_opened_1h`: harvester workers that started in the
0158 last hour, each a slot opened at the site.
0159 - `harvester_pilots_submitted_1h`: harvester workers submitted in the
0160 last hour, into the site's batch system or the OSG pool, where they
0161 wait for a slot. (Until 2026-10-21 16:30 ET `harvester_slots_opened_1h`
0162 carried this count.)
0163 - `pilots`: the queue's pilot slots by harvester's own count, from the
0164 harvester reporter's latest record (HARVESTER_REPORTER.md); `null` for
0165 a queue no harvester reports. `waiting` is the slots submitted and not
0166 yet started (an evicted pilot back in the batch queue included),
0167 `running` the slots running, `per_slot` the pilots in one slot (8 at
0168 GREX, 1 elsewhere). `waiting_current` is the canonical display count:
0169 the schedd's count when reported, otherwise Harvester's. `waiting_source`
0170 identifies that choice. The dashboard and room consume this resolved
0171 count; `waiting` and `waiting_schedd` retain the raw readings for diagnosis.
0172 `limit` is the waiting limit harvester last
0173 applied, from its worker-adjuster log, and `limit_at` when it logged
0174 it: harvester computes the limit from its running slots under the
0175 queue's ratio, floor and cap, and the configured `nQueueLimitWorker`
0176 is only the cap (on 2026-10-22 OSG applied 200 under a cap of 300,
0177 GREX 610 under 625, JLab 10 under 50). `limit` is `null` until the
0178 reporter has seen the adjuster log it. Harvester submits new slots
0179 only while `waiting` is below its limit, so `waiting` is what the site
0180 has not yet started: at GREX
0181 on 2026-10-21, 592 slots waited while GREX ran 118 and started 3 in an
0182 hour. For the OSG queues `waiting_schedd` is the idle pilots the
0183 submit schedd actually holds, from the OSG submit reporter
0184 (OSG_SUBMIT_REPORTER.md). The two disagree when pilots leave the
0185 schedd without harvester's knowledge: on 2026-10-21 harvester counted
0186 4,311 waiting at BNL_OSG_PanDA_1 against 131 in the schedd, after
0187 waiting pilots were removed there directly, and submitted none.
0188 `report_age_seconds` is the harvester record's age; the reporters run
0189 every five minutes.
0190 - `finished_1h`, `failed_1h`: production jobs that ended in the last
0191 hour.
0192 - `front`: the front's latest decision for the queue.
0193
0194 ### Capacity
0195
0196 The unit is the core. Every production job today uses one core, so jobs
0197 and cores agree. A multicore job later counts its cores.
0198
0199 - `capacity`: the cores available to us, with `capacity_source` naming
0200 where the figure comes from:
0201 - `pool`: the OSG pool's slots that our pilots' requirements admit,
0202 from the submit host's report (SNAPPER_PLATFORM.md). The pool is
0203 one behind both OSG queues, so the OSG site carries it as its
0204 capacity and each OSG queue repeats it as `pool, shared`;
0205 - `allocation`: a batch allocation's cores (Perlmutter);
0206 - `configured`: the SysConfig key `comp.capacity.<queue>`, an
0207 operator's figure, which overrides the others;
0208 - `observed peak`: the most jobs seen running in the census's
0209 calibration window. This is the site's discovered limit where our
0210 supply is open-ended, as at GREX: harvester keeps 125 to 625 of our
0211 8-pilot slots waiting there and GREX's scheduler starts about 120 to
0212 128 at a time (2026-10-21), so the peak is GREX's limit, not ours.
0213 The pilot controller's running target (SysConfig
0214 `pilot.queue.<queue>.target_running`, GREX 1,000) is our figure, not
0215 a capacity, and is not used.
0216 - `in_use`: running cores now.
0217 - `finished_core_h_1h`, `failed_core_h_1h`: the core-hours spent in the
0218 last hour by jobs that finished and by jobs that failed. A running
0219 job's outcome is not known until it ends, so the room splits the used
0220 part of a pillar green and red by this ratio.
0221
0222 An execute site's capacity is `null` until the submit host reports the
0223 pool's admitted slots per site. A queue that is not live has no
0224 capacity, and its health is a single grey `status` part. A site's
0225 capacity is its pool, or the sum of its queues' capacities.
0226
0227 ### Health
0228
0229 Every site, queue, execute site and storage element carries
0230 `health: {level, parts}`. `level` is `green`, `amber`, `red`, or `grey`
0231 when there is no evidence either way (an idle queue, a canary with too
0232 few jobs). It is the worst of its parts. Each part is
0233 `{level, value, note}`.
0234
0235 A queue's parts:
0236
0237 - `prod_activity`, from the last hour's ended jobs: `grey` with none;
0238 `red` with no finished job and ten or more failed; `amber` when failed
0239 jobs are more than a quarter of those that ended; otherwise `green`.
0240 - `canary`, the queue's canary verdict as the front reads it: `healthy`
0241 is green, `failing` red, `insufficient` and `unknown` grey.
0242 - `snapper_errors`: the last hour's failures by Snapper error category
0243 (SNAPPER_ERRORS.md): component x code, the job's first nonzero error
0244 component over all seven, labelled from the code catalogs
0245 (`panda/error_labels.category_label`) and read through the
0246 error-correction root (ERROR_ATTRIBUTION.md), so a label a rule marks
0247 unreliable shows its corrected reading. The note names the top category
0248 with its count; no failure reads "unattributed" (23 October 2026: the
0249 OSG failures were DDM 200, the log-name collision of 41039 and 41040).
0250 The part is `red` when one category accounts for more than half the
0251 ended jobs, the signature of an outage, and `amber` when the failures
0252 are more than a quarter of them.
0253 - `pilot_supply`, whether pilots keep reaching the queue, from the
0254 queue's `pilots` reading. Harvester submits only while its own count
0255 of waiting pilots is below its limit, and that count changes only
0256 when its monitor rechecks a pilot, so a count the schedd no longer
0257 bears out stops supply while the queue reads full. With jobs queued
0258 the part is `red` (`amber` with none queued) when:
0259 - harvester counts at least twice its limit while the schedd holds
0260 fewer than the limit: pilots left the schedd without harvester's
0261 knowledge (2026-10-21, 4,311 counted against 131 held);
0262 - the pilots the pool can start, those the schedd holds idle plus
0263 those harvester will still submit before its count reaches its
0264 limit, are fewer than half the limit: harvester has not yet seen
0265 its waiting pilots start. On 2026-10-21, with harvester's recheck at
0266 30 minutes, it counted 196 against a limit of 200 while the schedd
0267 held 39, so the pool could start 43, and OSG's running fell from
0268 1,137 to 433 in five hours; four minutes after the recheck went to
0269 five minutes the schedd held 163 of 200.
0270
0271 It is `red` also when jobs are queued and in the last hour no pilot
0272 waited, was submitted or started, unless the queue's running slots fill
0273 the operator's worker limit (`pilot.queue.<queue>.worker_limit`) or
0274 harvester's own `maxWorkers` (Perlmutter's node ceiling): a full queue
0275 is due no pilot, so the part is `green` and an operator's limit is its
0276 own Report line (Torre Wenaus, 2026-10-28, when GREX, full at its
0277 300-core limit, read red here). The two schedd rules need the OSG
0278 submit reporter's count and apply to the OSG queues only. `grey` when
0279 the report is more than fifteen minutes old or the limit harvester
0280 applies is not yet reported; otherwise `green`, with the counts in the
0281 note. A limit is fixed when the queue sets no ratio or a ratio of zero:
0282 harvester then applies `nQueueLimitWorker` as it stands. The job-demand
0283 cache age is not checked for the Perlmutter record, which cannot carry
0284 it (HARVESTER_REPORTER.md, Perlmutter).
0285
0286 A queue no harvester report names reads PanDA's own worker table
0287 instead (`harvester_workers`, the workers running or submitted now).
0288 `green` with a worker running or submitted; otherwise `amber` with jobs
0289 queued, `grey` without.
0290
0291 A queue the ops agent supplies with pilots instead of harvester
0292 (swf-epicprod `queues.AGENT_SUPPLIED`: BNL_ePIC_GOOGLE_es) reads its
0293 part from the GKE controller's worker observation, the same reading as
0294 its `gke_workers` part: `red` when the controller's latest worker
0295 failed, `amber` when no fresh observation exists, otherwise `green`
0296 with its waiting and running pilots.
0297
0298 A site's health is the worst of its queues'. An execute site's health
0299 has the `prod_activity` part only.
0300
0301 `site.level` is the site's bullet: the worst of its health, its status
0302 level and the levels of its report items (Report, below), so a site held
0303 for failures is never green (Torre Wenaus, 2026-10-28: GREX read green
0304 with its feed off for failures and its only task paused). Grey items do
0305 not raise it. A site that is not live keeps its status level.
0306
0307 ### Storage
0308
0309 The E1s' Rucio storage, reported as the queues are: what arrived in the
0310 last hour, what did not, what is still owed, and the capacity.
0311
0312 | id | name | holds | counts |
0313 |---|---|---|---|
0314 | `jlab-rucio` | JLab Rucio | science data | files |
0315 | `bnl-rucio` | BNL Rucio | logs | logs |
0316
0317 `counts` names the unit of the counts. Production tasks register their
0318 science outputs in JLab Rucio themselves, so PanDA's file table holds
0319 none of them; the only file PanDA stages for a production job is the
0320 pilot's log tarball, registered in BNL Rucio
0321 (swf-epicprod LOG_STAGEOUT_FALLBACK.md).
0322
0323 For `jlab-rucio`, from the payload reports of the last hour's finished
0324 production jobs (the PanDA metatable, swf-epicprod
0325 EPICPROD_PAYLOAD.md):
0326
0327 - `arrived_1h`: the files the jobs registered, each DID the report's
0328 registration lists. A clash registered under a derived name (outcome
0329 `diverted`, swf-epicprod RUCIO_RESILIENCE.md, Measure 3) is a
0330 registered file.
0331 - `bytes_1h`, `events_1h`: the bytes and events of those files, from
0332 the report's outputs joined to the DIDs by file name. A file
0333 registered under a derived name matches no output and adds no bytes.
0334 - `arrived_by_kind_1h`: the files by output kind (`reco`, `full`, an
0335 internal EVGEN task's own kind), `other` for a derived name.
0336 - `failed_1h`: jobs whose registration did not complete (`pending` or
0337 `unfinished`); the registrar completes a pending registration later.
0338 - `pending`: the files owed the catalog now, the sum of
0339 `pending_parts`: `stash`, the failover stash's entries not yet home
0340 (the drain's record, cached product `stash_state`,
0341 RUCIO_FAILOVER_STASH.md), and `registrar`, the registrations the
0342 registrar's last pass deferred (its action record). The drain runs
0343 every 30 minutes and the registrar hourly; `pending_at` is the older
0344 of the two passes.
0345 - `capacity`: the production output RSE, BNL-XRD, which every
0346 production configuration names as its output RSE; `rses[]`: every
0347 JLab RSE. Both are from the latest storage component
0348 (swf-epicprod STORAGE.md, per RSE capacity), refreshed every four
0349 hours: the production account's usage, its limit and the fraction,
0350 with the usage record's time. On 2026-10-22 BNL-XRD held 582.6 TB
0351 against a limit of 750 TB.
0352
0353 For `bnl-rucio`, from the PanDA job and file tables over the jobs that
0354 ended in the last hour:
0355
0356 - `arrived_1h`, `bytes_1h`: the logs registered and their bytes. A
0357 failed job's log is registered too: PanDA marks every file of a failed
0358 job failed, but the log is at BNL_PROD_DISK_1 (checked on
0359 2026-10-22). Only a job failed at log stage-out, or one whose pilot
0360 held its log in the stage-out bucket (`logHeld`), has no log there.
0361 - `failed_1h`: jobs failed at log stage-out.
0362 - `pending`: logs held in the stage-out bucket and not yet moved into
0363 BNL Rucio, from the hourly log-rescue pass's record:
0364 `pending_parts.held` over its window less `pending_parts.moved`.
0365 - `capacity` is `null` and `rses[]` empty: no usage record covers
0366 BNL_PROD_DISK_1.
0367
0368 For `jlab-rucio`, `flow` is the output flow on the trends axis
0369 (`trends.t`, the same whole quarter-hour bins): `files` and `bytes`, the
0370 files the finished production jobs ending in each bin registered and
0371 their bytes, and `registration_incomplete_jobs`, those jobs whose
0372 registration did not complete, all from the same payload-report reading
0373 as `arrived_1h`. These are registrations as the payload reports them,
0374 grouped by the job's end, not measured transfer bandwidth or the files'
0375 availability times; volume per hour is the bin's bytes times four. A
0376 bin's jobs are final once archived, so the bins are kept (cached product
0377 `jlab_flow:v1`) and each build reads again only the last two bins before
0378 the newest kept one, and each build reads an hour of the window's bins
0379 not yet kept, so the twelve hours fill within twelve builds (a single
0380 read of the whole window takes minutes); a bin not yet read is null, and
0381 `flow` is null when the reading fails or the trends axis is absent.
0382
0383 For both, `latest_arrival_s` is the seconds since the newest
0384 registration, and `by_site[]` splits `arrived_1h`, `bytes_1h` and
0385 `failed_1h` by the producing site (a `sites[]` id). Each reading is a
0386 part of its own: one that cannot be read is listed in `errors[]` and its
0387 fields are `null`.
0388
0389 Health parts for `jlab-rucio`:
0390
0391 - `registration`: the share of the last hour's finished jobs whose
0392 registration did not complete; `amber` over 5%, `red` over half.
0393 - `latest_arrival`: the age of the newest registration; `amber` over 30
0394 minutes, `red` over two hours or with none in two days.
0395
0396 Health parts for `bnl-rucio`:
0397
0398 - `log_stageout`: jobs that ended in the last hour with a log stage-out
0399 error; `amber` from 5, `red` from 50.
0400
0401 The storage-door record's state joins both once the door check leaves
0402 shadow mode.
0403
0404 ### Report and errors
0405
0406 Queue labels use the shared short-name vocabulary; BNL_OSG_PanDA_1 reads
0407 OSG. Queue identifiers and links retain their canonical names.
0408
0409 - `report.text`: a summary composed from the record on every build,
0410 without an LLM: the front, each live site's running and last-hour
0411 outcomes, and every non-green health part.
0412 - `report.items`: what the room's floor cannot show, one line each as
0413 `{n, key, level, text, link, site, since}`, newest first, the biggest
0414 number at the top (Torre Wenaus, 2026-10-28: "reverse time order, which
0415 means I should see biggest numbers at top"); `since` is when the line
0416 first stood. The level is
0417 carried by the colour, with no per-site counts (the pillars carry
0418 those). `n` is the
0419 line's standing number (Torre Wenaus, 2026-10-28: "prod now numbering
0420 should be immutable"): `key` names what the line is about (a queue's
0421 feed, a paused task, an alarm's title...), a line keeps its number while
0422 it stands, a new line takes the next number of a counter that only rises
0423 (PersistentState `next_prod_now_line`), so no number is ever given to a
0424 second line and numbers rise with time, and a cleared
0425 line's number stays held for an hour, so a line that returns keeps it
0426 and no other line takes it meanwhile (CachedProduct
0427 `prod_now_numbers`). `site` is the id of the site a line belongs to,
0428 or absent; the line names the site by its display name (the shared
0429 short-name vocabulary; a queue name only where the site has more than
0430 one live queue), and `site.notices` lists that site's lines,
0431 `{n, level, text, link}`, for its panel (Torre Wenaus, 2026-10-28:
0432 every exceptional condition of a site is a numbered line, and the
0433 panel cites the numbers). Every state a site is in is a line with who,
0434 when and why, read from the current settings when the record is read:
0435 - its front feed **off**, red, with the recorded reason, who and when
0436 (`front.queue.<queue>.feed_off_reason`, `.feed_set_by`,
0437 `.feed_set_at`); a feed off with no recorded reason is a red line
0438 saying so;
0439 - its front feed **exempt** (its own feeder supplies it), grey, with
0440 the recorded reason;
0441 - a production task **paused** at one of its queues, red, with who
0442 paused it, when and why (`paused`, below);
0443 - an operator **core limit**, red, with the control's reason, who and
0444 when (`pilot.queue.<queue>.worker_limit`);
0445 - a whole-node queue holding more **nodes** than its ceiling, red: its
0446 workers running and waiting in PanDA's worker table (the queue's
0447 `workers_now`) against SysConfig `comp.node_ceilings` (Perlmutter's
0448 Event Service queue at five; Torre Wenaus, 2026-10-28: "5 IS OUR MAX"),
0449 whose enforcement is the Harvester worker limit;
0450 - the pool's **fair-share** limit, grey, informational: OSG's normal
0451 mode of operation, which never colours the site (Torre Wenaus,
0452 2026-10-28), with the pool and the negotiation cycle's time
0453 (`site.fair_share.notice`).
0454
0455 Then why the front feeds nothing (the global front is off, each live
0456 queue's front decision in the words of CONTINUOUS_PRODUCTION.md's
0457 states and reasons, a feed switch apart), every amber or red health
0458 part with its note,
0459 every active alarm event (red) and approaching deadline ping (amber),
0460 storage parts not green, and late or missing scheduled campaign
0461 assessments (the System
0462 page's campaign-assessments row; the verdicts are held by corun-ai,
0463 which this build does not call). The text before the first ": " names
0464 what the line is about.
0465 Routine off and commissioning states remain on the site boards. A global
0466 empty-ready-buffer summary and healthy assessment acknowledgements are omitted.
0467 A live queue below its target work depth with no eligible ready task is
0468 amber: the front would release suitable work if it were available.
0469 The alarm engine selects approaching pings using each ping's configured
0470 lead time. Their report text shows the due date without the recorded
0471 title's stale countdown. Overdue pings escalate to red alarm severity.
0472 - `report.assessment`: the newest daily campaign assessment, from its
0473 `assessment_register` action record (swf-epicprod
0474 EPICPROD_ASSESSMENTS.md): the verdict, the verdict as a health level
0475 (`ok` green, `attention` amber, `alarm` red, anything else grey), the
0476 registration time, the assessment's page, the campaign, the report
0477 title and the narration; `null` when none is registered.
0478 - `errors[]`: a part that could not be read is listed here and left out
0479 of the record, never shown as zero.
0480
0481 ### Live
0482
0483 The room's epicprod-live screen (Torre Wenaus, 2026-10-22). The floor is
0484 the control room: it shows what is live now, and `live.link` opens the
0485 last day curated (`logs/epicprod-live/`, ACTION_STREAM.md, Curated view;
0486 Torre Wenaus, 2026-10-28), which links on to the logs page's live view,
0487 `logs/?app_name=epicprod&live=1`, the complete history, whose filters
0488 count the live rows it lists, not every record of the app, offering the
0489 busiest 15 users and instances, and whose table fits the page, never
0490 scrolling sideways. The items are records of the epicprod
0491 live stream (`live_stream_q`, ACTION_STREAM.md) at level WARNING, ERROR
0492 or CRITICAL from the last 12 hours, newest first, every one the rules
0493 below keep (the dashboard's panel grows downward; Torre Wenaus,
0494 2026-10-29), each with
0495 its time, level, title, detail and page (`logs/<id>/`). A task Move is
0496 normal operation, recorded at INFO while JEDI carries it out and when it
0497 completes, and stays on the screen at INFO for three hours (SysConfig
0498 `comp.live.move_hours`; Torre Wenaus, 2026-10-29); a Move that fails is a
0499 failure like any other. A task the front released from the ready buffer
0500 to a queue (its `front_decision` record with outcome `fed`) is shown the
0501 same way, one line per task (`Move ready buffer to Perlmutter · p4499.e106`),
0502 with why the queue took it. The records ride
0503 in the snapshot because the room reads it anonymously and the logs page
0504 is behind the login wall; they name tasks, queues, nodes and errors and
0505 carry no credential.
0506
0507 The screen shows the title and gives the detail on hover. The title says
0508 what happened and where in a few words, names in their short form
0509 (`monitor_app/short_names.py`, the one filter for concise settings): for
0510 a node guard decision the execute site and the node's number on that
0511 site's blacklist, in exclusion order (`Fir node guard 6`,
0512 `node_guard.exclusion_ranks`), so nodes at one site read apart; the task
0513 for a task operation (`Move · task 40857`), else the site, storage
0514 element, queue or configuration the record names. The detail is the
0515 informative message, concise. For a node guard decision it is the
0516 decision record's own message: the guard, its queue, the node, the
0517 reason and the evidence:
0518
0519 Fir node guard 6 on BNL_OSG_PanDA_1: fc20513. Kills jobs at a fixed
0520 run time, ~109 min (memory or slot limit): 12/12 failed in 4 h;
0521 tasks 40958, 40970 run fine elsewhere.
0522
0523 For a task operation it is the task and the operation's reading;
0524 otherwise the record's reason led by its subject. Both come from
0525 `live_notices.board_text`. No title is generic (Torre Wenaus,
0526 2026-10-29): a record that carries its own `title` is shown under it; a
0527 failure says how it failed (`System status refresh timed out`,
0528 `Log rescue failed · BNL-XRD`); a task, RSE or queue subject is named
0529 (`task 41470`); a finding (`watch_finding`, `production_finding`) with no
0530 title of its own is titled by its first sentence, which states what was
0531 found, and its detail is the rest of its text; any other title that would be
0532 its label alone is completed by the record's first sentence, led by its
0533 verdict where it carries one. The Capcom notices take the same titles
0534 (NOTICE_ROUTING.md). A Move's title names where from and where to
0535 (`Move GREX to OSG · task 41474`); its detail is the task, its route, who
0536 asked and why, from its operation record as the curated view reads it
0537 (`live_curated.task_operation_who_why`):
0538
0539 group.EIC...p4496.e106.s11.r11: GREX to OSG, by front: OSG idle;
0540 9,987 unstarted jobs waiting at GREX
0541
0542 A record leaves the floor when it is no longer news:
0543
0544 - a node guard decision is shown only for a node new to the blacklist
0545 (it was clear); a re-trip from half open is a node the floor knows;
0546 - one record per subject, the newest (an action on its subject, or a
0547 pass with no subject from its source), and a record leaves when a
0548 later record on its subject reports another outcome, such as a node
0549 the guard has moved to half open;
0550 - a failure (outcome error, timeout, partial or unrecorded) leaves once
0551 it has recovered: a later record of the same action from the same
0552 source on the same subject reports ok, the identity the epicprod-live
0553 channel uses for its recovery notices (`live_notices.failure_key`);
0554 - any record leaves when the operator's question about it has been
0555 answered: a `live_cleared` record in the action stream names the
0556 cleared record ids and the reason. The `epicprod_live_clear` MCP tool
0557 writes one; out of process, `scripts/live-clear.py <id> ... --reason
0558 "..."` writes one through the log REST endpoint.
0559
0560 None of these changes the records on the logs page.
0561
0562 `counts` are the live stream's records of the window (`hours`, 12) at
0563 INFO, WARNING and ERROR, in that order, zero included, each with its
0564 `link`, the logs page's live view narrowed to that level and window
0565 (`levelname=<level>&hours=12`), which lists exactly the records counted
0566 (Torre Wenaus, 2026-10-28).
0567
0568 ### Tasks
0569
0570 The room's task board, beside the live screen (Torre Wenaus,
0571 2026-10-22): exactly the production tasks in flight on the floor, those
0572 not finished in JEDI (done, finished, failed, broken, aborted) that have
0573 jobs running, starting or queued (the census's states) at a queue of
0574 the room shows, or rows JEDI has not yet made into jobs for such a queue.
0575 A task with neither is off the board. Newest first by `at`, the task's
0576 start (its creation before it starts), ISO UTC. `id` is the JEDI task id,
0577 `name` is the task's composed PanDA name, read from the same query;
0578 `link` the task's page; `tasks.link` lists the production tasks.
0579
0580 The board is the tasks in flight. A line is the task id (`title`) and
0581 its counts, just the numbers: jobs still to generate (`ungenerated`,
0582 the board's "generate": the task's input rows JEDI has not yet made into
0583 jobs, the census's measure, `census.ungenerated_by_task`; a row is one
0584 job under the production tasks' one-row-per-job manifest, one event
0585 range per job), jobs queued
0586 and running, files finished and files failed after their retries (a job
0587 that failed and then succeeded on a retry is not a failure of the task),
0588 finished shown green and failed red:
0589
0590 40856 30,631 2,133 747 14,250 2,244
0591
0592 The detail, on hover, is the task's physics in the concise form of the
0593 PCS description (`physics_description`, the one composer PCS pages use)
0594 and the site's short name, then the composed name, status, queue and
0595 start, and files done of the task's files and lost, with the alarm when
0596 the task is in one:
0597
0598 DIS, eAu 9x100, Q2 10 to 100, BeAGLE at GREX.
0599 group.EIC.26.07.3.epic_craterlake.p2428.e53.s11.r11, running on
0600 UM_GREX_PanDA_1 since 10-17 23:39 ET; 13,772 of 50,006 files done,
0601 2,184 lost after retries (13.7%), in alarm.
0602
0603 `level` is red for a task in a failure-rate alarm, amber for one that
0604 has lost files, green while it runs, grey while its jobs only wait.
0605
0606 The board holds every production task in flight wherever it is placed
0607 (Torre Wenaus, 2026-10-22, when the front placed two tasks on
0608 BNL_OSG_EPIC_PROD_1 after it had left the floor), by the same rules as
0609 any other; its detail names its queue, and its `sites` hold no id for a
0610 queue no floor site holds.
0611
0612 `queues` are the floor's queues the task is active at: those holding its
0613 running, starting or queued jobs, and the queue of its rows still to
0614 generate. `sites` are those queues' site ids, the ids of `sites[].id`.
0615 Both are sorted lists, one entry for a task at one site. Each site disc
0616 writes the ids of the tasks whose `sites` hold it (Torre Wenaus,
0617 2026-10-22: "Tasks: n1 n2 n3", nothing written when there are none).
0618
0619 ### Paused
0620
0621 `paused` is the epicprod disc's paused pillar (Torre Wenaus,
0622 2026-10-23): every production task (`processingtype` `epicproduction`)
0623 whose PanDA status is `paused`, wherever it is placed, a retired queue
0624 included, except a task ended quietly (swf-epicprod EPICPROD_OPS.md, Quiet end).
0625
0626 - `tasks`: the count; `link`: the task list narrowed to paused
0627 production tasks, its window reaching back to the oldest pause;
0628 `detail`: one line naming each task, its site and since when.
0629 - `items`, oldest pause first, each with `id`, `name`, `queue`, `since`
0630 (ISO, the task's last state change, which for a paused task is its
0631 pause), `link` (the task's page) and `detail`: the site and queue,
0632 since when, and the input files done and lost.
0633
0634 PanDA records no reason for a pause, and its "pause by Torre Wenaus" is
0635 the operations agent's credential, not the actor. A pause made through
0636 our tools has its operation record (`PandaTaskOperation`, operation
0637 `pause`), and every pause through our tools carries a reason (swf-epicprod
0638 EPICPROD_OPS.md): each item carries `paused_by` (the person, or `front
0639 task guard` for the front's guard) and `pause_reason` (the guard's trip
0640 from its evidence, or the recorded reason; null only for a pause made
0641 before 2026-10-28 without one). A paused task with no operation record
0642 was paused outside our tools, directly in PanDA: `paused_by` reads
0643 `outside our tools`.
0644
0645 ### Completed
0646
0647 `completed` lists the production tasks completed in the last 24 hours,
0648 for the dashboard's panel under the paused tasks (Torre Wenaus,
0649 2026-10-24): every `epicproduction` task whose PanDA status is `done`
0650 (every input file finished) or `finished` (some lost), trials included,
0651 by its end time, except a task ended quietly (swf-epicprod EPICPROD_OPS.md,
0652 Quiet end).
0653
0654 - `tasks`: the count; `window_hours`: 24; `link`: the day's production
0655 task list; `detail`: the count in words.
0656 - `items`, newest first, each with `id`, `name`, `queue`, `status`,
0657 `at` (ISO, the task's end time), `physics`, `link` (the task's page)
0658 and `detail`: the status, site and queue, when, the input files done
0659 and lost, and the physics. `physics` reads the task's tags as physics:
0660 PCS's one-line summary of its physics configuration
0661 (`pcs.physics_config.summary`: process, beams, Q², generator, sample,
0662 background, requesters), found through the task's PCS link or the
0663 composed identity its name carries; empty for a task PCS does not know.
0664
0665 ### Arrivals
0666
0667 `arrivals` is the science reaching JLab over the last 24 hours (the completed tasks' window) by physics
0668 configuration, for the dashboard's panel under the completed tasks
0669 (Torre Wenaus, 2026-10-24): the RECO files the finished production jobs
0670 registered and their events, from each job's payload report (the record the
0671 JLab Rucio pillar reads), grouped by task and the task's PC (`_task_pcs`, as
0672 for `completed`).
0673
0674 - `pcs`, `files`, `events`, `window_hours` (24), `link` (the campaign view)
0675 and `detail` (the totals in words).
0676 - `items`, newest arrival first, each with `pc`, `physics` (PCS's one-line
0677 summary), `label` (the physics in a row's width: the summary without its
0678 generator and requester tail, units or repeated nucleus), `state`
0679 (`finished` when every task delivering to it in the window has ended or
0680 the plan's target is met, past it included, else `running`), `files`, `events`, `tasks`, `sites`, `first_at` and `last_at`
0681 (ISO, the first and last registering job's end), `delivered_events` and
0682 `target_events` (the plan's, read from the stored completion record
0683 `prod_hub_campaign_completion` without building it), `link` (the PC's
0684 page) and `detail`: the physics, the 24-hour files and events with their
0685 times, tasks and sites, and the plan's delivered against target.
0686
0687 ### Trends
0688
0689 The floor's trend plots (Torre Wenaus, 2026-10-22): utilization in the
0690 moment over the last 12 hours, per site with a live queue, on one shared
0691 axis. `t` is the ends of 48 whole quarter-hour bins in ISO UTC, the last
0692 ending on the quarter hour at or before the series' newest sample
0693 (`sampled_at`); `source_as_of` is when the PanDA activity the snaps
0694 record was last read. For each site, summed over its live queues:
0695 `running` and `queued` are the jobs running and the jobs not yet started
0696 (the census's states: defined, waiting, assigned, activated, sent) at
0697 each bin end; `finished` and `failed` are the jobs that ended in the bin.
0698 `detail` is the site's hover line: running and queued at the last bin
0699 end, finished and failed in the hour before it.
0700
0701 The source is the Snapper Site view's series product
0702 (`snapper_ai.products.series_product`, focus `site`), one product for
0703 the floor's live queues; `link` opens that view. Every sample of a
0704 queue's PanDA state carries the queue's finished counter, so the
0705 counter's points are the queue's sample times, and a value at a bin end
0706 is read at the queue's newest sample at or before it. The series records
0707 every plotted job state at every sample, zero for a state that holds no
0708 jobs (`snapper_providers._plotted_job_states`; the PanDA state lists only
0709 the states that hold jobs). The finished and failed counters count up,
0710 so a bin's ended jobs are the difference of the count at its two ends.
0711 A value is null, never carried forward, when the newest sample before
0712 its bin end is more than 15 minutes older (the PanDA reading refreshes
0713 every five) or the bin end lies in a gap of collection. The counters
0714 being cumulative, a gap inside a bin loses none of its ended jobs; they
0715 are null only where the count at either end of the bin is. Limits: the
0716 state is sampled when the PanDA reading refreshes, every five minutes,
0717 so a state is the one at the newest refresh before the bin end, not at
0718 the bin end itself; and the series rebases the finished and failed
0719 counters by summing their nonnegative increments, so a raw counter
0720 reset reads as a bin with no ended jobs rather than as unknown. The gaps come from Snapper's own
0721 coverage record (the gaps recovering snaps closed and the capture
0722 cursor's open gap), listed in `gaps`. A queue with no sample is null
0723 throughout.
0724
0725 The live right end (Torre Wenaus, 2026-10-28, after GREX showed 265 cores
0726 over a plot ending at 8, its last point the 06:30 quarter-hour at 06:42):
0727 `live_t` is the time of the panel's live figures (the processing
0728 reading's `processing_observed_at`), and each site's `live` carries them,
0729 `cores` (its `processing_threads`) and `queued_cores` (its queues'
0730 `queued_cores`), added when the record is read. The dashboard ends the
0731 cores and queued curves there, after the last whole bin; the ended-job
0732 curves stay on whole bins.
0733
0734 ## Links
0735
0736 Every queue links to its ePIC queue page (`panda/epic-queues/<queue>/`),
0737 its errors view filtered to the queue (`panda/errors/?site=<queue>`) and
0738 the canary probes page (`canary/probes/`: the canary root answers with a
0739 redirect, which the proxy cannot relay). The pillars' drilldowns: a
0740 queue's `links.running` opens its running jobs
0741 (`panda/jobs/?site=<queue>&status=running`), `links.queued` its queued
0742 jobs (`status=queued`, the census's not-started set, what `queued`
0743 counts), `links.slots` the Workers card of its queue page
0744 (`#workers`); an execute site's `links.jobs` opens the jobs whose pilot
0745 reported that site (`panda/jobs/?execsite=<site>`). A site's links are
0746 those of its busiest live queue, for OSG the queue production runs on.
0747 The pressure front links to the
0748 front page (`panda/front/`) and every storage element to the storage
0749 doors page (`panda/storage-doors/`). A storage element's pillars open:
0750 for `jlab-rucio`, `links.arrived` the Storage view
0751 (`snapper/epicprod/storage/`) and `links.pending` the stash page
0752 (`pcs/stash/`), with `links.failed` `null`, since no page lists pending
0753 registrations; for `bnl-rucio`, `links.arrived` the finished jobs
0754 (`panda/jobs/?status=finished&days=1`) and `links.failed` the pilot
0755 errors (`panda/errors/?error_source=pilot&days=1`), with
0756 `links.pending` `null`, since no page lists held logs. The daily
0757 assessment links to its own page (`ai/assessments/<campaign>/daily/<date>/`).
0758 All links are on the public face (`https://epic-devcloud.org/prod/...`),
0759 and each was checked to answer 200 there on 2026-10-21, the storage
0760 and assessment links on 2026-10-22.
0761
0762 ## Shared board presentation
0763
0764 `report.header` contains the Computing now, Work available and Campaign
0765 blocks for both displays. Each block has `id`, `title`, optional `subtitle`,
0766 `metrics` (`value`, `label`, `colour`, `link`, `detail`), optional `footer`
0767 (`text`, `link`, `detail`), `link` and `detail`. Display strings and CSS hex
0768 colours are composed by the feed.
0769
0770 Sites carry `status_label`, `status_level` and `status_reason`. Commissioning
0771 is labelled `COMMISSIONING` in blue; Perlmutter off is `OFF` in amber. Live
0772 sites have no redundant status label and use their health colour, except
0773 a standing note (`LIVE_SITE_LABELS`): live Perlmutter is `Single node`. The internal
0774 `not_built` state is displayed as `OFF`. These display fields apply to cached
0775 snapshots immediately and do not alter queue admission or worker controls.
0776 Each queue also carries
0777 `production_display`: true for live queues and the enabled, bounded Google
0778 commissioning queue, false for inactive commissioning queues such as JLab.
0779 Google uses the same production pillars, metrics and trend presentation as
0780 GREX. The standard Google queue remains off. Controller and runtime
0781 diagnostics remain in the controller record and operator views.
0782
0783 `site.production_panel` is true for each standard site group, including
0784 inactive Canada, Perlmutter and JLab. It selects the shared panel geometry
0785 and reported counts independently of operational activity. Every site has
0786 a trend row on the shared axis; missing samples are null. Queue activity
0787 flags, admission and pilot controls are unchanged by panel availability.
0788
0789 GKE worker evidence comes from `gke_pilot_runtime`, published by the
0790 credentialed controller. `pilots.waiting_current` and `waiting_source`
0791 identify its pending workers (`gke-pilots`). A missing or stale observation
0792 remains unknown. Trend rows include displayed commissioning queues; bins
0793 without samples remain null.
0794
0795 ## Regulation telemetry, 22 October 2026
0796
0797 The 22 October regulation correction reads fixed ratio-zero waiting limits from the fresh Harvester database report. Ratio-derived limits retain the last applied adjuster observation, with its timestamp and `limit_source: adjuster`; the health note calls this the last applied limit. The adjuster skips that log line while the waiting queue is full, so an old event timestamp alone does not invalidate the value. The enclosing report must still be fresh, and a failed adjuster-log read is degraded. A limit never observed remains unknown. Missing or stale pilot evidence is amber when work waits, so another green component cannot conceal missing protection. The scheduled production notifier evaluates this record independently of browser requests.
0798
0799 ### JLab commissioning evidence
0800
0801 While JLAB_PanDA_1 is not live, its reason and health come from the PanDA
0802 Harvester worker record: statuses of workers submitted in the preceding
0803 48 hours, plus the latest worker and diagnostic. Failed or cancelled
0804 workers show red even before any PanDA payload starts. An unavailable
0805 query says unknown and shows amber. The former static claim that JLab's
0806 CE had not routed jobs was false and was removed on 22 October 2026.
0807 Other queue status policies are unchanged. Worker start/end timestamps
0808 are not used to infer runtime: Harvester can stamp them when discovering
0809 an already finished worker. The 48-hour failure history can remain red
0810 after a successful commissioning probe; the latest worker is stated
0811 separately, and admission to production remains an operator decision.