Legendary Arena Lab

wiki

Operator Wiki — Schema

The contract for every page under wiki/. If a page violates this schema, the page is wrong — not the schema.

Last updated: 2026-07-24


Purpose

This wiki is an internal operator reference for the migration that moves api.legendary-arena.com and its PostgreSQL off Render onto a self-hosted DigitalOcean Ubuntu droplet fronted by Cloudflare. Each page is an entity (a host subsystem, an infra artifact, a migration concept, or an operational procedure) with a defined shape, cross-references to related entities, and citations to the authoritative artifacts that govern it.

The wiki exists to answer:

  • “What is X, and which file in this repo owns it?”
  • “Which plan phase and infra script govern X?”
  • “What does X interact with, and what edge cases bite during cutover?”

It is not a replacement for docs/PLAN.md , the infra/ artifacts themselves, or the operator runbooks under content/ . The wiki explains; the cited artifacts govern and execute.


Authority Position

The wiki is documentation. It cites authoritative sources; it does not redefine them. The authority hierarchy for this repo:

1. .claude/CLAUDE.md                 # repo identity + working model
2. docs/PLAN.md                      # migration plan & repo blueprint
3. docs/01-REPO-FOLDER-STRUCTURE.md  # repo map
4. infra/** and .github/workflows/** # executable artifacts (the source of truth)
5. content/**                        # operator runbooks
6. (this wiki)
7. Active conversation context

If the wiki and a higher-authority artifact disagree, the wiki is wrong and must be corrected. Wiki pages never override the plan, the scripts, or the workflows. The wiki itself is never a valid source citation in another wiki page.

The core rebuild invariant lives in the plan, not here: “rebuild the host from documentation alone” reduces to “run the numbered infra/scripts/*.ps1 files in order” (see PLAN.md §0 ). The wiki describes what each script does; the script is the thing that runs.


Scope Exclusion

The wiki is descriptive, not prescriptive. It explains the migration; it does not govern it.

A wiki page MUST NOT:

  • Redefine decisions from docs/PLAN.md (droplet size, region, TLS posture, deploy mechanism, etc.). The wiki cites the locked-decisions table; it does not re-decide.
  • Restate a script line-for-line as if the wiki were the source. Cite the script and describe its behaviour; the script under infra/ is the executable truth. If the wiki and the script drift, fix the wiki.
  • Introduce new constraints that don’t exist in the plan or the artifacts. If you find yourself writing “the operator MUST do X” and X isn’t already in PLAN.md, a script, or a runbook, stop — the wiki is the wrong place.

If a wiki page drifts into prescriptive territory, the fix is to either (a) move the prescriptive content into the plan or the owning artifact and cite it, or (b) delete it.


File Layout

wiki/
├── SCHEMA.md            # this file — the contract
├── README.md            # purpose, conventions, authority
├── INDEX.md             # categorized list of all pages
└── <slug>.md            # entity pages (one per entity)

SCHEMA.md, README.md, and INDEX.md are reserved filenames. All other *.md files in wiki/ are entity pages and must conform to this schema.

There are no subdirectories. Categorization is by type and surfaced in INDEX.md. (The rendered operator wiki under content/ uses Hugo sections; this wiki/ knowledge layer is deliberately flat, like the engine repo’s wiki/ that inspired it.)

Flat-structure cap

The flat layout is valid up to 50 entity pages. Beyond 50, a formal SCHEMA amendment must introduce partitioning before any further pages are added.


File Naming

  • Filename = title, kebab-cased. Lowercase, replace spaces with -, drop characters outside [a-z0-9-], collapse consecutive hyphens.
    • title: SSH Hardeningssh-hardening.md
    • title: Cloudflare TLScloudflare-tls.md
  • Singular by default.
  • No leading numbers, no prefixesINDEX.md orders pages, not the filesystem. (Note: the scripts are numbered — 05-…, 10-… — because execution order matters there; wiki slugs are not.)
  • No spaces, no underscores, no special characters other than hyphens.
  • Reserved files are ALL-CAPSSCHEMA.md, README.md, INDEX.md.

Front-Matter Format

Every entity page begins with a YAML front-matter block — the page’s machine-readable contract.

Wiki-only convention. This front-matter shape is adopted only in wiki/. The operator runbooks under content/ carry their own Hugo front-matter; governance docs (docs/PLAN.md, docs/01-REPO-FOLDER-STRUCTURE.md) use the # Title + > **Last updated:** header pattern.

---
title: SSH Hardening
type: Tutorial
tags: [foundations, security, ssh, ubuntu]
related:
  - provision-droplet.md
  - ufw-firewall.md
status: draft
source:
  - C:\www\legendary-arena-lab\wiki\ssh-hardening.md (this page — internal operator wiki)
  - ../infra/scripts/05-user-and-ssh.ps1
  - ../docs/PLAN.md
  - ../content/foundations/ssh-hardening.md
last-reviewed: 2026-07-24
---

Field reference

FieldRequiredTypeNotes
titleyesstringHuman-readable title.
typeyesenumOne of the closed set below.
tagsyeslist of stringsLowercase-hyphenated. Free vocabulary. [] permitted but discouraged.
relatedyeslist of relative pathsOther wiki pages this entity touches. May be [] for true leaf entities.
statusyesenumcanonical | draft | deprecated
sourceconditionallistFirst entry is the page’s own self-reference. Remaining entries are the authoritative artifacts cited, as relative paths. Non-empty for canonical.
last-reviewedyesdate YYYY-MM-DDWhen the page was last verified against current artifacts.

Self-reference (first source entry)

The first entry in source is the page itself — its full drafting path — so a reader can tell from the file which copy is authoritative:

source:
  - C:\www\legendary-arena-lab\wiki\<slug>.md (this page — internal operator wiki)

There is no published URL locked yet (the plan puts the rendered operator wiki on Hugo behind Cloudflare Access — see PLAN.md §1 ); update the self-reference when a URL exists.


Required Sections

Every entity page must contain these H2 sections, in this order:

  1. ## Summary — One to three sentences. What this entity is and why it matters in the migration. No code, no citations.
  2. ## Mechanics — How it actually works: what the owning artifact does, the key config values, the order of operations. Concrete, technical, citable.
  3. ## Interactions — Which other entities this one touches, and how. Each interaction names another wiki page (link to it) or a specific artifact with a citation.
  4. ## Edge Cases — Corner conditions, lockout hazards, cutover gotchas, and drift risks. If none are known, write None known at this revision. rather than omitting the section.
  5. ## References — Bullet list of cited artifacts. May overlap with front-matter source but is the human-readable rendering.

Section names are fixed. Do not rename Mechanics to How it works or Edge Cases to Gotchas.


Optional Sections

These may appear when relevant, after Edge Cases and before References:

  • ## Execute — The exact command(s) to run the owning script, including documented environment-variable overrides. Use for Tutorial pages whose entity is a runnable script.
  • ## Verify — Commands that confirm the entity is in the desired state, with expected output.
  • ## Code Touchpoints — Relevant repo paths with one-line descriptions.
  • ## History — Timeline of plan phases / decisions that introduced or changed this entity.
  • ## Open Questions — Gaps the page could not fill from authoritative sources. Pages with open questions usually have status: draft.

Entity Types (Closed Set)

type must be exactly one of:

TypeDefinitionExamples
TutorialA step-by-step procedure that runs an owning infra artifactSSH Hardening, Nginx Reverse Proxy, PostgreSQL Setup
GuideA reference explaining conventions, contracts, or a subsystem without a single runnable scriptSecrets and Env, Systemd Service
ConceptAn abstract idea, contract, or design decisionRender-to-DigitalOcean Migration, Idempotent Provisioning
ReferenceA standing lookup — costs, ownership boundaries, tablesCost and Ownership

This set is closed. Adding a new type requires updating SCHEMA.md first.


Status Values (Closed Set)

StatusMeaningConstraints
canonicalEvery claim is sourced; verified against current artifacts at last-reviewed.source is non-empty; no uncited factual claims in body.
draftExists but has uncited claims, content gaps, or pending real-host verification (the migration has not executed against a live droplet yet).source may be []. Open Questions recommended.
deprecatedSuperseded or no longer accurate. Kept for history.Page links to its replacement in the first paragraph of Summary.

Pre-execution note. At the current phase, the infra/ scripts and configs exist and are described accurately, but the migration has not been run against a production host. Pages that describe on-host outcomes therefore carry status: draft until verified on a real droplet, even when every claim cites an existing artifact. This is honest scope, not incompleteness.


Cross-Reference Conventions

Within the wiki

See [SSH Hardening](ssh-hardening.md) for the access-hardening sequence.

To repo artifacts outside the wiki

Paths are relative to the current page (wiki/<slug>.md), so up one level (../) is the repo root:

- [PLAN.md §1](../docs/PLAN.md)
- [infra/scripts/06-ufw.ps1](../infra/scripts/06-ufw.ps1)
- [infra/nginx/api.conf](../infra/nginx/api.conf)
- [content/foundations/ufw-firewall.md](../content/foundations/ufw-firewall.md)
  • No Obsidian wiki-links[[SSH Hardening]] does not render in plain markdown.
  • No bare URLs in body text — every link has visible link text.
  • No absolute paths in body linksC:\... breaks across machines. (The source self-reference is the one deliberate exception, per the reference-wiki convention it inherits.)

Every internal link — within the wiki or out to a repo artifact — must resolve to an existing file. Broken internal links are review failures. Do not link to scripts that do not yet exist (e.g. the planned 50-backup.ps1); mention them in prose as planned instead.


Source Field Conventions

What counts as an authoritative source

  • Governance: .claude/CLAUDE.md, docs/PLAN.md, docs/01-REPO-FOLDER-STRUCTURE.md
  • Executable artifacts: infra/scripts/*.ps1, infra/cloud-init.yaml, infra/nginx/*.conf, infra/systemd/*.service, infra/.env.example, .github/workflows/*.yml
  • Operator runbooks: content/**/*.md

What does NOT count

  • This wiki itself (it cannot bootstrap its own authority)
  • Conversation transcripts or scratch notes
  • Commit messages alone (cite the plan phase or artifact the commit landed under)

Citation precision

  • Cite the specific script or config file an entity owns.
  • Cite PLAN.md section anchors when describing a locked decision.
  • For scripts, cite the file; do not cite line numbers — they rot.

When to Add a Page

Add a wiki page when an entity:

  1. Has an owning infra artifact or a named subsystem in this repo, and
  2. Has non-trivial mechanics worth explaining beyond the runbook’s step list, and
  3. Is referenced by other entities (it’s an anchor, not a leaf).

Do not add a page for:

  • A script that does not yet exist in infra/
  • One-off implementation details better left as a code comment
  • Decisions — those live in PLAN.md

Maintenance

  • Update last-reviewed whenever the page is verified against the current artifact (not on every typo fix).
  • Promote draftcanonical only when every body claim is cited and the described behaviour has been verified on a real host.
  • When a plan phase or script changes an entity, update the page’s History and References in the same change.
  • Regenerate INDEX.md when a page is added, renamed, or has its type / status changed.

Reserved Filenames

FilePurpose
SCHEMA.mdThis file — the contract.
README.mdPurpose, conventions, authority hierarchy.
INDEX.mdCategorized list of every page in the wiki.

These filenames are reserved and must not be used as entity slugs.