What's new
Development changelog — every change shipped to the platform.
-
3724763
auto video posters (ffmpeg) via a read_only media collection
Every legacy video episode gets a poster frame: - HasMediaCollections gains a `read_only` collection flag (mediaCollectionIsReadOnly) — system-generated, immutable collections marked in the model's config. - MediaItem: `poster` (read_only, auto) + `poster_custom` (admin overrid...
-
444364b
add ffmpeg for video poster frame extraction
ffmpeg (apk) so App\Jobs\Media\GenerateVideoPoster can pull a representative frame from the legacy video MP4s. The image already carries chromium + full imagemagick, so the marginal size is negligible and apk matches the Dockerfile.
-
c5926f0
dev/prod data isolation — 44100_dev split + media offload switch
dev → 44100_dev (own DB copy) + MEDIA_OFFLOAD_ENABLED=false (uploads stay local); prod 2569 → real 44100 + offloads to the bucket. So dev sees everything (DB copy + read-only bucket) but can't pollute prod's DB or bucket. Verified live.
-
4d9f3f4
per-env offload switch (dev keeps uploads local)
media.offload_enabled (MEDIA_OFFLOAD_ENABLED, default true). ON = uploads stream to the shared bucket (prod). OFF = uploads stay on the local source_disk and are served from there — the dev pattern: dev reads the shared 44100-data bucket for existing media (read-only) but never w...
-
2cdd051
record 2569.44100.com stand-up (new ungated prod)
Host layout: 44100.com = legacy placeholder (untouchable), dev.44100.com = cookie-gated dev, 2569.44100.com = new prod (Thai 2569), code /home/44100.com/2569, ungated (gate regex matches only dev). Stood up 2026-07-15 by populating 2569 + wiring nginx server block + traefik ENV_H...
-
fbb308d
serve Plyr sprite from public/plyr (deploy rsync excludes vendor)
The self-hosted sprite lived at public/vendor/plyr/plyr.svg, but the deploy rsync's `--exclude vendor` (for the composer vendor/ dir) is unanchored and also dropped public/vendor, so the sprite 404'd on dev and Plyr's controls lost their icons. Move it to public/plyr/plyr.svg and...
-
713ce0b
build deploy --assets inside fpm, not on the host
`ship deploy dev --assets` ran `npm run build` on the host, but node_modules holds Linux-native rollup/esbuild binaries installed in the fpm container, so a macOS host build dies with MODULE_NOT_FOUND (rollup/dist/native.js) and aborts the deploy. Build in the fpm container inste...
-
a0989e8
Plyr video player for legacy MP4 episodes (Govor Non-Stop)
The 29 "video" media items weren't lost — they're the 2006 video podcast whose MP4s live in 44100-media, served at pod.sorokchetyresto.com/video/<code>.mp4 (verified 200/206, cf-cache HIT). Their stored audio_url held the dead 2006 page URL; MediaItem::videoUrl() resolves the cod...
-
8891413
correct session handoff + record shared-index incident
The earlier dc41b58 accidentally bundled another session's staged WIP (shared index). Nothing lost; shared HEAD restored to their tip. This corrects the report and records the lesson. Committed with `git commit -o` so only this file lands regardless of the shared index.
-
cf5262d
trim admin docs file endings
-
dc41b58
session handoff — G0/G1 pass, deferred-deploy + open items
-
8bfe0e4
production cutover runbook (promote dev -> 44100.com) (G1)
dev recovery drills are green (restore drill + rollback drill), so the G1 production-cutover checklist is now written as CUTOVER.md: preconditions (green recovery chain, CI, strict audit, honest media), a HARD secrets-rotation gate (everything leaked in chat during migration), pr...
-
f79e153
make gallery/photo flags honest, correct 2015-fallback docs (G1)
Verified the real state on moon dev (source of truth, not the stale local DB): 2477 of 2488 galleries (200 731 photo rows) serve from data.44100.com; only 1 still falls through to the 2015 legacy base, which is still live (200). Both render paths browser-checked on local. - conf...
-
66dd378
media:audio-sweep — flag missing mix/podcast audio (G1)
Read-only HEAD sweep of every media_items.audio_url, sending our own Referer so the hotlink WAF rule allows the probe. Classifies ok/redirect/blocked/missing/ error, prints the failing rows and writes them to JSON for a fix pass. First full sweep (2026-07-15, 1097 URLs): 1096 mi...
-
a39014f
db:restore-drill — prove the offsite backup restores (G0)
`ship backup <env> restore-drill` used to only print a manual runbook. It now runs the drill: stream the latest 44100-backup object into a scratch database, load it with `gunzip | psql`, assert the core tables came back (users + migrations vs. the live DB), then drop the scratch...
-
072d93a
plan dj mix podcast workbench
-
20fd48f
update for test time
-
98e9ac6
mark podcast audio fixed
-
b9c2dea
refresh health handoff and roadmap
-
e4188da
queue/ops work applied to moon — deploy + compose reconcile done
Operator opened the ssh/ship permission gate; applied live and verified: - ship deploy dev -> moon at 65a5c91; Horizon 4-supervisor split + redis-long LIVE (queue doctor: 4 supervisors, 0 violations). Deploy's worker-restart fix ran for real (restarted 44100_horizon + 44100_s...
-
65a5c91
record full-suite result — 923 passed, 0 failures
Full `ship artisan test` run completed green (923 tests / 4970 assertions, ~5 min) — the audit-readiness health line now carries the concrete number.
-
bd69032
audit-readiness snapshot for the external review
Entry point for the incoming external code audit: repo state (dev @88a7d02, clean, pushed; ahead of moon on the queue/ops work), doc map, the 2026-07-13→15 queue/ops hardening with per-commit rationale + verification, verified health (ops guards green), and the honestly-open item...
-
88a7d02
ship compose diff|push — reconcile docker-compose.yml.prod with moon
docker-compose.yml.prod is the canonical prod topology, but `ship deploy` rsyncs only the app tree, not the root compose — so moon still runs a hand-edited file that drifts. `ship compose` closes that loop: - diff <env>: read-only, shows config-level deltas the push would apply...
-
0878089
commit docker-compose.yml.prod — moon topology as git source of truth
Moon ran a hand-edited /home/44100.com/docker-compose.yml that nobody could review and that diverged from the repo (horizon vs worker, pinned image tags, restart: always, /home/44100/dev paths). Capture it in git so prod is finally recorded. docker-compose.yml.prod mirrors moon'...
-
a8f535d
split Horizon into per-workload supervisors (+ redis-long lane)
One shared supervisor-1 auto-balanced all five queues, so a flood on a slow lane (embeddings, a media backfill) could eat every worker process and stall latency- sensitive web jobs. Split into four isolated pools — SAME total process budget as before (prod 10, local 4), so this i...
-
a155da1
record verified moon topology (horizon confirmed, no worker service)
ssh check 2026-07-14 (docker ps + moon's /home/44100.com/docker-compose.yml): moon runs a `horizon` service (44100_horizon, artisan horizon, image 44100/php-fpm:8.4-worker, restart: unless-stopped) + 44100_scheduler; NO worker service. Moon's compose diverges from the committed o...
-
4c74c44
ship deploy must restart the queue workers (were running stale code)
bin/cmd/deploy.sh restarted 44100_fpm (+ ai_agent/ai_results under --consumers) but never the Redis-queue workers, so after every code deploy the long-running Horizon + scheduler kept the OLD Job / scheduled-command code in memory until someone bounced them by hand — a silent cor...
-
26a70da
reconcile Horizon/worker docs with reality; flag deploy-restart gap
Background-process runtime is built and matches the reference's CURRENT prod shape (Docker restart policy = supervisor; no cron, no supervisord — that was the ref's legacy v1/v2, deliberately not ported). The docs had drifted: - ROADMAP Phase 7: check the "workers + scheduler as...
-
a3225d4
Horizon must watch embeddings/syndication/media queues (was default-only)
On moon Horizon is the ONLY queue consumer (no separate worker container), but with no config/horizon.php the vendor default supervised only ['default'] — so EmbedEntityJob (embeddings), SyndicateJob (syndication) and media jobs were NEVER consumed: new/edited content stopped get...
-
26c8618
rename vec1024 -> similarVec1024 (collided with VectorSearchTest, red-lined CI)
SimilarEntitiesTest declared a top-level vec1024() that already exists in tests/Feature/Search/VectorSearchTest.php — Pest loads every test file into one scope, so the full suite hit a fatal 'Cannot redeclare' (my Public-folder run missed it; the files are in different folders)....