Commit Graph

76 Commits

Author SHA1 Message Date
admin 65130c6c03 REPORT: the operator's ten answers (2026-10-06)
gates / gates (push) Successful in 3s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-06 12:29:01 +02:00
admin d1a148408f REPORT: the morning after (2026-10-06)
gates / gates (push) Successful in 4s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-06 08:50:51 +02:00
admin d955df1f15 REPORT: the burn-down night (2026-10-06)
gates / gates (push) Successful in 4s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-06 02:13:13 +02:00
admin 4828dc754d burn-down round 2: R-593 papra field copy, R-760 vikunja healthcheck reason, R-594 English allow-list, R-605 refusal exit 3, R-781 onboarding decoy clone, R-806 scheme; stale runner test fixed
gates / gates (push) Successful in 4s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-05 19:15:02 +02:00
admin 29ac711d26 R-799 metube add body, R-761 logo name, R-391 no observations section (burn-down)
gates / gates (push) Successful in 2s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-05 16:55:06 +02:00
admin 917a779cca Persistence gate: empty declared volume = UNDETERMINED (R-788), the app's own fixture seed as the exercise; re-sweep verdicts (CLEAN 40 / UNDETERMINED 18 / BROKEN 0); papra 256M -> 768M (R-803); records 2.1, EXISTING-APPS-GAPS regenerated
gates / gates (push) Successful in 2s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-02 16:54:29 +02:00
admin 96829d0d0f Grimmory and MeTube published behind the family gate (controller >= 0.287.0, decisions 63/64), with complete records
gates / gates (push) Successful in 3s
- family_gate / family_gate_except / min_controller format (README, REUSE); gate family-gate + decoys
- templates/grimmory (v3.5.0, exceptions OPDS/Kobo/KOReader/Komga) + onboarding/grimmory.md
- templates/metube (2026.09.29, no exceptions; ladder .28 -> .29) + onboarding/metube.md; fixture MeTube
- volume-persistence gate: routed port read from the label NAME (R-801, red-proofed); APP_EXERCISE (R-788)
- box_walk: family_cookie; no cached "not gated" while an app has no router

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-02 09:36:49 +02:00
admin de0a9bd29f SparkyFitness onboarding record (Part C: bench + 9202 measured, six rows open — R-786; licence non-commercial — R-784); CHANGELOG/CONTEXT/REPORT for the R-753 catalog work
gates / gates (push) Successful in 2s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-01 22:16:21 +02:00
admin 94477cba43 Grimmory tested but held (R-775): its fixture added; CHANGELOG, CONTEXT, REPORT for the night's new apps
gates / gates (push) Successful in 2s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-01 19:51:12 +02:00
admin dc0ab8b2a8 New-app checklist: reviewed, a gate (onboarding), the wger pilot record, the existing apps' gap page
gates / gates (push) Successful in 2s
NEW-APP-CHECKLIST.md: the reviewer's draft reviewed - 60 rows in 10 groups, each with how/why and a since date;
7 rows added, 16 sharpened, 9 wrong claims fixed. onboarding/_TEMPLATE.md (one line per id), onboarding/wger.md
(the pilot, exempt app, 11 open rows each a register row), onboarding/EXISTING-APPS-GAPS.md (read only, from
scripts/onboarding_gaps.py). Gate onboarding (scripts/check-onboarding.py) in --fast: a template directory not
among the 53 published before 2026-10-01 needs a complete record; decoys in test_gate_decoys.py (16 cases, 5 gate
mutants seen red). CLAUDE.md, REUSE.md 5, README point to it. No template changed.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-01 15:20:52 +02:00
admin 9c5eae9999 CHANGELOG + REPORT: calibre-web generated login name (decision 61); an installed app's template is not frozen (R-757)
gates / gates (push) Successful in 2s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-01 13:29:50 +02:00
admin ed6df4b46b CHANGELOG + REPORT: wger lockout fix, three apps measured (R-752)
gates / gates (push) Successful in 3s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-01 12:49:39 +02:00
admin 83636352ea REPORT: the first full monthly re-test, mealie's lockout, R-744/R-746/R-749
gates / gates (push) Successful in 2s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-01 10:21:00 +02:00
admin efd492d0bb CHANGELOG + REPORT: same-tag re-tests (decision 52), wger's key, wanderer on the bench
gates / gates (push) Successful in 2s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-09-30 23:23:16 +02:00
admin d18116539a CHANGELOG + REPORT: twelve more steps, six first ladders (R-462, R-738, R-742, R-732)
gates / gates (push) Successful in 2s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-09-30 20:26:54 +02:00
admin 4c552cf56b CHANGELOG + REPORT: immich 768M + v3.2.4 (R-732)
gates / gates (push) Successful in 2s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-09-30 16:17:17 +02:00
admin 06e804b824 CHANGELOG + REPORT: the last six PostgreSQL apps, Part F; zipline's fixture tries /api/setup first (R-624)
gates / gates (push) Successful in 2s
zipline 4's first-run route is POST /api/setup (measured on the bench 2026-09-30, v4.6.1: GET ->
{"firstSetup":true}, POST {username,password} -> 200 SUPERADMIN, the login works). The two paths the
fixture tried stay as fallbacks. No image moves in this commit.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-09-30 14:45:02 +02:00
admin 6446197925 Sign-up locked twice (after_setup + case-insensitive blocks); wanderer closable (decision 48); ghost/HA/gramps probes; probe-measured gate; decoy fixture fix
gates / gates (push) Successful in 2s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-09-29 17:00:18 +02:00
admin 6faf432e22 Setup gate on 28 more apps; signup_block on 11 (decision 47); claper R-713 base64; FIRST-ADMIN current
gates / gates (push) Successful in 2s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-09-29 11:08:56 +02:00
admin d0e7e2eb51 Setup gate on immich/n8n/audiobookshelf/uptime-kuma (decision 46); mealie/wger/calibre-web after_install; romm/zipline stale notes; grafana R-708; wger R-712
gates / gates (push) Successful in 2s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-09-29 09:19:05 +02:00
admin a791aae057 FIRST-ADMIN.md: the 53-app first-admin audit (decision 45); CHANGELOG + REPORT
gates / gates (push) Successful in 1s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-09-28 18:59:24 +02:00
admin 82da54415c CHANGELOG + REPORT: calcom 1536M and PostgreSQL 18
gates / gates (push) Successful in 1s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-09-28 11:49:25 +02:00
admin 174a7625bd CHANGELOG + REPORT: claper PostgreSQL 17, calcom inconclusive
gates / gates (push) Successful in 2s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-09-28 10:55:54 +02:00
admin f1a7d6c9fd CHANGELOG + REPORT: paperless-ngx 18, tandoor 17, adventurelog v0.13.0
gates / gates (push) Successful in 2s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-09-27 12:55:35 +02:00
admin 4f19b21e29 REPORT: docmost 16 -> 18, harness v4, the gate's proof clause
gates / gates (push) Successful in 1s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-09-25 14:39:09 +02:00
admin dd9c6ad57b CHANGELOG + REPORT: n8n and mealie moved (night 2026-09-25 Part E)
gates / gates (push) Successful in 1s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-09-25 02:32:41 +02:00
admin c8025093d2 REPORT: step .felhom.yml files (night 2026-09-24)
gates / gates (push) Successful in 2s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-09-24 14:53:58 +02:00
admin 635c7e68f7 REPORT + CONTEXT + CLAUDE.md: step definitions (2026-09-24)
gates / gates (push) Successful in 2s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-09-24 08:52:59 +02:00
admin 585a7cba22 CONTEXT + REPORT: the night shift of 2026-09-23 (test record, 12 steps)
gates / gates (push) Successful in 2s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-09-24 00:23:42 +02:00
admin 6db08a5eb3 test record: an image move must carry its proof (09 decision 13, part 4)
gates / gates (push) Successful in 1s
update_ladder: in .felhom.yml, one JSON entry per line (spiked live on
controller v0.266.0 and v0.267.0 first). Two gates: check-test-record.py
(static, CI too) and check-test-record-move.py (history + registry for
moved refs only). 16 decoys, 3 red-proofs. The ONLY writer is
upgrade-test.py --write-ladder (bench AND box proven, digests resolved).
Harness v3: box fixtures on the bench, files_may_change.
Backfill: the 21 moves of 2026-09-22, 21 proven from their records.
No image: line moved.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-09-23 20:52:32 +02:00
admin cfcfe52784 upgrade-test: watch memory after the readback (harness v2, R-635/R-462)
gates / gates (push) Successful in 2s
After an edge reads back, --soak seconds (default 600) of light load while
the kernel's own oom_kill counter is read host-side from the container's
cgroup. A kill or restart turns proven into failed; a peak over 80% of the
limit adds the memory_tight mark. New Romm fixture; edges M1 / M1old.

Red-proof on scratch 9202: M1old (template as promoted, 512M, 4 workers)
OOM-killed at +76 s -> failed. M1 (current, 768M, 2 workers) proven, 0
kills in 608.5 s, peak 81% -> memory_tight.

Test code only; no template changed.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-09-23 08:54:53 +02:00
admin 4463243f2e Upgrade harness: four fixtures and seven real upstream edges from the update night (R-462)
gates / gates (push) Successful in 1s
Test code only — no template changed and no image: line moved.

The update night walked real within-a-major upstream edges on scratch guest 9202 through the
product's own guarded Update, against a PRIVATE DRILL CATALOG; the live catalog was never
touched. This brings the expensive half of that work — the seed routes — back into the harness
so the same edges can be run here WITH their ABORT step, which the box deliberately does not
offer (09 6.1: whether the old image starts on migrated data is per-app and unpredictable).

- upgrade_fixtures.py: ActualBudget, Navidrome, AudiobookShelf, Vikunja. Each seeds through the
  app's OWN interface (R-156); each carries a negative control run on every verify(), so a
  readback that has broken into always succeeding fails instead of passing everything.
- upgrade-test.py: edges U1..U7, all real upstream moves existing 2026-09-21 that this catalog
  has NOT made, each holding its database engine constant.
- Limitations kept: Navidrome and AudiobookShelf seed the DATABASE half only, and say so.

OWED, stated so it is not mistaken for done: the U1..U7 harness RUNS, and with them the per-app
ABORT answers. The code is in; the runs are not.

Gates: catalog_gates.py --fast — image-pins, engine-major, catalog-since, copy-i18n all OK.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-09-21 21:00:50 +02:00
admin bd22749e50 REPORT for the R-469 rule lift
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-21 12:59:35 +02:00
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 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 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 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 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 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 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 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 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 122bbeea48 papra: mount the volume where the app actually writes (R-156, last leg)
gates / gates (push) Successful in 1s
papra mounted papra_data:/app/data while the application writes to
/app/app-data, so its database sat in the container's writable layer: lost on
redeploy, and tarred nightly as an empty directory while the healthcheck stayed
green. Last of the three apps R-156 convicted.

Decided from the IMAGE, not the README. docker inspect of
ghcr.io/papra-hq/papra:26.6.1-rootless gives WORKDIR=/app and all three data
paths under ./app-data (DATABASE_URL, DOCUMENT_STORAGE_FILESYSTEM_ROOT,
PAPRA_CONFIG_DIR) — and /app/data does not exist in the image at all.

Reconfiguring the app to write to /app/data was available and deliberately not
taken: it enumerates data paths, so a fourth added upstream would escape to the
writable layer again, silently — this defect re-armed. Mounting the app's own
data ROOT captures every current and future path by construction.

Precondition checked rather than inherited: docker ps -a (including stopped) on
BOTH demo guests, plus the hub fleet view (two enrolled hosts, zero papra) —
both boxes were wiped and rebuilt today, so the 2 August evidence was re-measured.

Proven by the runtime gate in both directions: CLEAN with the self-test passing,
and BROKEN when the mount is reverted, with the exact R-156 evidence. Full
catalog_gates.py papra: all three gates OK.
2026-08-03 11:29:51 +02:00
admin 7cb58ecdf8 docs: CHANGELOG + REPORT for the CI workflow
gates / gates (push) Successful in 1s
2026-08-02 16:35:45 +02:00
admin f16f29757e REPORT: catalog_gates --fast + pre-push hook 2026-08-02 15:37:11 +02:00
admin fd7747d129 catalog gates: one entry point, mandated in CLAUDE.md (R-161 ruling)
scripts/catalog_gates.py runs all three gates - image-pins, image-resolvable,
volume-persistence - and exits non-zero if any fails. Mandated in CLAUDE.md the way
felhom.eu/scripts/site_gates.py is: run it after any template change, naming the
app(s) you touched.

Operator ruling, recorded because both alternatives were rejected for measured
reasons. Controller-side enforcement at template load was rejected because such a
check can only read the file, and a static audit of all 53 templates reports the
catalog clean INCLUDING papra - it would pass on the exact defect it exists to
catch; the property is decidable only at runtime. CI was rejected for now: neither
repo has any, and there are no users yet. What was chosen copies the shape that
demonstrably works here - of this project's gates, the only ones that ever get run
are the ones with a single entry point named in a CLAUDE.md; site_gates.py is run,
and R-29's three orphans are named nowhere and have stopped nothing.

Behaviour: 0 all clean / 1 convicted / 2 UNDETERMINED, never a pass; a conviction
outranks an undetermined result so the reader knows which they have. Gate output is
streamed, not captured. App names scope the two gates that accept scoping; with no
names the runtime gate deploys every template and belongs on a scratch host.
Adding a fourth gate means one line in GATES.

R-161 stays OPEN at reduced scope: this is convention, run by a person. Real
automatic enforcement is owed when a second person touches templates.

Verified: image-pins passes standalone (53 templates, 0 unpinned), the
unknown-option path exits 2, and the aggregation was unit-checked over five
gate-code combinations. The runtime leg was deliberately NOT executed - it deploys
templates via docker compose and DooPlex is the recovery chain - so the runner's
end-to-end invocation of that third gate is inferred, not measured, and is flagged
in REPORT.md to be closed on a scratch host at the next campaign.

REPORT.md overwritten per convention; the persistence sweep's report is preserved
at audits/persistence-sweep-2026-08-02/ and pointed to from the new one.
2026-08-02 14:03:55 +02:00
admin 6d45b60f94 persistence sweep: renumber proposed findings R-159..R-162 (R-158 collided mid-session)
The register grep that put these at R-158..R-161 was true when run and stale within hours: the
parallel session pushed SPIKE-recovery-unit-space-2026-08-02.md and CAMPAIGN-10-closeout-2026-08-02.md
mid-run, both using R-158 for an unrelated finding, and neither files it — ROADMAP.md and
OPEN-ITEMS.md still stop at R-155.

So two sessions minted the same number for different findings on the same day, which is the exact
failure §8.0 was already documenting about R-154/R-155 and R-156/R-157. Now recorded with itself as
the third instance. R-156, R-157 and R-158 are all live in audit documents and none is filed.
2026-08-02 12:24:48 +02:00
admin acb44672fd persistence sweep: teardown complete (all 3 layers) + papra referral updated
Layer 1: guest 9301 destroyed, vm-9301-disk-0 removed, pct list clean.
Layer 2: local-lvm available returned to 258 702 410 KiB — EXACTLY the pre-run baseline (29.27%).
Layer 3: no hub record was ever created (the scratch guest ran no controller and was never
enrolled, by design); confirmed absent from /configs and /hosts after teardown.

papra referral updated: c10-soak was torn down by the other session mid-run and papra disappeared
from hub telemetry with grafana, homebox and rallly — Campaign 10's four discriminator apps (§A4).
So papra's one deployment was on c10-soak. The fix is STILL not applied: that is absence evidence,
demo-hp is fenced, and applying it wrongly is irreversible while leaving it is a one-line push.
The single command that settles it is recorded.
2026-08-02 12:23:40 +02:00