From b9f8ce4ee4b671e5e9bad6cc3f06b9d8d28bf8a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Padez?= Date: Sat, 29 Aug 2026 01:14:47 +0100 Subject: [PATCH] originals/ and derived/, because the names are the rule MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit media/ originals/ nothing regenerates these derived/ rebuildable from originals/, safe to wipe a pure rename: nothing had been created yet — checked the real root on fofos, only `website/` was there — so there is no directory to move and no file to lose. that is the last moment this was free, which is why it happened now. `user/` and `treated/` both named the wrong thing. `user` said who put the file there, which stops distinguishing anything the moment a job writes one, and reads like it should hold a folder per person. `treated` said what had happened to it, which stops being informative as soon as there is more than one kind of treatment. these two say which one you can afford to lose. that is the only property that matters about the pair, and it is the one that decides every rule anybody writes about them later — what a cleanup job may delete, what a backup must never skip, what a conversion may overwrite without asking. a name that carries it is a rule that cannot be forgotten, which is more than the comment above it can promise. Co-Authored-By: Claude Opus 5 --- api/media.ts | 28 +++++++++++++++++----------- manifest.ts | 2 +- web/MediaFolder.tsx | 9 ++++----- 3 files changed, 22 insertions(+), 17 deletions(-) diff --git a/api/media.ts b/api/media.ts index 0b67b19..67d947c 100644 --- a/api/media.ts +++ b/api/media.ts @@ -10,8 +10,8 @@ import { readSettings } from './settings'; * / * website/ the checkout * media/ - * user/ what people upload, untouched - * treated/ what comes back out of conversion + * originals/ what people upload, untouched. nothing regenerates these + * derived/ made from originals/, and safe to wipe * * ── BESIDE the checkout, never inside it ── * @@ -25,16 +25,22 @@ import { readSettings } from './settings'; * The two live under one root so a backup of the root is the whole site — the code and the things it * serves — which is the property that makes the root worth being a setting at all. * - * ── The asymmetry between the two halves ── + * ── The names ARE the asymmetry, and that is the whole reason for them ── * - * `user/` is ORIGINAL. Nothing regenerates it; if it is lost, somebody has to be asked for the file - * again, and they may not have it. + * `originals/` cannot be regenerated. If it is lost, somebody has to be asked for the file again, and + * they may not have it. * - * `treated/` is DERIVED. Every file in it can be made again from the one it came from, so it is the - * half that is safe to delete, safe to rebuild, and safe for a job to overwrite without asking. + * `derived/` can. Every file in it is reproducible from the one it came from, so it is the half that is + * safe to delete, safe to rebuild, and safe for a job to overwrite without asking. * - * Nothing here enforces that yet — no code deletes either — but it is the fact that should decide - * every rule written about them later, so it is recorded before the first one is. + * They were called `user/` and `treated/` for about an hour. Both named the wrong thing: `user` said + * who put the file there, which stops distinguishing anything the moment a job writes one, and read + * like it should hold a folder per person. `treated` said what had happened to it, which stops being + * informative as soon as there is more than one kind of treatment. + * + * These say which one you can afford to lose. Nothing enforces it yet — no code here deletes anything — + * but every rule written about these two later should start from that sentence, and a name that carries + * it is a rule that cannot be forgotten. */ const DIR_NAME = 'media'; @@ -46,8 +52,8 @@ const DIR_NAME = 'media'; * "ready" about a structure that is missing a folder the creator stopped making. */ export const MEDIA_CHILDREN = [ - { name: 'user', hint: 'What people upload, untouched' }, - { name: 'treated', hint: 'What comes back out of conversion' }, + { name: 'originals', hint: 'Uploaded, untouched — nothing regenerates these' }, + { name: 'derived', hint: 'Made from originals — safe to wipe and rebuild' }, ] as const; export type MediaChildStatus = { diff --git a/manifest.ts b/manifest.ts index a0fbf78..3810679 100644 --- a/manifest.ts +++ b/manifest.ts @@ -35,7 +35,7 @@ import type { PluginManifest } from '@@/plugins/manifest'; */ export const manifest: PluginManifest = { publisher: 'officerdev', - version: '2026.08.29.15', + version: '2026.08.29.16', platform: '>=1.0.0', label: 'Fofos', diff --git a/web/MediaFolder.tsx b/web/MediaFolder.tsx index 4bc65c2..d377d4c 100644 --- a/web/MediaFolder.tsx +++ b/web/MediaFolder.tsx @@ -15,8 +15,8 @@ import { readableError } from './errors'; * * ── The children are listed, and the button repairs ── * - * `user/` and `treated/` are shown whether or not they are there, so a structure that is missing one - * reads as INCOMPLETE rather than as fine. The button follows: "Create" when there is nothing, "Create + * `originals/` and `derived/` are shown whether or not they are there, so a structure that is missing + * one reads as INCOMPLETE rather than as fine. The button follows: "Create" when there is nothing, "Create * missing" when part of it exists. It is `mkdir -p` on every path either way, so pressing it can only * add and can never fail on something already correct. */ @@ -93,9 +93,8 @@ export const MediaFolder = ({ rootPath }: { rootPath: string }) => {

Not created yet.

)} - {/* The structure, always — the folders that are missing are the point of showing it. Named - with what they hold, because "user" and "treated" say who and what happened rather than - what goes in them. */} + {/* The structure, always — the missing folders are the point of showing it. The hint beside + each name carries the one distinction that matters: which of the two can be rebuilt. */}
    {status.children.map((child) => (