Notice when an alert does not arrive, and stop pasting a fake token #4

Merged
branderson merged 1 commits from alert-verify into main 2026-08-28 17:39:46 -07:00
Collaborator

Summary generated by LLM agent

Reported: the container setup had

printf 'ntfy_token = tk_...\n' > secrets/config

inside a block meant to be pasted whole. Pasted verbatim that writes a literal tk_..., and the operator ends up with a config carrying a wrong token.

Which turned out to be the smaller half

Every alert call site ended in || true.

So a wrong token — or a wrong topic, or an ntfy that was down — produced exactly nothing: the guard collected, found drift, printed ALERTED: see ..., and no alert existed anywhere. The report on disk was the only trace.

That is the worst failure this program can have. Worse than the guard dying, because a dead guard trips the heartbeat and this did not. And a token pasted from the README would have produced precisely it.

What changed

A failed send is reported, and suppresses the heartbeat.

A guard that has found something and cannot tell anyone is, for every practical purpose, a guard that is not running — and the one channel left that can report that is the one that reports silence. Letting the heartbeat through would tell Uptime Kuma all is well on the single cycle where that is least true.

The detail is still written to the report, since it is now the only surviving record of a finding nobody was told about.

dejima-guard test-alert, because the fallback above is not a fix.

A clean cycle never publishes, so a broken channel waits undiscovered until the first real finding — and then takes it down with it. Nothing inside this program can close that: whether a push arrived is a question only the phone in your pocket answers. So it is a command, the setup says to run it and go and look, and it prints "sent is not received" rather than implying it verified anything.

The secret is a documented step, not a pasteable placeholder: create secrets/config, put the token in it, with what it is and where it comes from stated. The surrounding steps are numbered and separated so the whole thing is not one block to paste.

Tested

bats test/ — 33 passing, 7 new:

  • a failed send is reported rather than swallowed;
  • a failed send suppresses the heartbeat — the point of the first;
  • the detail is still written when the alert could not go;
  • no alerting configured at all is a failure, not a quiet success;
  • test-alert publishes and says sent is not received;
  • test-alert fails loudly when the channel is broken;
  • the README never pastes a placeholder token into a file again.

That last one is a grep guard on the documentation, in the same spirit as the CHANGE-ME check: the bug was in prose, and prose is where it would come back.

Still not run

No docker here, and ssh/curl are stubbed. test-alert is exercised against a stub curl, so what is verified is that the guard reacts correctly to a send failing — not that publishing to a real ntfy works. That is the step the setup now asks you to perform.

**Summary generated by LLM agent** Reported: the container setup had ```sh printf 'ntfy_token = tk_...\n' > secrets/config ``` inside a block meant to be pasted whole. Pasted verbatim that writes a literal `tk_...`, and the operator ends up with a config carrying a wrong token. ## Which turned out to be the smaller half Every `alert` call site ended in `|| true`. So a wrong token — or a wrong topic, or an ntfy that was down — produced **exactly nothing**: the guard collected, found drift, printed `ALERTED: see ...`, and no alert existed anywhere. The report on disk was the only trace. That is the worst failure this program can have. Worse than the guard dying, because a dead guard trips the heartbeat and this did not. And a token pasted from the README would have produced precisely it. ## What changed **A failed send is reported, and suppresses the heartbeat.** A guard that has found something and cannot tell anyone is, for every practical purpose, a guard that is not running — and the one channel left that can report that is the one that reports *silence*. Letting the heartbeat through would tell Uptime Kuma all is well on the single cycle where that is least true. The detail is still written to the report, since it is now the only surviving record of a finding nobody was told about. **`dejima-guard test-alert`**, because the fallback above is not a fix. A clean cycle never publishes, so a broken channel waits undiscovered until the first real finding — and then takes it down with it. Nothing inside this program can close that: whether a push *arrived* is a question only the phone in your pocket answers. So it is a command, the setup says to run it and go and look, and it prints **"sent is not received"** rather than implying it verified anything. **The secret is a documented step**, not a pasteable placeholder: create `secrets/config`, put the token in it, with what it is and where it comes from stated. The surrounding steps are numbered and separated so the whole thing is not one block to paste. ## Tested `bats test/` — 33 passing, 7 new: - a failed send is reported rather than swallowed; - **a failed send suppresses the heartbeat** — the point of the first; - the detail is still written when the alert could not go; - no alerting configured at all is a failure, not a quiet success; - `test-alert` publishes and says sent is not received; - `test-alert` fails loudly when the channel is broken; - the README never pastes a placeholder token into a file again. That last one is a grep guard on the documentation, in the same spirit as the `CHANGE-ME` check: the bug was in prose, and prose is where it would come back. ## Still not run No docker here, and `ssh`/`curl` are stubbed. `test-alert` is exercised against a stub curl, so what is verified is that the guard reacts correctly to a send failing — not that publishing to a real ntfy works. That is the step the setup now asks you to perform.
dejima-agent added 1 commit 2026-08-28 17:01:31 -07:00
Reported: the container setup had

    printf 'ntfy_token = tk_...\n' > secrets/config

inside a block meant to be pasted whole. Pasted verbatim it writes a literal
tk_... and the operator has a config with a wrong token.

WHICH TURNED OUT TO BE THE SMALLER HALF. Every alert call ended in `|| true`,
so a wrong token, a wrong topic or an ntfy that was down produced exactly
nothing: the guard found drift, printed ALERTED, and no alert existed. That
is the worst failure this program can have - worse than dying, because a dead
guard trips the heartbeat and this did not. A wrong token pasted from the
README would have produced precisely it.

A failed send now says so, and SUPPRESSES THE HEARTBEAT. A guard that has
found something and cannot tell anyone is, practically, a guard that is not
running, and the one channel left that can report it is the one that reports
silence. Letting the heartbeat through would tell the dead-man's switch all
is well on the single cycle where that is least true.

That is a fallback rather than a fix, because a clean cycle never publishes -
so a broken channel waits undiscovered until the first real finding takes it
down with it. Hence `test-alert`, and a setup step that says to run it and go
and look. Whether a push arrived is a question only the operator's phone can
answer, so the command says "sent is not received" rather than implying it
verified anything.

The secret is a documented step now: create secrets/config and put the token
in it, with what and where stated, rather than a placeholder in a code block.

`bats test/` 33 passing, 7 new - including one asserting the README never
pastes a placeholder token into a file again.
branderson approved these changes 2026-08-28 17:39:41 -07:00
branderson merged commit 4471bf74ce into main 2026-08-28 17:39:46 -07:00
Sign in to join this conversation.