Expand description
Notices: what needs the operator’s attention but is not a question.
A merged run whose release bump failed, a task held after three attempts, a
disk gate that refused to start work - each used to end in a log line or in
a question-shaped record nobody could answer. A Notice is the missing
shape: something to know, with a severity, a timestamp and an optional
link, that the operator marks read or dismisses. It is deliberately not a
crate::ask::Question: nothing waits on it and there is nothing to answer.
§Shape
The same split as crate::queue and crate::ask. Notice is data
plus pure transitions; Notices owns every filesystem call and is
constructed with its root, so a test drives a real store in a temp
directory and nothing here is process-global.
One notice is one JSON file, written atomically, because magi serve,
magi web and the CLI all write here from different processes and a rename
is the only cross-process write that needs no coordination. The file name is
derived from the notice’s key by a stable function, which is what makes
deduplication lock-free: two processes raising the same problem write the
same file. A raise racing another may lose one increment of count; that is
accepted.
§Deduplication, and what dismissing means
A key names a kind and a subject (release-bump:<run>, task:<id>), never
the prose. Raising a key that exists bumps count and last_at. It returns
the notice to unread only when the message changed or the severity rose:
a retry loop re-raising the identical problem must not relight the bell.
Dismissal is a tombstone (dismissed_at) rather than a delete, so the same
message re-raised does not resurrect what the operator already waved away.
The cost is that a genuine recurrence with identical wording stays hidden
until the cap prunes the tombstone; producers should therefore keep
messages stable and put anything that varies elsewhere.
Structs§
- Notice
- One thing the operator should know.
- Notices
- A notice store on disk.
- Page
- One page for the operator’s
[notify]command.
Enums§
- Link
- Where a notice points, when it points anywhere.
- Severity
- How serious a notice is. Ordered so a rise is a plain comparison.
Constants§
- CAP
- The most notices kept. Older ones are pruned on every write: dismissed first, then read, then unread, oldest first within each.
- SCHEMA
- On-disk format. A file is refused only when its own schema is greater
than this one; every field added later must carry
#[serde(default)].
Functions§
- covers
- Does open question
qalready page the operator for whatnreports? - id_of
- A stable, file-name-safe id for a key: a readable slug plus FNV-1a of the
whole key. Not
DefaultHasher, whose output may change between builds and would strand every existing file’s dedupe. - install_
pager - Let notices fire the
[notify]command in this process. - merged_
red - The notice for a pull request that merged while checks were red.
- quiet_
for - A question was just filed for
run: quiet the unread notices about it. - raise
- The one function producers call. Best-effort by construction: a notice that
cannot be filed is a
tracing::warn, never a reason to fail the run, the loop or the request that wanted to mention it. - raise_
in raiseinto an explicit magi home, for callers that already carry one (the janitor) and so must not reach for the process-global.- raise_
in_ with raise_inwith the pager injected.sendis called only when the raise should page (seeNotice::raise_again); it must not block.- raise_
with raisefor a producer that already holds the repo’s[notify].- run_
ended - The notice for a run that ended Blocked, Stalled or Failed, if it did.
- run_
stopped - The notice for a run whose graph returned an error before it settled.
- task_
held - The notice for a task the machine or its attempt budget has held, if it is.