From 470afbff9841eef3f37d557e983a088327d96339 Mon Sep 17 00:00:00 2001 From: autonomic-bot Date: Sun, 31 May 2026 05:24:19 +0000 Subject: [PATCH] =?UTF-8?q?fix(discourse=20F2-15):=20add=20N/A=20PARITY.md?= =?UTF-8?q?=20(P2=20=C2=A74.1)=20=E2=80=94=20parity=20genuinely=20N/A=20(n?= =?UTF-8?q?o=20upstream=20corpus);=20documents=20functional=20tests=20+=20?= =?UTF-8?q?P4=20integrity?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- machine-docs/JOURNAL-2.md | 12 ++++++++++ tests/discourse/PARITY.md | 49 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 tests/discourse/PARITY.md diff --git a/machine-docs/JOURNAL-2.md b/machine-docs/JOURNAL-2.md index 0bbdc64..f3a991b 100644 --- a/machine-docs/JOURNAL-2.md +++ b/machine-docs/JOURNAL-2.md @@ -1618,3 +1618,15 @@ silent-wget defect → cache/retry/un-silence; full upgrade/backup/restore green sign-off granted; maximal gitea+drone subset run post host-rebuild). Both need the cc-ci node; HOLDING deploys while the Adversary cold-verifies (single node, MAX_TESTS=1). Next: author plausible recipe-PR offline, queue its validation run for when the node frees. + +--- +## 2026-05-31T05:3xZ — discourse Q4.6 PASS; fixed F2-15 (PARITY.md); mumble F2-14c verdict pending (Builder) +**Adversary cold-verified discourse Q4.6 = PASS** (REVIEW-2 `7525478` @05:34Z) — closes the discourse +portion of the DONE VETO. One finding **F2-15 [adversary]**: `tests/discourse/PARITY.md` missing (P2 §4.1 +required file even though parity is genuinely N/A — no upstream discourse corpus). NOT a VETO item, does +not reopen Q4.6. **Fixed:** added `tests/discourse/PARITY.md` (N/A parity note + the 3 functional tests +[create-topic round-trip §4.3, site.json config, health] + P4 postgres ci_marker integrity + BACKUP_VERIFY +note + P6 advisory), modeled on ghost/mattermost-lts N/A PARITY.md; claims verified against the live test +bodies (site_basic asserts `categories` is a list; health GETs /srv/status). Left the F2-15 box for the +Adversary to close after re-check (only the Adversary closes [adversary] items). mumble F2-14c verdict +still pending; plausible Q4.7b + drone Q4.10 queued behind the node. Still parked on the F2-14c gate. diff --git a/tests/discourse/PARITY.md b/tests/discourse/PARITY.md new file mode 100644 index 0000000..18f6d25 --- /dev/null +++ b/tests/discourse/PARITY.md @@ -0,0 +1,49 @@ +# Parity — discourse + +The recipe-maintainer corpus has **no** `recipe-info/discourse/tests/` directory — discourse was not +in their parity suite (verified absent: `/srv/recipe-maintainer/recipe-info/discourse` does not +exist). So there is **no upstream test to port** and parity is genuinely **N/A** (no silent omission — +there is simply no corpus). Per plan §4.1 this file still documents the Phase-2 health baseline + +recipe-specific tests beyond, and P2's "non-ports documented" requirement is satisfied by this note. + +## Parity ports + +None — no `recipe-info/discourse/tests/*.py` exists upstream to port. (Not a deliberate omission of a +test that exists; the upstream corpus is absent. Same disposition as ghost / mattermost-lts.) + +## Recipe-specific tests (Phase-2 P3, ≥2 beyond a bare health check) + +Discourse is a **forum/discussion platform**: a Rails app whose primary object is a *topic* (a thread +of posts), with a public JSON surface (`/site.json`, `/t/.json`, `/posts.json`) and an Admin API. +Defining behaviors exercised against the live per-run deploy: + +| cc-ci file | what's verified | rationale | +|---|---|---| +| `functional/test_create_topic.py::test_create_topic_roundtrip` | Bootstraps an admin + API key via Rails in the `app` container (`_discourse.mint_admin`), POSTs `/posts.json` to create a NEW topic with a unique marker in title + body, then GETs `/t/.json` and asserts the title (Discourse `title_prettify`-aware) **and** the unique body marker round-tripped in the first post's `cooked`. | §4.3 "create the app's primary object — a topic — and read it back". Non-vacuous: the marker is unique per run, so a stale/echoed response can't pass; a wedged DB/Rails/posting path fails here even though `/srv/status` returns 200. | +| `functional/test_site_basic.py::test_site_json_has_discourse_config` | GETs `/site.json` and asserts a Discourse-specific config structure (e.g. a `categories` list), not a bare 200. | Proves Rails is serving its real site config JSON (a distinctive Discourse structure), distinguishing "the forum backend is up + emitting its API" from "a static/error page at /". | +| `functional/test_health_check.py::test_discourse_srv_status_ok` | GETs `/srv/status` and asserts the Discourse readiness signal (Rails serving). | Baseline readiness (parity-aligned health check). | + +Two recipe-specific functional tests (create-topic round-trip + site.json config) + the health check += the ≥2 floor met, with a real create-an-object + read-it-back as the characteristic-behavior test. + +## Backup data-integrity (P4) — AUTHORED, non-vacuous + +`ops.py` + the lifecycle overlays (`test_backup.py` / `test_restore.py`) seed a deterministic +`ci_marker` row into the **PostgreSQL** `discourse` DB (the recipe's real state store), via the `db` +service. The recipe's backupbot db pre-hook (`/pg_backup.sh backup`, added in PR head `3758522`) dumps +the DB into the backed-up `postgresql_data/backup.sql`; the `backupbot.restore.*` post-hook reimports +it — so the seeded marker rides backup→restore the way a real topic's row would. `pre_restore` drops +the marker table (divergence so a passing restore can't be a no-op); `test_restore.py:: +test_restore_returns_state` asserts the value returns post-restore. The published recipe had a pg_dump +backup but **no restore hook** (silent data loss — same class as immich/mattermost-lts/ghost); cc-ci's +P4 overlay caught it, fixed via recipe-PR `recipe-maintainers/discourse#1`. + +A `BACKUP_VERIFY` probe (`recipe_meta.py`) re-runs the backup if `backup.sql` is gzip-invalid/empty +(the chaos-upgrade db-cycle race truncates the dump) — a read-only check that weakens no assertion; +the restore re-read stays the real P4 gate. + +## Playwright (P6) + +Not authored. Discourse's core API surface is exercised over HTTP/JSON above (create-topic round-trip +is the characteristic flow); a Playwright login + topic-compose flow would be a future hardening +(advisory, not a P3 blocker — the create-an-object behavior is already proven via the Admin API).