Tests only, plus wording. No change to what the reader or bridge does.
- A spawn timeout and a spawn error (ENOBUFS from a bridge that floods
stdout) record unknown, are never re-posted, and block the closure.
WATCHDOG_NOTICE_BRIDGE_TIMEOUT_MS overrides the 60 s timeout so the test
reaches that branch; the default is unchanged.
- A 500/502/503/429 answer to the message POST exits 75 from the bridge, and
through the reader is retried with the same nonce until it completes.
- allowed_mentions {parse: []} is asserted in the posted body; status exits
non-zero while an entry is unknown and zero when none is.
- The bridge comment and docs/watchdog-notice.md no longer call a non-2xx
answer "definite": it is retried with the same nonce, relying on
enforce_nonce inside Discord's window, and may double-send if Discord acted
on a 5xx outside it.
Builds. Two tests fail on Windows (SIGKILL status), as before; they pass on
Yggdrasil.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Fix batch for Soul pass s1 (spec r3):
- Delete prune-on-absence and its test. Absence from Idunn's store no longer
deletes a journal entry, so an empty or restored store never re-sends.
- discord-dm exits 75 only when no message can have been sent (arguments,
token, DM channel open, non-2xx on the message POST). The reader records
failed for 75 only; any other non-success without a message id is unknown
and is never re-posted.
- Subject grammar is Idunn's require_id; the notice puts it in backticks.
- Times are bounded to the Date range; notice text is built before the
running entry is written.
Builds and passes on Linux. On Windows the two tests that SIGKILL the reader
cannot pass (process.kill does not deliver a signal there).
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
tools/watchdog-notice.mjs is a one-shot reader. It reads Idunn's incident
store unlocked with SingleFileMessagePackBackingStore.pullAll, sends one opening
and one closing DM per incident through bifrost-bridge.mjs, and keeps a
bifrost.watchdog_notice_execution.v1 journal: a running entry becomes unknown
and is never re-posted, a failed one is retried with the same nonce up to five
times, terminal entries are pruned once Idunn retires the incident. The exit
status is the delivery-failure signal.
discord-dm accepts --nonce (at most 25 chars) and sends nonce with
enforce_nonce so a retry inside Discord's window returns the original message.
The tests run the CLI against the store bytes Idunn wrote (fixture from
GameCult/Idunn 7f7528b3) with a counting bridge double, and once through the
real bridge with fetch stubbed. docs/watchdog-notice.md states the CultLib
>= 8cb3b728 floor.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
REC-099: `postBridgeJson` (tools/bifrost-bridge.mjs) and
`postDispatchRunJson` (tools/dispatch-agent-requests.mjs) each occur
exactly once in their file: their own definition, with no caller.
Each was the sole caller of that file's private `ensureTrailingSlash`
copy, which becomes dead in the same cut. The `ensureTrailingSlash`
copies in agent-transport.mjs and governance-threads.mjs are separate,
still-called definitions and were left untouched.
Kill attempts that failed: none.
- `rg -n "postBridgeJson" tools/*.mjs` -> only its own (now removed)
definition.
- `rg -n "postDispatchRunJson" tools/*.mjs` -> only its own (now
removed) definition.
- `rg -n "ensureTrailingSlash" tools/bifrost-bridge.mjs` and the same
against tools/dispatch-agent-requests.mjs -> confirmed each file's
copy had exactly one caller (the function just removed) before
cutting it.
Checks run: `node --check tools/bifrost-bridge.mjs` and
`node --check tools/dispatch-agent-requests.mjs` -> both syntax OK. No
package.json/test suite exists for these standalone tool scripts.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>