Decisions 149-150 recorded; instruction files kept true; R-890, R-891, R-644 closed, R-469 narrowed (142 -> 139)
gates / gates (push) Successful in 2m38s

Decision 150 (operator 13:25): sessions correct stale facts in instruction files themselves,
naming each edit; never loosen a rule. Added to unprompted-work.md §5 (all copies) and
PROMPT-TEMPLATE.md §9. CLAUDE.md gates paragraph (R-891), architecture pointer, docs/website
rules, the doubled R-286 sentence in the workspace CLAUDE.md.
Decision 149: vaultwarden's step proven on bench 9401 and box 9202 (evidence here).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
2026-10-06 13:52:28 +02:00
parent 7d0dffcf34
commit a29ee9dd33
31 changed files with 1244 additions and 18 deletions
@@ -0,0 +1,11 @@
Tue Oct 6 11:47:10 UTC 2026
== all containers
filebrowser Up 5 hours (healthy)
felhom-controller Up 6 minutes (healthy)
paperless-webserver Up 11 hours (healthy)
paperless-postgres Up 11 hours (healthy)
paperless-redis Up 11 hours (healthy)
traefik Up 28 hours
== gokapi
0
0
@@ -0,0 +1,23 @@
# 2026-10-06 (afternoon) — instruction files kept true; vaultwarden on the update ladder (R-890, R-891)
Rulings: `09` §3 decisions 149 (the admin seed on the test boxes) and 150 (instruction files kept true by the session).
## Part B — vaultwarden 1.36.0-alpine → 1.37.4-alpine, both venues
| venue | result | file |
|---|---|---|
| bench LXC 9401 (demo-hp), harness v5, `FELHOM_BENCH_ADMIN_SEED=1`, 600 s memory watch | **proven**: seed read back before and after, healthy in 30.9 s, anon peak 16.3 % (cgroup 22.3 %), 0 kills, 0 restarts, no file changed | `bench/R890-vw.log`, `bench/evidence/MV-vaultwarden/verdict.json` |
| scratch guest 9202 (drill catalog), `FELHOM_BOX_ADMIN_SEED=1` | **proven**: a fresh install; self-registration 400 (closed by design); the admin sign-in and invite INSIDE the box → (200, session yes, 200); invited registration 200; seed read back; the guarded Update backing-up → pulling → copying → verifying → done in 12.3 s; seed read back; badge „Frissítés elérhető — 80 napja" before, „Naprakész" after; removed through the product (no container, no volume left) | `box/vaultwarden/step.txt`, `box/vaultwarden/box-verdict-vaultwarden.json`, `box/run.out` |
Written to the live catalog by `upgrade-test.py --write-ladder` (catalog `ecb8552`). The tool: `tools/vwstep.py` (one
process, so the install and the seed are the same run — the guard requires that). 9202 pointed at the drill:
`box/C1-repoint-drill.txt`.
**Secrets:** the admin token was never on DooPlex — the box read it from the container's environment and handed it to
curl on stdin; only HTTP codes came back. Scan of `bench/` and `box/` for 48+ hex characters, `VW_ADMIN=` and
`ADMIN_TOKEN=` values: 0 hits; control: a fresh 64-hex line → 1 hit. The bench's run `.env` is gone (shredded by the
harness); the bench has 0 containers and is stopped.
## Part C
- R-644: `C/R-644-9202-live.txt` — no gokapi on 9202 any more.
@@ -0,0 +1,115 @@
[11:37:33] scratch drive folders cleared before FROM (R-656): none existed
[11:37:33] MV-vaultwarden: deploying vaultwarden at FROM {'vaultwarden': 'vaultwarden/server:1.36.0-alpine'}
[11:38:04] FROM settled=True in 30.9s :: {"vaultwarden": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}}
[11:38:04] fixture: the BOX walk's own (Vaultwarden), through upgrade_boxport
[11:38:04] vaultwarden: self-registration http=400 (closed by design, R-512 — 400 expected)
[11:38:04] vaultwarden: bench admin sign-in http=200 session=yes
[11:38:04] vaultwarden: bench admin invite http=200
[11:38:05] vaultwarden: invited registration http=200
[11:38:05] vaultwarden: token for the seeded account http=200 ok=True
[11:38:05] C1 (seed reads back BEFORE): True
[11:38:05] MV-vaultwarden: swapping to TO {'vaultwarden': 'vaultwarden/server:1.37.4-alpine'}
[11:38:12] TO up -d rc=0
[11:38:43] TO settled=True in 30.9s :: {"vaultwarden": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}}
[11:38:43] migration lines observed: 0
[11:38:44] vaultwarden: token for the seeded account http=200 ok=True
[11:38:44] RESULT (seed reads back AFTER): True
[11:38:44] memory watch: 600s, 4 callers on 1 path(s) at 172.18.0.2:80
[11:38:59] + 15s vaultwarden=44M/256M peak=45M kills=0 rs=0 reqs=300
[11:39:14] + 30s vaultwarden=44M/256M peak=46M kills=0 rs=0 reqs=600
[11:39:29] + 45s vaultwarden=45M/256M peak=46M kills=0 rs=0 reqs=900
[11:39:45] + 60s vaultwarden=47M/256M peak=49M kills=0 rs=0 reqs=1200
[11:40:00] + 76s vaultwarden=47M/256M peak=49M kills=0 rs=0 reqs=1500
[11:40:15] + 91s vaultwarden=47M/256M peak=49M kills=0 rs=0 reqs=1800
[11:40:30] + 106s vaultwarden=47M/256M peak=49M kills=0 rs=0 reqs=2100
[11:40:45] + 121s vaultwarden=47M/256M peak=49M kills=0 rs=0 reqs=2400
[11:41:00] + 136s vaultwarden=47M/256M peak=49M kills=0 rs=0 reqs=2700
[11:41:15] + 151s vaultwarden=47M/256M peak=49M kills=0 rs=0 reqs=2996
[11:41:30] + 166s vaultwarden=47M/256M peak=49M kills=0 rs=0 reqs=3296
[11:41:46] + 182s vaultwarden=47M/256M peak=50M kills=0 rs=0 reqs=3596
[11:42:01] + 197s vaultwarden=47M/256M peak=50M kills=0 rs=0 reqs=3896
[11:42:16] + 212s vaultwarden=48M/256M peak=51M kills=0 rs=0 reqs=4196
[11:42:31] + 227s vaultwarden=49M/256M peak=51M kills=0 rs=0 reqs=4496
[11:42:46] + 242s vaultwarden=50M/256M peak=51M kills=0 rs=0 reqs=4796
[11:43:01] + 257s vaultwarden=49M/256M peak=51M kills=0 rs=0 reqs=5096
[11:43:16] + 272s vaultwarden=50M/256M peak=51M kills=0 rs=0 reqs=5396
[11:43:31] + 287s vaultwarden=49M/256M peak=51M kills=0 rs=0 reqs=5696
[11:43:47] + 303s vaultwarden=52M/256M peak=54M kills=0 rs=0 reqs=5996
[11:44:02] + 318s vaultwarden=51M/256M peak=54M kills=0 rs=0 reqs=6292
[11:44:17] + 333s vaultwarden=51M/256M peak=54M kills=0 rs=0 reqs=6592
[11:44:32] + 348s vaultwarden=52M/256M peak=54M kills=0 rs=0 reqs=6892
[11:44:47] + 363s vaultwarden=53M/256M peak=55M kills=0 rs=0 reqs=7192
[11:45:02] + 378s vaultwarden=53M/256M peak=55M kills=0 rs=0 reqs=7492
[11:45:17] + 393s vaultwarden=53M/256M peak=55M kills=0 rs=0 reqs=7792
[11:45:32] + 408s vaultwarden=53M/256M peak=55M kills=0 rs=0 reqs=8092
[11:45:48] + 424s vaultwarden=54M/256M peak=56M kills=0 rs=0 reqs=8392
[11:46:03] + 439s vaultwarden=54M/256M peak=56M kills=0 rs=0 reqs=8692
[11:46:18] + 454s vaultwarden=54M/256M peak=56M kills=0 rs=0 reqs=8992
[11:46:33] + 469s vaultwarden=54M/256M peak=56M kills=0 rs=0 reqs=9292
[11:46:48] + 484s vaultwarden=55M/256M peak=56M kills=0 rs=0 reqs=9589
[11:47:03] + 499s vaultwarden=54M/256M peak=56M kills=0 rs=0 reqs=9889
[11:47:18] + 514s vaultwarden=54M/256M peak=56M kills=0 rs=0 reqs=10189
[11:47:34] + 530s vaultwarden=55M/256M peak=56M kills=0 rs=0 reqs=10489
[11:47:49] + 545s vaultwarden=54M/256M peak=56M kills=0 rs=0 reqs=10789
[11:48:04] + 560s vaultwarden=54M/256M peak=56M kills=0 rs=0 reqs=11089
[11:48:19] + 575s vaultwarden=55M/256M peak=56M kills=0 rs=0 reqs=11389
[11:48:34] + 590s vaultwarden=54M/256M peak=56M kills=0 rs=0 reqs=11689
[11:48:49] + 605s vaultwarden=55M/256M peak=56M kills=0 rs=0 reqs=11989
[11:48:50] memory watch: killed=False tight=[] requests=11989 codes={'200': 11989}
[11:48:50] MV-vaultwarden: ABORT — putting the FROM images back
[11:49:21] vaultwarden: token for the seeded account http=200 ok=True
[11:49:21] ABORT: app came back in 30.9s; data present=True
{
"harness_version": 5,
"edge": "MV-vaultwarden",
"app": "vaultwarden",
"note": "night 2026-09-23 within-a-major move: vaultwarden=vaultwarden/server:1.37.4-alpine",
"from": {
"vaultwarden": "vaultwarden/server:1.36.0-alpine"
},
"to": {
"vaultwarden": "vaultwarden/server:1.37.4-alpine"
},
"verdict": "proven",
"seed_read_before": true,
"seed_read_after": true,
"healthy_after": true,
"migration_observed": null,
"abort": "starts-and-serves",
"abort_detail": null,
"engine_state_after": null,
"memory": {
"soak_s": 605.5,
"requested_s": 600,
"requests": 11989,
"codes": {
"200": 11989
},
"first_kill": null,
"containers": {
"vaultwarden": {
"limit": 268435456,
"peak": 59731968,
"peak_pct": 0.223,
"anon_peak_sampled": 43720704,
"anon_peak_pct": 0.163,
"oom_kills": 0,
"restarts": 0,
"oomkilled_flag": false,
"measured": true
}
},
"unmeasured": [],
"load": "reached"
},
"marks": [],
"bench_overrides": null,
"duration_s": 30.9,
"measured_at": "2026-10-06T11:49:21Z",
"evidence": "evidence/MV-vaultwarden",
"scratch_cleared": [],
"files_changed": [],
"files_changed_detail": [],
"files_ignored": [],
"total_s": 708.8
}
@@ -0,0 +1,8 @@
{
"vaultwarden": {
"status": "running",
"health": "healthy",
"restarts": 0,
"exit": 0
}
}
@@ -0,0 +1,26 @@
vaultwarden | /--------------------------------------------------------------------\
vaultwarden | | Starting Vaultwarden |
vaultwarden | | Version 1.36.0 |
vaultwarden | |--------------------------------------------------------------------|
vaultwarden | | This is an *unofficial* Bitwarden implementation, DO NOT use the |
vaultwarden | | official channels to report bugs/features, regardless of client. |
vaultwarden | | Send usage/configuration questions or feature requests to: |
vaultwarden | | https://github.com/dani-garcia/vaultwarden/discussions or |
vaultwarden | | https://vaultwarden.discourse.group/ |
vaultwarden | | Report suspected bugs/issues in the software itself at: |
vaultwarden | | https://github.com/dani-garcia/vaultwarden/issues/new |
vaultwarden | \--------------------------------------------------------------------/
vaultwarden |
vaultwarden | [NOTICE] You are using a plain text `ADMIN_TOKEN` which is insecure.
vaultwarden | Please generate a secure Argon2 PHC string by using `vaultwarden hash` or `argon2`.
vaultwarden | See: https://github.com/dani-garcia/vaultwarden/wiki/Enabling-admin-page#secure-the-admin_token
vaultwarden |
vaultwarden | [2026-10-06 13:48:50.671][start][INFO] Rocket has launched from http://0.0.0.0:80
vaultwarden | [2026-10-06 13:49:21.529][request][INFO] POST /identity/connect/token
vaultwarden | [2026-10-06 13:49:21.529][auth][ERROR] Unauthorized Error: No Bitwarden-Client-Version header provided
vaultwarden | [2026-10-06 13:49:21.689][vaultwarden::api::identity][ERROR] Username or password is incorrect. Try again. IP: 172.18.0.1. Username: drill-d12fe8d2@gate.invalid.
vaultwarden | [2026-10-06 13:49:21.689][response][INFO] (login) POST /identity/connect/token => 400 Bad Request
vaultwarden | [2026-10-06 13:49:21.724][request][INFO] POST /identity/connect/token
vaultwarden | [2026-10-06 13:49:21.724][auth][ERROR] Unauthorized Error: No Bitwarden-Client-Version header provided
vaultwarden | [2026-10-06 13:49:21.879][vaultwarden::api::identity][INFO] User drill logged in successfully. IP: 172.18.0.1
vaultwarden | [2026-10-06 13:49:21.879][response][INFO] (login) POST /identity/connect/token => 200 OK
@@ -0,0 +1,682 @@
[
{
"t": 15.1,
"containers": {
"vaultwarden": {
"limit": 268435456,
"current": 46456832,
"peak": 47407104,
"anon": 38027264,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 300
},
{
"t": 30.3,
"containers": {
"vaultwarden": {
"limit": 268435456,
"current": 46735360,
"peak": 49123328,
"anon": 38473728,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 600
},
{
"t": 45.4,
"containers": {
"vaultwarden": {
"limit": 268435456,
"current": 47403008,
"peak": 49123328,
"anon": 38641664,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 900
},
{
"t": 60.5,
"containers": {
"vaultwarden": {
"limit": 268435456,
"current": 49934336,
"peak": 52183040,
"anon": 40976384,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 1200
},
{
"t": 75.7,
"containers": {
"vaultwarden": {
"limit": 268435456,
"current": 49467392,
"peak": 52183040,
"anon": 40087552,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 1500
},
{
"t": 90.8,
"containers": {
"vaultwarden": {
"limit": 268435456,
"current": 49885184,
"peak": 52183040,
"anon": 40316928,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 1800
},
{
"t": 105.9,
"containers": {
"vaultwarden": {
"limit": 268435456,
"current": 49991680,
"peak": 52183040,
"anon": 40300544,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 2100
},
{
"t": 121.1,
"containers": {
"vaultwarden": {
"limit": 268435456,
"current": 49860608,
"peak": 52183040,
"anon": 40488960,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 2400
},
{
"t": 136.2,
"containers": {
"vaultwarden": {
"limit": 268435456,
"current": 49836032,
"peak": 52183040,
"anon": 39841792,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 2700
},
{
"t": 151.3,
"containers": {
"vaultwarden": {
"limit": 268435456,
"current": 50278400,
"peak": 52183040,
"anon": 40030208,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 2996
},
{
"t": 166.4,
"containers": {
"vaultwarden": {
"limit": 268435456,
"current": 49954816,
"peak": 52183040,
"anon": 39927808,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 3296
},
{
"t": 181.6,
"containers": {
"vaultwarden": {
"limit": 268435456,
"current": 50135040,
"peak": 52711424,
"anon": 40226816,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 3596
},
{
"t": 196.7,
"containers": {
"vaultwarden": {
"limit": 268435456,
"current": 49827840,
"peak": 52711424,
"anon": 39620608,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 3896
},
{
"t": 211.8,
"containers": {
"vaultwarden": {
"limit": 268435456,
"current": 51314688,
"peak": 54259712,
"anon": 40148992,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 4196
},
{
"t": 226.9,
"containers": {
"vaultwarden": {
"limit": 268435456,
"current": 51630080,
"peak": 54259712,
"anon": 40075264,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 4496
},
{
"t": 242.1,
"containers": {
"vaultwarden": {
"limit": 268435456,
"current": 52629504,
"peak": 54259712,
"anon": 40218624,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 4796
},
{
"t": 257.2,
"containers": {
"vaultwarden": {
"limit": 268435456,
"current": 52166656,
"peak": 54259712,
"anon": 39854080,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 5096
},
{
"t": 272.3,
"containers": {
"vaultwarden": {
"limit": 268435456,
"current": 52514816,
"peak": 54259712,
"anon": 39993344,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 5396
},
{
"t": 287.4,
"containers": {
"vaultwarden": {
"limit": 268435456,
"current": 51990528,
"peak": 54259712,
"anon": 40095744,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 5696
},
{
"t": 302.6,
"containers": {
"vaultwarden": {
"limit": 268435456,
"current": 54804480,
"peak": 57143296,
"anon": 42119168,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 5996
},
{
"t": 317.7,
"containers": {
"vaultwarden": {
"limit": 268435456,
"current": 53960704,
"peak": 57143296,
"anon": 42205184,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 6292
},
{
"t": 332.8,
"containers": {
"vaultwarden": {
"limit": 268435456,
"current": 53817344,
"peak": 57143296,
"anon": 41398272,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 6592
},
{
"t": 347.9,
"containers": {
"vaultwarden": {
"limit": 268435456,
"current": 54542336,
"peak": 57143296,
"anon": 41426944,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 6892
},
{
"t": 363.1,
"containers": {
"vaultwarden": {
"limit": 268435456,
"current": 56356864,
"peak": 58667008,
"anon": 43720704,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 7192
},
{
"t": 378.2,
"containers": {
"vaultwarden": {
"limit": 268435456,
"current": 56516608,
"peak": 58667008,
"anon": 43200512,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 7492
},
{
"t": 393.3,
"containers": {
"vaultwarden": {
"limit": 268435456,
"current": 56545280,
"peak": 58667008,
"anon": 43233280,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 7792
},
{
"t": 408.4,
"containers": {
"vaultwarden": {
"limit": 268435456,
"current": 56168448,
"peak": 58667008,
"anon": 42938368,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 8092
},
{
"t": 423.6,
"containers": {
"vaultwarden": {
"limit": 268435456,
"current": 56717312,
"peak": 58896384,
"anon": 43270144,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 8392
},
{
"t": 438.7,
"containers": {
"vaultwarden": {
"limit": 268435456,
"current": 57171968,
"peak": 58896384,
"anon": 42594304,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 8692
},
{
"t": 453.9,
"containers": {
"vaultwarden": {
"limit": 268435456,
"current": 57262080,
"peak": 58896384,
"anon": 42614784,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 8992
},
{
"t": 469.0,
"containers": {
"vaultwarden": {
"limit": 268435456,
"current": 57131008,
"peak": 58896384,
"anon": 42680320,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 9292
},
{
"t": 484.1,
"containers": {
"vaultwarden": {
"limit": 268435456,
"current": 57974784,
"peak": 59424768,
"anon": 42905600,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 9589
},
{
"t": 499.3,
"containers": {
"vaultwarden": {
"limit": 268435456,
"current": 57352192,
"peak": 59424768,
"anon": 42680320,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 9889
},
{
"t": 514.4,
"containers": {
"vaultwarden": {
"limit": 268435456,
"current": 56872960,
"peak": 59424768,
"anon": 42700800,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 10189
},
{
"t": 529.5,
"containers": {
"vaultwarden": {
"limit": 268435456,
"current": 57950208,
"peak": 59424768,
"anon": 42795008,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 10489
},
{
"t": 544.7,
"containers": {
"vaultwarden": {
"limit": 268435456,
"current": 57360384,
"peak": 59424768,
"anon": 43061248,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 10789
},
{
"t": 559.8,
"containers": {
"vaultwarden": {
"limit": 268435456,
"current": 57270272,
"peak": 59424768,
"anon": 42733568,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 11089
},
{
"t": 574.9,
"containers": {
"vaultwarden": {
"limit": 268435456,
"current": 57892864,
"peak": 59731968,
"anon": 42790912,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 11389
},
{
"t": 590.1,
"containers": {
"vaultwarden": {
"limit": 268435456,
"current": 56963072,
"peak": 59731968,
"anon": 42803200,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 11689
},
{
"t": 605.2,
"containers": {
"vaultwarden": {
"limit": 268435456,
"current": 58019840,
"peak": 59731968,
"anon": 43212800,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 11989
}
]
@@ -0,0 +1,61 @@
[11:37:33] scratch drive folders cleared before FROM (R-656): none existed
[11:37:33] MV-vaultwarden: deploying vaultwarden at FROM {'vaultwarden': 'vaultwarden/server:1.36.0-alpine'}
[11:38:04] FROM settled=True in 30.9s :: {"vaultwarden": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}}
[11:38:04] fixture: the BOX walk's own (Vaultwarden), through upgrade_boxport
[11:38:04] vaultwarden: self-registration http=400 (closed by design, R-512 — 400 expected)
[11:38:04] vaultwarden: bench admin sign-in http=200 session=yes
[11:38:04] vaultwarden: bench admin invite http=200
[11:38:05] vaultwarden: invited registration http=200
[11:38:05] vaultwarden: token for the seeded account http=200 ok=True
[11:38:05] C1 (seed reads back BEFORE): True
[11:38:05] MV-vaultwarden: swapping to TO {'vaultwarden': 'vaultwarden/server:1.37.4-alpine'}
[11:38:12] TO up -d rc=0
[11:38:43] TO settled=True in 30.9s :: {"vaultwarden": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}}
[11:38:43] migration lines observed: 0
[11:38:44] vaultwarden: token for the seeded account http=200 ok=True
[11:38:44] RESULT (seed reads back AFTER): True
[11:38:44] memory watch: 600s, 4 callers on 1 path(s) at 172.18.0.2:80
[11:38:59] + 15s vaultwarden=44M/256M peak=45M kills=0 rs=0 reqs=300
[11:39:14] + 30s vaultwarden=44M/256M peak=46M kills=0 rs=0 reqs=600
[11:39:29] + 45s vaultwarden=45M/256M peak=46M kills=0 rs=0 reqs=900
[11:39:45] + 60s vaultwarden=47M/256M peak=49M kills=0 rs=0 reqs=1200
[11:40:00] + 76s vaultwarden=47M/256M peak=49M kills=0 rs=0 reqs=1500
[11:40:15] + 91s vaultwarden=47M/256M peak=49M kills=0 rs=0 reqs=1800
[11:40:30] + 106s vaultwarden=47M/256M peak=49M kills=0 rs=0 reqs=2100
[11:40:45] + 121s vaultwarden=47M/256M peak=49M kills=0 rs=0 reqs=2400
[11:41:00] + 136s vaultwarden=47M/256M peak=49M kills=0 rs=0 reqs=2700
[11:41:15] + 151s vaultwarden=47M/256M peak=49M kills=0 rs=0 reqs=2996
[11:41:30] + 166s vaultwarden=47M/256M peak=49M kills=0 rs=0 reqs=3296
[11:41:46] + 182s vaultwarden=47M/256M peak=50M kills=0 rs=0 reqs=3596
[11:42:01] + 197s vaultwarden=47M/256M peak=50M kills=0 rs=0 reqs=3896
[11:42:16] + 212s vaultwarden=48M/256M peak=51M kills=0 rs=0 reqs=4196
[11:42:31] + 227s vaultwarden=49M/256M peak=51M kills=0 rs=0 reqs=4496
[11:42:46] + 242s vaultwarden=50M/256M peak=51M kills=0 rs=0 reqs=4796
[11:43:01] + 257s vaultwarden=49M/256M peak=51M kills=0 rs=0 reqs=5096
[11:43:16] + 272s vaultwarden=50M/256M peak=51M kills=0 rs=0 reqs=5396
[11:43:31] + 287s vaultwarden=49M/256M peak=51M kills=0 rs=0 reqs=5696
[11:43:47] + 303s vaultwarden=52M/256M peak=54M kills=0 rs=0 reqs=5996
[11:44:02] + 318s vaultwarden=51M/256M peak=54M kills=0 rs=0 reqs=6292
[11:44:17] + 333s vaultwarden=51M/256M peak=54M kills=0 rs=0 reqs=6592
[11:44:32] + 348s vaultwarden=52M/256M peak=54M kills=0 rs=0 reqs=6892
[11:44:47] + 363s vaultwarden=53M/256M peak=55M kills=0 rs=0 reqs=7192
[11:45:02] + 378s vaultwarden=53M/256M peak=55M kills=0 rs=0 reqs=7492
[11:45:17] + 393s vaultwarden=53M/256M peak=55M kills=0 rs=0 reqs=7792
[11:45:32] + 408s vaultwarden=53M/256M peak=55M kills=0 rs=0 reqs=8092
[11:45:48] + 424s vaultwarden=54M/256M peak=56M kills=0 rs=0 reqs=8392
[11:46:03] + 439s vaultwarden=54M/256M peak=56M kills=0 rs=0 reqs=8692
[11:46:18] + 454s vaultwarden=54M/256M peak=56M kills=0 rs=0 reqs=8992
[11:46:33] + 469s vaultwarden=54M/256M peak=56M kills=0 rs=0 reqs=9292
[11:46:48] + 484s vaultwarden=55M/256M peak=56M kills=0 rs=0 reqs=9589
[11:47:03] + 499s vaultwarden=54M/256M peak=56M kills=0 rs=0 reqs=9889
[11:47:18] + 514s vaultwarden=54M/256M peak=56M kills=0 rs=0 reqs=10189
[11:47:34] + 530s vaultwarden=55M/256M peak=56M kills=0 rs=0 reqs=10489
[11:47:49] + 545s vaultwarden=54M/256M peak=56M kills=0 rs=0 reqs=10789
[11:48:04] + 560s vaultwarden=54M/256M peak=56M kills=0 rs=0 reqs=11089
[11:48:19] + 575s vaultwarden=55M/256M peak=56M kills=0 rs=0 reqs=11389
[11:48:34] + 590s vaultwarden=54M/256M peak=56M kills=0 rs=0 reqs=11689
[11:48:49] + 605s vaultwarden=55M/256M peak=56M kills=0 rs=0 reqs=11989
[11:48:50] memory watch: killed=False tight=[] requests=11989 codes={'200': 11989}
[11:48:50] MV-vaultwarden: ABORT — putting the FROM images back
[11:49:21] vaultwarden: token for the seeded account http=200 ok=True
[11:49:21] ABORT: app came back in 30.9s; data present=True
@@ -0,0 +1,18 @@
vaultwarden | /--------------------------------------------------------------------\
vaultwarden | | Starting Vaultwarden |
vaultwarden | | Version 1.37.4 |
vaultwarden | |--------------------------------------------------------------------|
vaultwarden | | This is an *unofficial* Bitwarden implementation, DO NOT use the |
vaultwarden | | official channels to report bugs/features, regardless of client. |
vaultwarden | | Send usage/configuration questions or feature requests to: |
vaultwarden | | https://github.com/dani-garcia/vaultwarden/discussions or |
vaultwarden | | https://vaultwarden.discourse.group/ |
vaultwarden | | Report suspected bugs/issues in the software itself at: |
vaultwarden | | https://github.com/dani-garcia/vaultwarden/issues/new |
vaultwarden | \--------------------------------------------------------------------/
vaultwarden |
vaultwarden | [NOTICE] You are using a plain text `ADMIN_TOKEN` which is insecure.
vaultwarden | Please generate a secure Argon2 PHC string by using `vaultwarden hash` or `argon2`.
vaultwarden | See: https://github.com/dani-garcia/vaultwarden/wiki/Enabling-admin-page#secure-the-admin_token
vaultwarden |
vaultwarden | [2026-10-06 13:38:12.635][start][INFO] Rocket has launched from http://0.0.0.0:80
@@ -0,0 +1,8 @@
{
"vaultwarden": {
"status": "running",
"health": "healthy",
"restarts": 0,
"exit": 0
}
}
@@ -0,0 +1,54 @@
{
"harness_version": 5,
"edge": "MV-vaultwarden",
"app": "vaultwarden",
"note": "night 2026-09-23 within-a-major move: vaultwarden=vaultwarden/server:1.37.4-alpine",
"from": {
"vaultwarden": "vaultwarden/server:1.36.0-alpine"
},
"to": {
"vaultwarden": "vaultwarden/server:1.37.4-alpine"
},
"verdict": "proven",
"seed_read_before": true,
"seed_read_after": true,
"healthy_after": true,
"migration_observed": null,
"abort": "starts-and-serves",
"abort_detail": null,
"engine_state_after": null,
"memory": {
"soak_s": 605.5,
"requested_s": 600,
"requests": 11989,
"codes": {
"200": 11989
},
"first_kill": null,
"containers": {
"vaultwarden": {
"limit": 268435456,
"peak": 59731968,
"peak_pct": 0.223,
"anon_peak_sampled": 43720704,
"anon_peak_pct": 0.163,
"oom_kills": 0,
"restarts": 0,
"oomkilled_flag": false,
"measured": true
}
},
"unmeasured": [],
"load": "reached"
},
"marks": [],
"bench_overrides": null,
"duration_s": 30.9,
"measured_at": "2026-10-06T11:49:21Z",
"evidence": "evidence/MV-vaultwarden",
"scratch_cleared": [],
"files_changed": [],
"files_changed_detail": [],
"files_ignored": [],
"total_s": 708.8
}
@@ -0,0 +1,2 @@
26: repo_url: https://gitea.dooplex.hu/admin/app-catalog-drill.git
@@ -0,0 +1,18 @@
{
"app": "vaultwarden",
"venue": "box 9202 (drill catalog), the product's guarded Update; seeded through the admin invite inside the box (R-890)",
"from": {
"vaultwarden": "vaultwarden/server:1.36.0-alpine"
},
"to": {
"vaultwarden": "vaultwarden/server:1.37.4-alpine"
},
"verdict": "proven",
"seed_read_before": true,
"seed_read_after": true,
"healthy_after": true,
"duration_s": 12.3,
"final_phase": "done",
"measured_at": "2026-10-06T11:41:48Z",
"evidence": "felhom.eu/documentation/audits/r890-instructions-2026-10-06/box/vaultwarden/step.txt"
}
@@ -0,0 +1,37 @@
vaultwarden: self-registration http=400 (closed by design, R-512 — 400 expected)
vaultwarden: test-box admin sign-in and invite (inside the box) -> ('200', 'yes', '200')
vaultwarden: invited registration http=200
vaultwarden: token for the seeded account http=200 ok=True
C1 seed reads back BEFORE: True
before: pinned={'vaultwarden': 'vaultwarden/server:1.36.0-alpine'}
drill: a603087 DRILL vaultwarden: vaultwarden/server:1.36.0-alpine -> vaultwarden/server:1.37.4-alpine (box proof, R-890)
badge before: {'hu': [{'title': 'Újabb változat érhető el ehhez az alkalmazáshoz. A frissítés indításához nyomd meg a Frissítés gombot.', 'text': 'Frissítés elérhető — 80 napja'}], 'en': [{'title': 'A newer version of this app is available. Select the Update button to start it.', 'text': 'Update available — 80 days ago'}]}
phase +0.0s backing-up | err=None
phase +2.1s pulling | err=None
phase +6.2s copying | err=None
phase +7.2s verifying | err=None
phase +12.3s done | err=None
vaultwarden: token for the seeded account http=200 ok=True
2026/10/06 11:41:50 update.go:537: [INFO] [stacks] update vaultwarden: accepted — guarded update started
2026/10/06 11:41:50 update.go:1377: [INFO] [stacks] update vaultwarden: phase checking
2026/10/06 11:41:50 update.go:795: [INFO] [stacks] update vaultwarden: ladder — the last step (1 of 1) — the catalog's current definition
2026/10/06 11:41:50 update.go:825: [INFO] [stacks] update vaultwarden: no usable copy on any tier — younger than 24h0m0s and not older than this install's deploy (2026-10-06T11:41:17Z) (found: none) — backing up first
2026/10/06 11:41:50 update.go:1377: [INFO] [stacks] update vaultwarden: phase backing-up
2026/10/06 11:41:51 update.go:840: [INFO] [stacks] update vaultwarden: precondition met after the backup — Tier 2 (second drive) copy from 2026-10-06T11:41:50Z
2026/10/06 11:41:51 update.go:1377: [INFO] [stacks] update vaultwarden: phase safety-dump
2026/10/06 11:41:51 update.go:855: [INFO] [stacks] update vaultwarden: safety dump done (0 file(s)) []
2026/10/06 11:41:52 undo.go:287: [INFO] [stacks] update vaultwarden: the undo copy will hold 1 named volume(s), 0.3 MiB
2026/10/06 11:41:52 update.go:1377: [INFO] [stacks] update vaultwarden: phase pinning
2026/10/06 11:41:52 pin.go:373: [INFO] [stacks] update vaultwarden: pin advanced to /opt/docker/felhom-controller/data/catalog-cache/templates/vaultwarden/docker-compose.yml (vaultwarden=vaultwarden/server:1.37.4-alpine)
2026/10/06 11:41:52 update.go:1377: [INFO] [stacks] update vaultwarden: phase pulling
2026/10/06 11:41:55 update.go:1377: [INFO] [stacks] update vaultwarden: phase copying
2026/10/06 11:41:56 update.go:1377: [INFO] [stacks] update vaultwarden: phase copying
2026/10/06 11:41:56 undo.go:437: [INFO] [stacks] update vaultwarden: copied vaultwarden_vaultwarden_data → vaultwarden_vaultwarden_data.pre-update-20261006T114156Z in 461ms
2026/10/06 11:41:56 update.go:1377: [INFO] [stacks] update vaultwarden: phase starting
2026/10/06 11:41:56 update.go:1377: [INFO] [stacks] update vaultwarden: phase verifying
2026/10/06 11:42:02 update.go:1006: [INFO] [stacks] update vaultwarden: healthy after 5s (the app's health check passed)
2026/10/06 11:42:02 update.go:1042: [INFO] [stacks] update vaultwarden: DONE in 12s
badge after: {'hu': [{'title': 'Ez az alkalmazás a legfrissebb elérhető változatot futtatja.', 'text': 'Naprakész'}], 'en': [{'title': 'This app is running the newest version available.', 'text': 'Up to date'}]}
RESULT final_phase=done after={'vaultwarden': 'vaultwarden/server:1.37.4-alpine'} seed_after=True verdict=proven (12.3 s)
remove -> 200
@@ -0,0 +1,37 @@
#!/usr/bin/env python3
"""Point 9202 at the drill catalog, or put the saved controller.yaml back. `09` §6.5."""
import io, os, re, sys
sys.path.insert(0, "/mnt/5_hdd/felhom.eu/git/app-catalog-felhom.eu/scripts")
import box_walk as w
VOL = "/var/lib/docker/volumes/felhom-controller-data/_data"
SAVE = f"{VOL}/controller.yaml.pre-r890"
DRILL = "https://gitea.dooplex.hu/admin/app-catalog-drill.git"
def creds():
for l in io.open(os.path.expanduser("~/.git-credentials")).read().split("\n"):
m = re.match(r"https://(admin):([^@]+)@gitea\.dooplex\.hu", l)
if m: return m.group(1), m.group(2)
sys.exit("no admin credential")
if sys.argv[1] == "drill":
u, t = creds()
out = w.guest(f"""set -e
test -f {SAVE} || cp -p {VOL}/controller.yaml {SAVE}
python3 - <<'PY'
import re
p = "{VOL}/controller.yaml"; s = open(p).read()
s = re.sub(r'(^\\s+repo_url: ).*$', r'\\g<1>{DRILL}', s, count=1, flags=re.M)
s = re.sub(r'(^git:(?:\\n\\s+.*)*?\\n\\s+token: ).*$', r'\\g<1>"{t}"', s, count=1, flags=re.M)
s = re.sub(r'(^git:(?:\\n\\s+.*)*?\\n\\s+username: ).*$', r'\\g<1>"{u}"', s, count=1, flags=re.M)
open(p, "w").write(s)
PY
rm -rf {VOL}/catalog-cache {VOL}/data/catalog-cache
docker restart felhom-controller >/dev/null
grep -n 'repo_url' {VOL}/controller.yaml
""")
print(out.replace(t, "<token>"))
elif sys.argv[1] == "restore":
print(w.guest(f"""set -e
cp -p {SAVE} {VOL}/controller.yaml
rm -rf {VOL}/catalog-cache {VOL}/data/catalog-cache
docker restart felhom-controller >/dev/null
grep -n 'repo_url' {VOL}/controller.yaml; grep -c 'token: ""' {VOL}/controller.yaml || true
cmp {SAVE} {VOL}/controller.yaml && echo RESTORED-IDENTICAL"""))
@@ -0,0 +1,76 @@
"""vwstep.py <to-ref> — R-890: vaultwarden's step on scratch 9202 (drill catalog), ONE process, through the product.
1 install vaultwarden fresh at the live pin (this run installs it — the admin seed refuses otherwise);
2 seed through the household's door, the invite through the admin page INSIDE the box
(FELHOM_BOX_ADMIN_SEED=1, upgrade_fixtures_box.box_admin_seed_allowed); read it back (C1);
3 a DRILL-only commit moves the image and adds a ladder entry; sync, rescan;
4 the product's guarded Update; the seed read back; box verdict JSON;
5 remove through the product.
Evidence: ../box/vaultwarden/step.txt + box-verdict-vaultwarden.json. The live entry is written ONLY by
`upgrade-test.py --write-ladder` from both verdicts."""
import json, os, re, subprocess, sys, time
sys.path.insert(0, "/mnt/5_hdd/felhom.eu/git/app-catalog-felhom.eu/scripts")
import box_walk as w
import upgrade_fixtures_box as fixtures
APP, SUB, SVC = "vaultwarden", "vault", "vaultwarden"
to = sys.argv[1]
HERE = os.path.dirname(os.path.abspath(__file__))
EVD = os.path.join(HERE, "..", "box", APP); os.makedirs(EVD, exist_ok=True)
log = open(f"{EVD}/step.txt", "a", buffering=1)
D = "/mnt/5_hdd/felhom.eu/drill/app-catalog-drill"
def say(*a):
w.say(*a); log.write(" ".join(map(str, a)) + "\n")
fx = fixtures.FIXTURES[APP]
w.login()
if w.stack(APP).get("deployed"):
say("vaultwarden already installed on 9202 — removing it first (scratch box)")
w.remove(APP)
w.sync_rescan()
if not w.deploy(APP, SUB):
sys.exit(say("RESULT the install did not complete") or 1)
tok = fx.seed(w, SUB, say)
if tok is None or not fx.verify(w, SUB, tok, say):
say(f"RESULT C1 failed: {getattr(fx, 'tried', '')}")
w.remove(APP); sys.exit(1)
say("C1 seed reads back BEFORE: True")
before = (w.stack(APP).get("app_config") or {}).get("pinned_images")
say(f"before: pinned={before}")
subprocess.run(["git", "-C", D, "pull", "-q", "--rebase", "origin", "main"], check=True)
comp, fy = f"{D}/templates/{APP}/docker-compose.yml", f"{D}/templates/{APP}/.felhom.yml"
s = open(comp).read()
frm = re.search(r"^\s+image:\s*(\S+)", s, re.M).group(1)
open(comp, "w").write(s.replace("image: " + frm, "image: " + to, 1))
entry = {"from": {SVC: frm}, "to": {SVC: to}, "verdict": "proven", "tested_at": "DRILL", "harness_version": 5,
"evidence": "DRILL (box proof in progress)", "marks": {"files_may_change": False, "needs_person": None, "memory_tight": False}}
f = open(fy).read()
f = (f.rstrip("\n") + "\n - " + json.dumps(entry) + "\n") if "update_ladder:" in f else (f.rstrip("\n") + "\nupdate_ladder:\n - " + json.dumps(entry) + "\n")
open(fy, "w").write(f)
subprocess.run(["git", "-C", D, "commit", "-q", "-am", f"DRILL {APP}: {frm} -> {to} (box proof, R-890)"], check=True)
subprocess.run(["git", "-C", D, "push", "-q", "origin", "main"], check=True, capture_output=True)
say("drill:", subprocess.run(["git", "-C", D, "log", "--oneline", "-1"], capture_output=True, text=True).stdout.strip())
w.sync_rescan(APP, to)
say(f"badge before: {w.badges(APP)}")
since = w.guest("date -u +%Y-%m-%dT%H:%M:%SZ").strip()
res = w.press_update(APP, poll=1, cap_s=1800)
for p in res.get("phases", []):
log.write(f" phase +{p['t']}s {p['phase']} | err={p['error']}\n")
time.sleep(10)
read = fx.verify(w, SUB, tok, say)
lines = w.guest(f"docker logs --since {since} felhom-controller 2>&1 | grep -E 'update {APP}' | grep -v DEBUG | cut -c1-400")
log.write(lines + "\n")
st = w.stack(APP); after = (st.get("app_config") or {}).get("pinned_images")
verdict = {"app": APP, "venue": "box 9202 (drill catalog), the product's guarded Update; seeded through the admin invite inside the box (R-890)",
"from": before, "to": after,
"verdict": "proven" if (res.get("final_phase") == "done" and read and (after or {}).get(SVC) == to) else "failed",
"seed_read_before": True, "seed_read_after": read, "healthy_after": st.get("state") == "running",
"duration_s": res.get("duration_s"), "final_phase": res.get("final_phase"), "measured_at": since,
"evidence": "felhom.eu/documentation/audits/r890-instructions-2026-10-06/box/vaultwarden/step.txt"}
json.dump(verdict, open(f"{EVD}/box-verdict-{APP}.json", "w"), indent=2)
say(f"badge after: {w.badges(APP)}")
say(f"RESULT final_phase={res.get('final_phase')} after={after} seed_after={read} verdict={verdict['verdict']} ({res.get('duration_s')} s)")
say(f"remove -> {w.remove(APP)}")