Commit Graph

246 Commits

Author SHA1 Message Date
admin de392cd7b8 REPORT: the catalog speaks English — all 53 apps, 1 031 of 1 032 strings
gates / gates (push) Failing after 1s
The per-app table, the unverified UI labels for the slice-6 walk, the judgement
calls recorded rather than hidden, the one string deliberately left in Hungarian and
why the ceiling's floor is 1 rather than 0, and the live proof: the English Apps list
shows zero Hungarian app descriptions across all 53.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-09-20 16:39:42 +02:00
admin 1f8065076b English copy — BATCH 3 of 3: the last 16 apps. THE CATALOG IS TRANSLATED.
gates / gates (push) Failing after 2s
actualbudget, claper, docmost, emby, gitea, immich, kimai, komga, onlyoffice,
opengist, plant-it, rallly, recipe-importer, seerr, vaultwarden, zipline — 306
strings. EN_MISSING_CEILING 307 -> 1.

1 031 of 1 032 strings now carry an English twin. The one that does not is papra's
AUTH_SECRET description, a Hungarian defect (R-593) left to fall back rather than
translated wrongly.

The gate convicted two of my own sentences and was half right: vaultwarden's invite
step and sign-up setting ended "can open an account", and the retrieval-promise
pattern reads "can ... open" as the claim that sealed backups can be opened. Opening
an ACCOUNT is not that claim, so the conviction was a false positive — but the
wording was also the weaker wording, so both now read "can sign up". The gate has no
way to REGISTER a legitimate occurrence, which the shared vocabulary's own design
calls for; filed as R-594.

No Hungarian byte moved in any of the three batches; the freeze gate proves it on all
53 apps on every push.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-09-20 16:34:47 +02:00
admin 5fe70d1f8a English copy — BATCH 2 of 3: 17 apps, 317 strings (R-560 slice 5)
gates / gates (push) Failing after 2s
audiobookshelf, code-server, crafty-controller, glance, gokapi, gramps-web,
jellyfin, mealie, navidrome, plex, sonarr, tandoor, termix, uptime-kuma, vikunja,
wger, wishlist. EN_MISSING_CEILING 624 -> 307.

Two lines needed judgement rather than translation, and both are written up in the
CHANGELOG so a later reader does not take them for slips. Jellyfin's setup step tells
the reader to pick Hungarian in the wizard — wrong advice for an English household,
so the English says "choose your language". Mealie's "Hungarian is available too"
becomes "English and Hungarian among them". Neither adds a promise the Hungarian does
not make; the Hungarian is untouched in both.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-09-20 16:32:18 +02:00
admin 0695d8eeda English copy — BATCH 1 of 3: 17 apps, 319 strings (R-560 slice 5)
gates / gates (push) Failing after 2s
adventurelog, bentopdf, bookstack, calcom, calibre-web, ghost, grafana,
home-assistant, homebox, homepage, n8n, nextcloud, outline, papra, radarr,
sparkyfitness, wanderer. EN_MISSING_CEILING 943 -> 624.

No Hungarian byte moved; no image, pin, catalog_since or compose line changed.

The blocks are GENERATED from a flat {path: english} map rather than hand-written:
fifty nested blocks whose keys must match the Hungarian exactly is fifty chances to
mistype an env_var, and a mistyped key is INERT on the box rather than an error, so
nobody would learn. The generator builds from the same flat paths the freeze uses,
derived from the Hungarian file itself, so an invented key cannot be written.

One string is deliberately untranslated: papra's AUTH_SECRET description is a
Hungarian DEFECT (it describes a session-signing key as "the app's subdomain").
Translating it faithfully would ship the error in a second language; changing the
Hungarian is forbidden in a localisation release. It falls back, papra stands at
13/14, and the ceiling's floor is 1 until R-593 is fixed — stated in the ceiling's
own comment so a later batch does not "fix" it by editing Hungarian.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-09-20 16:29:37 +02:00
admin d9aa02a93f REPORT: the pilot's English quoted in full for the operator's read (R-560)
gates / gates (push) Failing after 2s
The three apps' English text, the per-app table, the unverified UI labels for the
slice-6 walk, the gate's five checks and the three defects its own decoys found in
it, and the live proof on both demo boxes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-09-20 14:44:02 +02:00
admin e81d41e527 English copy — the PILOT: privatebin, paperless-ngx, romm (R-560 slice 5)
gates / gates (push) Failing after 2s
89 of 1 032 strings. No Hungarian byte moved; no image, pin, catalog_since or
compose line changed. EN_MISSING_CEILING 1032 -> 943 in this commit.

Chosen for SHAPE: privatebin exercises the plain case (description, tagline, lists);
paperless-ngx adds select options, a placeholder and a customer-facing folder label;
romm carries the catalog's only optional_config block, whose group has no id of its
own and is matched by `match_group` — the Hungarian group name it translates. All
three run on the demo box, so the English pages can be fetched rather than reasoned
about.

Two gate defects fixed while translating, each found by its own decoy rather than by
reading: coverage was counted only for the apps NAMED on the command line, so
`check-copy-i18n.py privatebin` reported 47 more missing strings than the same tree
unscoped and either number could have been made to "pass"; and the ASCII-Hungarian
stems matched as bare substrings, so „ird be" convicted "the third best" and „angol"
convicted "Angola". Both now have their own case in the decoy suite.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-09-20 14:34:22 +02:00
admin 84e058463b GATE: copy-i18n — Hungarian frozen, English sound (R-560, slice 5)
`scripts/check-copy-i18n.py`, fifth row of `catalog_gates.py`, static and in the
pre-push hook. Five checks:

  1. FREEZE — every Hungarian copy string equals `copy_freeze/hu.json`. Runs on all
     53 apps whatever scope is named: a scoped push that quietly edits a neighbour is
     what a freeze is for. A NEW app must be admitted with `--add-app NAME --reason`.
  2. STRUCTURE — the `i18n.en` block may carry copy fields and nothing else; every
     key-matched entry (`env_var`, option `value`, `match_group`, `target`, `path`)
     must have a Hungarian twin, or it would be INERT on the box and the translator
     would never know. Lists must have the Hungarian's length — they are replaced
     whole, never merged by index.
  3. LANGUAGE — no accented Hungarian letter, no ASCII-ONLY Hungarian, no
     "please"/"kindly", no English retrieval promise the Hungarian does not make, the
     app name and „Felhom" preserved.
  4. CREDENTIALS — the login tokens inside `default_creds` and the initial-credentials
     note survive translation verbatim.
  5. RATCHET — `EN_MISSING_CEILING` (1032 today) convicts above AND below.

MEASURED, against the numbers the task carried: 1 032 copy strings, 832 of them with
a Hungarian letter (that half matches). The ASCII-only Hungarian is NOT three strings
(„Igen"/„Nem"/„Nincs" do not occur in this catalog at all) but roughly 120 — „Aldomain"
and „A szerver domain neve" alone are 53 each. An accent-only gate would have passed
every one of them inside an English block, which is why check 3 folds and stems.

18 decoy cases in `test_gate_decoys.py`, each seen to convict or to pass as intended
(R-421). One of them found a real hole while being written: the credential check
searched for the token as a substring, so „admin" matched "administrator" and a
rewritten login passed. It now requires word boundaries.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-09-20 14:26:07 +02:00
admin 0c19b45e31 FREEZE: the catalog's Hungarian copy, captured before slice 5 (R-560)
1 032 customer-facing strings across all 53 apps — every `description`, tagline,
use case, first step, prerequisite, deploy-field label/description/placeholder,
select-option label, optional-config group and field, integration label, data-path
label and initial-credentials note.

Captured from THIS commit's parent, before any translation exists, so the file can
only ever record what was already signed off. `scripts/check-copy-i18n.py` (next
commit) compares every string against it on every push: a translator who "fixes a
typo while they are in there" breaks the product's first localisation rule — a
household who never switches language must not be able to tell a localisation
release happened — and does it silently, because the Hungarian page still renders.

Its own commit, deliberately: a baseline that arrives with the checker that reads it
cannot be shown to predate the work it is baselining.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-09-20 14:25:13 +02:00
admin 94bc5febac REPORT: P1 fixes — vaultwarden invite-first, paperless batch sizing, live proofs
gates / gates (push) Successful in 1s
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-09-15 11:32:32 +02:00
admin 73a9bc4807 vaultwarden: compose header matches invite-first; live proof lines (R-512/R-514)
gates / gates (push) Successful in 1s
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-09-15 11:28:51 +02:00
admin e6aa4434c3 vaultwarden: signups closed by default, invite-first card (R-512); paperless: 1 worker, 1280M, card creds text (R-514/R-515)
gates / gates (push) Successful in 1s
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-09-15 09:57:08 +02:00
admin 882a43e49f REPORT: BIGNIGHT privatebin drill bump and revert; R-524 found by the revert
gates / gates (push) Successful in 1s
2026-09-15 00:28:37 +02:00
admin a161ccb918 privatebin 2.0.6 -> 2.0.5: revert the BIGNIGHT drill bump (d5d91e0) in the same phase
gates / gates (push) Successful in 1s
2026-09-14 21:17:55 +02:00
admin d5d91e09a0 privatebin 2.0.5 -> 2.0.6: DRILL bump for the BIGNIGHT guarded-update walk (reverted in the same phase)
gates / gates (push) Successful in 1s
2026-09-14 20:59:36 +02:00
admin 6d6eec3079 REPORT: R-483 closed — port-80 cut confirmed by the operator
gates / gates (push) Successful in 1s
2026-09-13 21:58:05 +02:00
admin ed62cfd28d REPORT: R-483 first cut recorded
gates / gates (push) Successful in 1s
2026-09-13 21:46:11 +02:00
admin 8555660123 adventurelog: the backend router targets port 80 (nginx + X-Accel-Redirect), not gunicorn — photos came back empty (R-483) 2026-09-13 21:45:52 +02:00
admin 317225868c adventurelog: route /media, /static, /admin, /accounts to the backend — photos rendered as broken content (R-483)
gates / gates (push) Successful in 1s
2026-09-13 21:32:44 +02:00
admin 4cfac09bc4 rules: unprompted-work.md declares unconditional: true (the instructions gate requires a scope or that declaration)
gates / gates (push) Successful in 1s
2026-09-13 21:31:36 +02:00
admin 0ced479133 rules: unprompted-work.md — the rules for goal and nightly sessions, byte-identical in all three repos
gates / gates (push) Successful in 1s
2026-09-13 21:29:48 +02:00
admin 3f73c0e28a catalog-since gate: an image: move must bump the app's catalog_since (R-452) — hook-enforced, shallow CI skips out loud
gates / gates (push) Successful in 1s
2026-09-13 19:42:13 +02:00
admin 7410915d82 REPORT: adventurelog DEBUG off and glance seed, both proven live
gates / gates (push) Successful in 1s
2026-09-13 19:38:06 +02:00
admin 50ad28631e glance: seed a default glance.yml on first boot — the image crash-loops without one (R-473)
gates / gates (push) Successful in 1s
2026-09-13 19:23:51 +02:00
admin ed2c01855b adventurelog: DEBUG=False on the backend — the image defaults to Django debug pages on the public origin (R-482)
gates / gates (push) Successful in 1s
2026-09-13 19:22:35 +02:00
admin 48d2003b7e CHANGELOG + REPORT: slice-4 live-test commits, all reverted — no net catalog change
gates / gates (push) Successful in 1s
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-09-13 12:29:59 +02:00
admin 6d8c7ab4bc Revert "LIVE-TEST (controller v0.238.0 slice 4 Scenario F), REVERTED IN THE SAME SESSION: uptime-kuma 2.4.0 -> alpine:3.20"
gates / gates (push) Successful in 1s
This reverts commit 6ce3f65, reverted EARLY — as soon as the update under test had advanced its pin,
which is the last moment the catalog value mattered to Scenario F. Flagged by the commit security
review (supply-chain: a catalog push is a deploy, and any fresh uptime-kuma install in that window
would have received an image that exits at once). Measured exposure: demo-hp's throwaway was the only
uptime-kuma install on either demo box. catalog_since is back to its original value.

Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-09-13 12:14:25 +02:00
admin 6ce3f65695 LIVE-TEST (controller v0.238.0 slice 4 Scenario F), REVERTED IN THE SAME SESSION: uptime-kuma 2.4.0 -> alpine:3.20
gates / gates (push) Successful in 1s
Scenario F of the guarded-update live validation, the same way the 2026-09-01 spike did it: the new
"version" is an image that starts and exits immediately, so the app never becomes healthy and must be
HELD — and then restored from its named copy. catalog_since moves with the image line; the revert
restores it.

Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-09-13 12:12:04 +02:00
admin 41dd686395 Revert "LIVE-TEST (controller v0.237.0 slice 4 Scenario E), REVERTED IN THE SAME SESSION: uptime-kuma 2.4.0 -> 2.4.999 (does not exist)"
This reverts commit 29a8cbe. Scenario E is recorded: the pull failed, the pin and definition were put
back, and the app's container was untouched (same id, same start time).

Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-09-13 12:11:45 +02:00
admin 29a8cbe6c4 LIVE-TEST (controller v0.237.0 slice 4 Scenario E), REVERTED IN THE SAME SESSION: uptime-kuma 2.4.0 -> 2.4.999 (does not exist)
gates / gates (push) Successful in 0s
Scenario E of the guarded-update live validation: the catalog names a tag that does not resolve, so
the update's pull must fail and the pin must be PUT BACK with the app untouched. catalog_since moves
with the image line, as the catalog rule requires; the revert restores it.

Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-09-13 12:10:26 +02:00
admin 28ce33baf1 Revert "LIVE-TEST (controller v0.237.0 slice 4), REVERTED IN THE SAME SESSION: uptime-kuma 2.4.0 -> 2.3.2"
gates / gates (push) Successful in 1s
This reverts commit 01c631d — and is itself the real catalog tag change (2.3.2 -> 2.4.0) that
Scenario A of the slice-4 live validation updates the deployed throwaway across. catalog_since is
back to its original value.

Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-09-13 12:07:28 +02:00
admin 01c631d609 LIVE-TEST (controller v0.237.0 slice 4), REVERTED IN THE SAME SESSION: uptime-kuma 2.4.0 -> 2.3.2
gates / gates (push) Successful in 1s
The throwaway app for the guarded-update live validation on demo-hp is installed from this older
tag, so the revert that follows is a real catalog tag change for Scenario A (2.3.2 -> 2.4.0).
catalog_since moves with the image line, as the catalog rule requires; the revert restores it.

Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-09-13 11:59:25 +02:00
admin 045495fa54 Revert "LIVE-TEST (controller v0.237.0 slice 4), REVERTED IN THE SAME SESSION: glance v0.8.5 -> v0.8.4"
This reverts commit a1f1c38. glance was abandoned as the live-test app: its template crash-loops on
a FRESH install (the image exits with "reading /app/config/glance.yml: no such file or directory"
and nothing seeds that file) — filed in felhom.eu OPEN-ITEMS.md. uptime-kuma is used instead.
catalog_since is back to 2026-07-18.

Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-09-13 11:59:25 +02:00
admin a1f1c38736 LIVE-TEST (controller v0.237.0 slice 4), REVERTED IN THE SAME SESSION: glance v0.8.5 -> v0.8.4
gates / gates (push) Successful in 0s
The throwaway app for the guarded-update live validation on demo-hp is installed from this older
tag, so the revert commit that follows is a real catalog tag change for Scenario A. catalog_since
moves with the image line, as the catalog rule requires; the revert restores 2026-07-18.

Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-09-13 11:54:16 +02:00
admin 3525e355a1 CHANGELOG + REPORT: MARIADB_AUTO_UPGRADE on four db services, engine-major gate, harness verdicts
gates / gates (push) Successful in 0s
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-09-13 09:58:02 +02:00
admin bd328307d4 engine-major gate: no database-engine pin crosses a MAJOR until Slice 4 (R-448) ships
The rule (CLAUDE.md, operator ruling 2026-09-13): until the Update button takes a verified backup
as its precondition, no template may move a mariadb:/postgres: image across a major version. Four
MariaDB and eleven PostgreSQL services; the gate finds them by image name, not by a list.

scripts/check-engine-major.py — fast (git reads only), diffs each changed template's per-service
image: line between the two ends of the push range, refuses a major move naming the rule and its
expiry (R-448). Fourth row of catalog_gates.py; .githooks/pre-push now hands the push range
through as --range=<remote sha>..<local sha>.

HONEST LIMIT: it needs a parent commit and CI fetches at --depth 1 (the R-452 gap, not re-filed),
so on a shallow clone the runner SKIPS it out loud instead of reddening every CI push. The hook,
which has the full clone, is where it bites.

Red-proof (scripts/test_gate_decoys.py, 7 cases, all seen to judge correctly): mariadb 11.6->12.3
REFUSED, postgres 16->17 REFUSED, mariadb:lts INCONCLUSIVE; 11.6->11.8 PASSES; the major moving
only in a comment / kimai's serverVersion env / README / the app's own image PASSES. COVERS literal
registered for felhom.eu's decoy_coverage_gate (which now reads 1 covered, 3 exempt, 0 unaccounted).
test_catalog_gates.py pins the four-gate table and the announced shallow-clone skip.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-09-13 09:45:35 +02:00
admin eec1228dc8 MariaDB finishes its own conversion: MARIADB_AUTO_UPGRADE=1 on the four db services (R-459)
bookstack-db, kimai-db, nextcloud-db, romm-db each gain `MARIADB_AUTO_UPGRADE=1` in the db
service's environment list. Operator ruling 2026-09-13 on the measurement in
felhom.eu/documentation/audits/SPIKE-r459-mariadb-upgrade-2026-09-06.md: an unconverted datadir
is stable but never heals; the conversion costs ~7 s and the engine backs its system tables up
first. MARIADB_DISABLE_UPGRADE_BACKUP is deliberately left UNSET — that backup is the precaution.

NO `image:` line changed, so `catalog_since` does NOT move — the CLAUDE.md rule ties it to an
image change and this is not one. Do not "fix" that.

The setting is inert until an engine major actually moves, and none may until Slice 4 (R-448)
ships — see the engine-major rule in CLAUDE.md and scripts/check-engine-major.py (next commit).
The eleven PostgreSQL templates are untouched: R-463 is a different engine and a different
measurement.

REUSE.md: one convention row for the MariaDB sidecar env, same commit.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-09-13 09:40:22 +02:00
admin b7ef0c4a09 upgrade-test.py: record the engine's own view of its datadir, beside the verdict
gates / gates (push) Successful in 1s
R-459. The harness returned proven for E3b while MariaDB was logging that the
conversion it requires had been skipped. The verdict was right - the app's data
survived, which is what it asked - but the harness watched the app and the
migration log, and neither looks at engine state.

engine_state_after now carries each database service's own answer: MariaDB's
datadir version plus 'mariadb-upgrade --check-if-upgrade-is-needed', and
PostgreSQL's PG_VERSION.

It sits BESIDE the verdict and is never folded into it. An unconverted datadir is
not known to be a failure - 5 of 5 restarts showed no degradation - so a verdict
that called it failed would encode an unproven judgement, which is worse than
reporting a fact and letting a person read both.

No template changed. Nothing with MARIADB_ in it is committed by this work: that
is a fleet-wide decision the operator owns, and it affects four apps.
2026-09-06 17:38:50 +02:00
admin 0474ce387e upgrade-test.py: measure whether a real app upgrade keeps the customer's data
gates / gates (push) Successful in 0s
R-449. Until today one upgrade out of 53 had ever been measured - Nextcloud, by
hand, in a spike - and the whole update arc was designed against that single data
point.

Per edge: deploy at FROM, seed through the app's OWN interface, prove the seed
reads back, swap to TO, ask the app for the data again, then put the FROM images
back and record what happens - verbatim, and never called a rollback.

Success is an application-level readback, not file identity: survive2.py's
sha256+inode rule is right for a redeploy and wrong for an upgrade, because a
migration is supposed to rewrite files. And nothing is ever seeded by hand (R-156)
- an app with no non-browser route is recorded inconclusive, never faked.

C3 is a negative control whose TO image exits immediately, and it must be run
first: it came back failed, which is what makes the greens mean anything.

The bookstack fixture uses artisan for both halves and carries its own negative
control on every call, because the obvious HTTP-login readback cannot work: the
template's https APP_URL makes the session cookies secure, so curl over http gets
419 on every login and it looks exactly like a wrong password.
2026-09-06 11:44:18 +02:00
admin 7b9b9b34a5 CHANGELOG: record the two v0.235.0 live-test pushes and their reverts as a measurement, not a release
gates / gates (push) Successful in 1s
2026-09-06 10:23:06 +02:00
admin 17cc784b0f Revert "LIVE-TEST (v0.235.0 Scenario A), REVERTED IN THE SAME SESSION: bentopdf healthcheck interval 30s -> 45s"
This reverts commit dc7e5484fd.
2026-09-06 10:22:54 +02:00
admin 1798ce62b8 Revert "LIVE-TEST (v0.235.0 Scenario B), REVERTED IN THE SAME SESSION: bentopdf v2.8.6 -> v2.8.5"
This reverts commit 09b4ff50a4.
2026-09-06 10:22:54 +02:00
admin 09b4ff50a4 LIVE-TEST (v0.235.0 Scenario B), REVERTED IN THE SAME SESSION: bentopdf v2.8.6 -> v2.8.5
gates / gates (push) Successful in 0s
An IMAGE change, pushed to prove that a pinned app does NOT receive it — the whole
point of slice 3. bentopdf is deployed on demo-hp only and is file-based with no
database and no volume, so no data anywhere can be touched. The revert follows in
the same session.
2026-09-06 10:05:35 +02:00
admin dc7e5484fd LIVE-TEST (v0.235.0 Scenario A), REVERTED IN THE SAME SESSION: bentopdf healthcheck interval 30s -> 45s
gates / gates (push) Successful in 0s
A NON-image template change, pushed to prove that a pinned app still receives
template fixes on the normal 15-minute cycle. No image pin is touched. The revert
commit follows in the same session.
2026-09-06 09:47:17 +02:00
admin 8220f8d82e REPORT: the catalog_since backfill — 53 apps, six hand-checks, one known gate gap
gates / gates (push) Successful in 1s
2026-09-02 20:15:53 +02:00
admin 69761cf91b catalog_since on all 53 apps: the date this repo last moved each app's pinned images
Backfilled from this repo's own git history (newest commit whose image: set differs
from its parent's), excluding the two bentopdf SPIKE commits by hash — they moved a
pin and reverted it in the same hour and are a measurement, not a release.

Four anchors confirmed (nextcloud 5e2c1ae, grafana b789acc, calcom 147cee7,
vikunja 3fa63cd, all 2026-07-18); six apps re-checked against git log by hand.

Consumed by felhom-controller v0.233.0 to render 'Frissitesi elerheto - N napja'.
No version number is ever shown to the customer, so there is no version: key.

Rule added to CLAUDE.md; the missing drift gate is filed as a register row (the
gates runner fetches at --depth 1 and has no parent to diff an image: line against).
2026-09-02 20:15:33 +02:00
admin 5d8f25f611 CHANGELOG: record the bentopdf pin move + revert as a spike measurement, not a release
gates / gates (push) Successful in 1s
2026-09-01 19:59:22 +02:00
admin 30bd892fd3 Revert "SPIKE ONLY, REVERTED IN THE SAME SESSION: bentopdf v2.8.6 -> v2.8.5"
This reverts commit 214d44873a.
2026-09-01 19:59:09 +02:00
admin 214d44873a SPIKE ONLY, REVERTED IN THE SAME SESSION: bentopdf v2.8.6 -> v2.8.5
gates / gates (push) Successful in 0s
Phase 2 of SPIKE-app-update-2026-09-01: measure live whether the 15-minute
catalog sync rewrites a DEPLOYED app's docker-compose.yml on demo-hp while its
running container keeps the old image (R-438).

bentopdf is deployed on demo-hp ONLY (demo-felhom runs opengist alone; Peti's
box is down with no access route), it is file-based with no database and no
volume, so the change cannot touch customer data anywhere.

This commit is reverted as soon as the measurement is taken.
2026-09-01 19:38:21 +02:00
admin 29edad9c5b decoy sweep: no gate changed here, and that is the result (R-421)
gates / gates (push) Successful in 1s
All 29 gate scripts across the four repos were read and DECOYED - the label constructed without the
fact, the gate run, the verdict recorded. 16 were fooled. None of them were in this repo.

A decoy that nobody would write proves nothing, so the attempts that turned out illegitimate were
WITHDRAWN rather than counted. Both of this repo were withdrawn, and both are named in the audit.

The gates here that could not be given a plausible decoy are listed BY NAME in
felhom.eu/scripts/decoy_coverage_gate.py EXEMPT (R-426) as UNTESTED - not as sound. A gate nobody
tried to fool is UNKNOWN, and calling it sound would be the same confident guess this sweep exists
to find.

Survey table: felhom.eu/documentation/audits/AUDIT-gate-decoys-2026-09-01.md
2026-09-01 12:38:59 +02:00
admin 459766cb16 docs: R-168 is CLOSED — the "CI is still owed" sentence was stale (R-229 part 2)
gates / gates (push) Successful in 0s
Corrected in all four instruction files across all four repos. Found while confirming this
session own push by run ID, which is precisely the check that catches it.

In felhom-agent/CLAUDE.md the sentence contradicted the same file release section, which
already said R-168 mails the failure -- a contradiction inside one instruction file, the exact
class the R-229 work exists to find.

REPORT.md deliberately NOT overwritten in the sibling repos: a one-line docs correction must not
destroy the record of their last real implementation.
2026-08-06 11:03:02 +02:00