The CI lint step was `biome check . || true`, so it could never fail: 14 real
violations were passing unnoticed. Drop the `|| true` and fix what it found.
Lint fixes, none of which change behaviour:
- give list items their natural identity instead of the array index
(key={c} / key={char}, key={`skeleton-${i}`})
- document the two useEffect dependency lists that must keep their
function-declaration handlers, with the reasoning that dropping them broke
the tree and save-on-Ctrl+S once already (704e3363)
- scope the remaining noArrayIndexKey / useExhaustiveDependencies exemptions to
the three files that need them, in biome.json instead of scattered comments
Storage, on a host that had grown to 81% disk:
- byparr starts a Firefox per request and never removes the profile it leaves in
the container's writable layer. With no volume mounted, nothing else reclaimed
it: 716 profiles / 6.8 GB in two days, ~1.7 GB/day. docker-prune.sh now removes
orphaned profiles, identifying live ones by the open fd in /proc/<pid>/fd rather
than by age, because browsers stay warm for ~27 hours here — longer than the
leak window, so no age threshold can be both safe and useful.
- bound the build cache properly: buildx treats --max-used-space and --filter as
mutually exclusive, so passing both silently dropped the 4 GB cap and the cache
reached 49 GB.
- escalate to the emergency prune when / drops below 8 GB free, so the bound holds
even if the schedule stops.
- clear multi-GB tmp_pack files left behind by a gc that was OOM-killed
mid-repack; git only removes those on the next successful gc.
- make setup-cron.sh append instead of replacing the crontab (`crontab -`
overwrites the whole file, which had been dropping the other scheduled jobs),
and run the prune daily rather than weekly to match the leak rate.
Volumes are still never pruned: mariadb-turbo-data is a database.
`next build` on Turbopack never completes on this app. The compiler is a
single native process whose RSS grows monotonically with no plateau:
0.9G -> 1.6G -> 2.8G -> 5.0G -> 5.5G -> 6.2G -> killed
It still dies with 4GB of swap attached, at 12GB RSS. The build workers are
only 0.17GB each, so `experimental.cpus` is not the lever either.
A `--max-old-space-size` cap cannot help: measured with a 2GB cap, RSS still
reached 8GB, because the memory is native Turbopack (Rust) memory rather than
the V8 heap. The cap added in 1c9ddcd4 was therefore inert and only created
false confidence, so it is dropped from the build script.
Webpack builds the same 329 routes in ~95s with a ~6GB peak.
Ruled out by measurement: the 25 bundled locale files (stubbing 24 of them
from 7.1MB down to 276KB still peaked at 11GB), worker count, and the
flatten/unflatten message pipeline (600 iterations cost 6.4s and settle at
39MB of heap).
Verified: `pnpm run build` exits 0, TypeScript passes, 279/279 static pages are
generated, and the standalone output boots and serves /, /login and /register.
The previous dependency upgrade rewrote the file with two-space indentation, which violated the Biome formatter setting (indentStyle: tab) and broke `biome check .`.
Patch release, bug fixes only, no breaking changes. Two entries are
relevant to this repository: a stack overflow when spying on
Set.prototype.add, and the hanging-process reporter switching to its ESM
entrypoint, which drops why-is-node-running 2.3.0, siginfo and stackback
in favour of why-is-node-running 3.2.2.
Verified with the CI unit command: 3302 tests pass under --maxWorkers=4,
the coverage run clears its thresholds, pnpm deps:audit reports no known
vulnerabilities, and the lockfile stays consistent under
--frozen-lockfile.
Align the active runtime with the pinned version across .nvmrc, package.json
engines and the Dockerfile base images, so scripts/check-node-toolchain.mjs
passes on the CI host running Node 26.10.0.
Bump the framework to the latest 16.3.6 patch release. Typecheck passes and
the homepage renders (HTTP 200) on the dev server with Next 16.3.6 under
Turbopack.
- password.ts: derive plain and salted digest detection from one DIGEST_SCHEMES
table instead of parallel hardcoded lists, so adding a family is one row.
- auth.ts: move 2FA challenge verification into twofactor-verification.ts and
the website login-log insert into website-login-log.ts, slimming the
NextAuth provider to orchestration only.
- deps: bump @formatjs/icu-messageformat-parser, @tanstack/react-query, jszip,
lucide-react, motion (patch/minor only). @types/react stay pinned per
pnpm-workspace.yaml; next-auth is already at the newest available (v5 beta).
Replace the premium dark-gaming redesign of home, login and register with
the original classic landing (Habbo sky background, AuthTopBar, SurfaceCard
layout). Keeps the theme background visible again and adds a subtle
theme-aware brand halo behind the hero/Frank plus a soft primary glow on
card hover.
Also upgrades dependencies: next 16.3.5, vite 8.3.0 (typescript 7.0.2 was
already latest). Temporarily lowers pnpm minimumReleaseAge to 60 min so the
fresh 16.3.5 release can be installed; restore to 1440 once it is 24h old.
Run vitest without coverage by default (pnpm test) and add pnpm test:coverage which enforces the coverage thresholds. CI keeps using the coverage run so thresholds are still enforced on every push.
Drop the unused knip dead-code check and the husky+lint-staged pre-commit hook pipeline. All checks remain covered by the CI workflow (lint, typecheck, i18n, tests).
- Use floating node:alpine that tracks the latest supported LTS; pnpm
bootstrap follows package.json's packageManager pin.
- Drop corepack (removed from node:26), install pnpm via npm global.
- Add pnpm fetch + offline install for stable dependency-layer caching.
- Run as non-root nextjs (UID/GID 33 = host www-data) with tini as PID 1
for correct signal handling.
- Open node engines to >=20.9.0 so patches/minors float automatically.
- Add docker-preflight.sh (per-VPS checks incl. --fix) and gate docker-update.sh
so Node major upgrades require explicit review while patches deploy silently.
Replace the pure-JS lzma decoder with lzma-wasm (Rust/WASM, base64-inlined,
zero-alloc decompress), giving an order-of-magnitude speedup on furni
imports. Remove the obsolete lzma type shim and the redundant top-level
vite dev dependency, which nothing imports directly.
.nvmrc and package.json engines.node must match the exact version the
CI environment runs, otherwise scripts/check-node-toolchain.mjs fails
the strict equality assertion.