mirror of
https://github.com/kuhyx/signal-bot.git
synced 2026-11-14 16:31:01 +01:00
!sztuka posts a work of art, skewed 60% Polish; !wiersz posts one short public-domain Polish poem, whole. Both follow the rule the rest of the bot already keeps: the repository commits identifiers, and the words arrive over the wire when somebody asks. !wiersz was written the other way first, and the gate caught it. A pack of short public-domain poems was harvested, name-filtered and committed, and check_personal_data.sh refused it: three lines carried a real group member's given name, and two still did after a filter that had discarded 31% of the corpus. That is structural, not a tuning problem -- Polish verse capitalises every line, so a line-initial capital carries no signal, and that is exactly where a name sits. The pack now holds Wolne Lektury slugs; the poem, its title and its author are fetched at post time and appear nowhere in git. It is also the better version: with no name filter there are no false positives, so the pool is larger and the attribution is a full name again. The gate then refused the art category list too, over a painter whose given name is somebody's. That is the popes.json case exactly, so it takes the same answer: a file-scoped allowlist entry, still refused everywhere else. The Commons harvest is now three modules by what they are, not by where the line count fell: commons_api is the conversation with Commons, commons_harvest turns categories into a pool of licensed page ids, commons_cache makes an interrupted run resumable. Along the way it gained licences in the same request that lists a category (the second pass was 1,500 requests at 2.3s each), maxlag instead of a guessed sleep, 5xx retries because one 504 used to destroy a whole run, and Wikidata for works by creators of Polish citizenship: the Polish pool grew 15,221 -> 20,092. Batching categories through CirrusSearch looked like a further 6x and was measured out again: 2,404 files where the authoritative enumeration returns 2,429, a different ~1% missing on every run. The offline run is 19s where it was four minutes, almost all of it the deafness gate waiting out three thirty-second liveness probes to prove something provable in three; the tick is configuration now, and e2e enforces a 40s budget on itself so that never silently comes back.
102 lines
4.1 KiB
Bash
Executable File
102 lines
4.1 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# ============================================================================
|
|
# The assertions scripts/e2e.sh makes after the scenarios have replayed.
|
|
#
|
|
# Split out of e2e.sh at the 250-line cap. A filing change, not an interface
|
|
# change: these are sourced, so they still run against the same fake server
|
|
# and the same bot process the scenarios used.
|
|
# ============================================================================
|
|
|
|
prove_the_add_photo_invariants() {
|
|
local pack="${TEMP_DIR}/pack"
|
|
|
|
echo "== checking every stored file was actually stripped"
|
|
"$PYTHON" "$REPO_ROOT/tool/e2e_media.py" --verify-pack "$pack"
|
|
|
|
echo "== checking a typed label never reached custom.json as a key"
|
|
if grep -qE '"(wakacje|piesek)"[[:space:]]*:' "${pack}/custom.json"; then
|
|
echo "Error: a typed label became a key in custom.json" >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "== checking !dodaj with no attachment minted nothing"
|
|
if grep -q "piesek" "${pack}/custom.json"; then
|
|
echo "Error: a mint survived a message that carried no attachment" >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "== checking the refused uploads were not stored"
|
|
if grep -q "att-junk" "${pack}/tags.json"; then
|
|
echo "Error: a refused file reached tags.json" >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "== checking signal-cli's own copies were deleted"
|
|
local left
|
|
left="$(curl -sf "${FAKE_URL}/_control/attachments")"
|
|
if [[ "$left" == *"att-person"* || "$left" == *"att-custom"* ]]; then
|
|
echo "Error: an ingested attachment is still in the container store: ${left}" >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "== checking the adder was recorded for a future !undo_photo"
|
|
if [[ ! -s "${pack}/adds.json" ]]; then
|
|
echo "Error: adds.json was never written" >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# The gate that did not exist on 2026-08-29, proven against the real process:
|
|
# with signal-cli unable to reach Signal, /healthz must go red rather than
|
|
# keep answering 200 while nothing arrives.
|
|
prove_the_deafness_gate() {
|
|
local health="http://127.0.0.1:${BOT_PORT}/healthz"
|
|
echo "== cutting the fake's connection to Signal"
|
|
curl -sf -X POST "${FAKE_URL}/_control/connection" \
|
|
-H 'Content-Type: application/json' -d '{"alive": false}' >/dev/null
|
|
|
|
local code="" waited=0
|
|
while ((waited < 150)); do
|
|
code="$(curl -s -o /dev/null -w '%{http_code}' "$health")"
|
|
[[ "$code" == "503" ]] && break
|
|
sleep 1
|
|
waited=$((waited + 1))
|
|
done
|
|
[[ "$code" == "503" ]] || die "/healthz still answers ${code} with the connection cut"
|
|
curl -s "$health" | grep -q "Closed unexpectedly" ||
|
|
die "/healthz went red without saying why"
|
|
echo "== /healthz turned 503 and named the reason after ${waited}s"
|
|
|
|
echo "== restoring the connection"
|
|
curl -sf -X POST "${FAKE_URL}/_control/connection" \
|
|
-H 'Content-Type: application/json' -d '{"alive": true}' >/dev/null
|
|
waited=0
|
|
while ((waited < 150)); do
|
|
code="$(curl -s -o /dev/null -w '%{http_code}' "$health")"
|
|
[[ "$code" == "200" ]] && break
|
|
sleep 1
|
|
waited=$((waited + 1))
|
|
done
|
|
[[ "$code" == "200" ]] || die "/healthz stayed ${code} after the connection came back"
|
|
echo "== /healthz recovered on its own after ${waited}s"
|
|
}
|
|
|
|
# A budget, not a benchmark. This run was four minutes until the liveness
|
|
# tick became configurable, and nothing announced the cost -- slower is the
|
|
# one regression a green suite never reports. Exceeding it fails the run;
|
|
# whoever exceeded it decides whether the check earned its seconds or the
|
|
# budget moves. E2E_BUDGET_SECONDS raises it for a loaded machine.
|
|
enforce_the_time_budget() {
|
|
local started="$1"
|
|
local budget="${E2E_BUDGET_SECONDS:-40}"
|
|
local elapsed=$(( $(date +%s) - started ))
|
|
echo "== end to end took ${elapsed}s (budget ${budget}s)"
|
|
if ((elapsed > budget)); then
|
|
echo "Error: the offline run took ${elapsed}s, over its ${budget}s budget." >&2
|
|
echo " Either the new check earns its seconds and the budget moves," >&2
|
|
echo " or something got slower and this is the report of it." >&2
|
|
exit 1
|
|
fi
|
|
}
|