docs(plan): record the org lead's decisions and design against them #2

Merged
whitlocktech merged 1 commits from docs/plan-decisions into main 2026-08-19 23:26:25 +00:00
Member

Revision 2 of the design of record. Revision 1 (#1) ended in five open questions; all are answered, so the plan now states decisions and designs against them rather than asking.

What changed

New §5 — decisions of record. Twelve decisions taken by the org lead on 2026-08-19, recorded so they are not re-litigated: the runtime, the beta signup, the scope of the documentation fixes, real screenshots over placeholders, who drafts the legal pages, who deploys, the maturity posture, no analytics, the support channels, keeping the existing emblem, and the demo instance.

New §6–§9, designing against them:

  • §6 Runtime — Astro with the Node adapter, pages prerendered, three dynamic endpoints. One container. Fully static could not satisfy either the signup or bind-mounted branding.
  • §7 Branding is bind-mounted data/app/brand resolved per-file against a baked /app/brand-default, served at stable unhashed URLs so Vite cannot fingerprint them. A checkTokens.mjs fails the build on any colour literal outside the token file, because otherwise "one CSS file changes the appearance" quietly decays into "most of the appearance".
  • §8 The Android closed-beta signup — the page, the SQLite schema, abuse resistance without a third party, and the export path.
  • §9 Legal pages/privacy in three separately-scoped sections, /terms, and where the Play Data Safety declaration comes from.

§4 Phase 0 grows from the four operator-facing fixes to all ten documentation conflicts, plus retiring the personal Gmail that docs/SECURITY.md publishes as the public vulnerability contact.

§15 records the demo instance as planned and out of scope: a Proxmox VM running the full stack including ServUO, restricted and reset hourly. The site reserves its slot now so it costs one line in a bind-mounted file later.

Re-verification, and three things revision 1 got wrong

Every version re-read from the Gitea API on 2026-08-19. Protocol 4, bundle 2026.08.19, sidecar v2.0.0, overlay v1.0.0, installer v0.1.0, module-uo v1.0.1, Android v0.5.0, Module API 1.6.0 — all confirmed. Corrected:

  1. The bundle manifests live at the root of the bundles branch, not under bundles/. §12's fact-checker would have fetched a 404.
  2. website publishes no releases at all — it ships as container images. The site must never print a "website version".
  3. The Android app targets no server of ours. BaseUrlHolder / HostSelectionInterceptor / ServerPreferences mean the user enters the address. This is load-bearing for the privacy policy and the Play Data Safety form.

Two design notes worth a second opinion

The site sends no email, and that turned out not to block the beta. With Play's email-list method Google does not notify testers either — the developer distributes the opt-in link. But that link only works for addresses already on the tester list, so it is safe to publish: the confirmation screen shows it, and Discord carries the "you've been added" announcement. No SMTP, no deliverability, no unsubscribe machinery for a list nobody is mailed from.

The CSV export is a CLI, not an admin page. An authenticated HTTP surface on a marketing site is a login form, a session and a password to rotate, for an operation performed by the one person who already has shell on the host against a file already on their disk. The site keeps no authenticated surface at all.

Still open (§14) — none of it blocks starting

  • N1 resolved — the domain is registered through Cloudflare with DNS there.
  • N2 — a contact address is required by Play and by /privacy; Cloudflare Email Routing is free and the domain is already on Cloudflare. Three forwards proposed: hello@, privacy@, security@.
  • N3 — Gitea registration is disabled, so "file an issue" is a wall for outsiders. §14 carries a Gitea 1.24.7 config that reopens it without repeating the spam flood: manual approval as the real control, MAX_CREATION_LIMIT = 0 as defence in depth, Turnstile on the form. /community is written the same way either way; only one sentence changes.

AI-assisted contribution

Drafted by Claude (Claude Code), per the org's AI-usage disclosure policy. Commit carries the Co-Authored-By trailer.

Revision 2 of the design of record. Revision 1 (#1) ended in five open questions; all are answered, so the plan now states decisions and designs against them rather than asking. ## What changed **New §5 — decisions of record.** Twelve decisions taken by the org lead on 2026-08-19, recorded so they are not re-litigated: the runtime, the beta signup, the scope of the documentation fixes, real screenshots over placeholders, who drafts the legal pages, who deploys, the maturity posture, no analytics, the support channels, keeping the existing emblem, and the demo instance. **New §6–§9**, designing against them: - **§6 Runtime** — Astro with the Node adapter, pages prerendered, three dynamic endpoints. One container. Fully static could not satisfy either the signup or bind-mounted branding. - **§7 Branding is bind-mounted data** — `/app/brand` resolved per-file against a baked `/app/brand-default`, served at stable unhashed URLs so Vite cannot fingerprint them. A `checkTokens.mjs` fails the build on any colour literal outside the token file, because otherwise "one CSS file changes the appearance" quietly decays into "most of the appearance". - **§8 The Android closed-beta signup** — the page, the SQLite schema, abuse resistance without a third party, and the export path. - **§9 Legal pages** — `/privacy` in three separately-scoped sections, `/terms`, and where the Play Data Safety declaration comes from. **§4 Phase 0 grows** from the four operator-facing fixes to all ten documentation conflicts, plus retiring the personal Gmail that `docs/SECURITY.md` publishes as the public vulnerability contact. **§15** records the demo instance as planned and out of scope: a Proxmox VM running the full stack including ServUO, restricted and reset hourly. The site reserves its slot now so it costs one line in a bind-mounted file later. ## Re-verification, and three things revision 1 got wrong Every version re-read from the Gitea API on 2026-08-19. Protocol 4, bundle 2026.08.19, sidecar v2.0.0, overlay v1.0.0, installer v0.1.0, module-uo v1.0.1, Android v0.5.0, Module API 1.6.0 — all confirmed. Corrected: 1. **The bundle manifests live at the root of the `bundles` branch**, not under `bundles/`. §12's fact-checker would have fetched a 404. 2. **`website` publishes no releases at all** — it ships as container images. The site must never print a "website version". 3. **The Android app targets no server of ours.** `BaseUrlHolder` / `HostSelectionInterceptor` / `ServerPreferences` mean the user enters the address. This is load-bearing for the privacy policy and the Play Data Safety form. ## Two design notes worth a second opinion **The site sends no email, and that turned out not to block the beta.** With Play's email-list method Google does not notify testers either — the developer distributes the opt-in link. But that link only works for addresses already on the tester list, so it is safe to publish: the confirmation screen shows it, and Discord carries the "you've been added" announcement. No SMTP, no deliverability, no unsubscribe machinery for a list nobody is mailed from. **The CSV export is a CLI, not an admin page.** An authenticated HTTP surface on a marketing site is a login form, a session and a password to rotate, for an operation performed by the one person who already has shell on the host against a file already on their disk. The site keeps no authenticated surface at all. ## Still open (§14) — none of it blocks starting - **N1 resolved** — the domain is registered through Cloudflare with DNS there. - **N2** — a contact address is required by Play and by `/privacy`; Cloudflare Email Routing is free and the domain is already on Cloudflare. Three forwards proposed: `hello@`, `privacy@`, `security@`. - **N3** — Gitea registration is disabled, so "file an issue" is a wall for outsiders. §14 carries a Gitea 1.24.7 config that reopens it without repeating the spam flood: manual approval as the real control, `MAX_CREATION_LIMIT = 0` as defence in depth, Turnstile on the form. `/community` is written the same way either way; only one sentence changes. ## AI-assisted contribution Drafted by Claude (Claude Code), per the org's AI-usage disclosure policy. Commit carries the `Co-Authored-By` trailer.
wtclaude added 1 commit 2026-08-19 22:55:27 +00:00
Revision 1 ended in five open questions. All are now answered, plus the
domain and Gitea-registration facts, so the plan states decisions instead
of asking.

New section 5 holds the twelve decisions of record. Sections 6-9 design
against them: the Astro + Node adapter runtime, branding resolved out of a
bind mount against baked defaults, the Android closed-beta signup, and the
legal pages the beta cannot ship without.

Re-verified every version against the Gitea API and corrected three things
revision 1 got wrong: the bundle manifests live at the root of the bundles
branch rather than under bundles/, the website publishes no releases at
all, and the Android app targets no server of ours - the user enters the
address, which is load-bearing for the privacy policy.

Phase 0 grows from the four operator-facing documentation fixes to all
ten conflicts, plus retiring the personal Gmail that SECURITY.md
publishes as the public vulnerability contact.

Two design notes worth flagging. Play does not notify testers on the
email-list path either, so a site that sends no mail looked blocked - but
the closed-testing opt-in URL only works for addresses already on the
list, so it is safe to publish on the confirmation screen, with Discord
carrying the announcement. And the CSV export is a CLI against the bind
mount rather than an admin page, so the site keeps no authenticated
surface at all.

The demo instance is recorded as planned and out of scope: a Proxmox VM
running the full stack including ServUO, restricted and reset hourly. The
site reserves its slot now so it costs one line in a bind-mounted file
later.

Co-Authored-By: Claude <noreply@anthropic.com>
whitlocktech merged commit 650ea21ad4 into main 2026-08-19 23:26:25 +00:00
whitlocktech deleted branch docs/plan-decisions 2026-08-19 23:26:26 +00:00
Sign in to join this conversation.
No description provided.