No description
  • Go 54.9%
  • CSS 27.9%
  • HTML 13.8%
  • Shell 3.4%
Find a file
Arne Skaar Fismen 5b3911f85c
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
feedback: rename room to "Feedback → Posta"
The arrow reads more naturally than the em-dash for "feedback going to
Posta." Updates the actor doc name, the HTML page title, and the
archive page header. Tests use their own fixture names and don't
need to track this.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 14:04:35 +02:00
app-icon wip: typography polish, fonts, intro, app-icon assets 2026-05-13 19:23:47 +02:00
deploy bootstrap: use alpine/3.21 image (3.20 no longer in registry) 2026-05-09 10:27:16 +02:00
internal feedback room: /feedback as a Posta participant inside posta-web 2026-05-13 23:14:17 +02:00
static remove decorative clouds 2026-05-13 23:56:17 +02:00
templates remove decorative clouds 2026-05-13 23:56:17 +02:00
.gitignore wip: typography polish, fonts, intro, app-icon assets 2026-05-13 19:23:47 +02:00
.woodpecker.yaml ci: bump go 1.22 → 1.25, clone posta/spec before build 2026-05-13 23:16:56 +02:00
go.mod feedback room: /feedback as a Posta participant inside posta-web 2026-05-13 23:14:17 +02:00
go.sum feedback room: /feedback as a Posta participant inside posta-web 2026-05-13 23:14:17 +02:00
intro.md wip: typography polish, fonts, intro, app-icon assets 2026-05-13 19:23:47 +02:00
main.go feedback: rename room to "Feedback → Posta" 2026-05-14 14:04:35 +02:00
mark-night.png wip: typography polish, fonts, intro, app-icon assets 2026-05-13 19:23:47 +02:00
README.md feedback room: /feedback as a Posta participant inside posta-web 2026-05-13 23:14:17 +02:00
SPEC.md sync SPEC.md from posta/spec — key management + cache freshness 2026-05-12 20:53:15 +02:00

posta/web

The marketing/documentation site for posta, served by a single Go binary.

Layout

web/
├── main.go              HTTP server + spec-md cache
├── templates/
│   ├── layout.html      shared header/footer/nav
│   ├── index.html       /        — landing
│   ├── spec.html        /spec    — server-rendered SPEC.md
│   └── design.html      /design  — design system reference
├── static/
│   └── style.css        all visual decisions
└── go.mod

Templates and static files are embedded with embed.FS, so the binary is self-contained.

Run

go run . --listen :9495 --spec ../spec/SPEC.md

Flags:

  • --listen TCP listen address (default :9495).
  • --spec path to SPEC.md. Read on every request, re-rendered when mtime changes. Default ../spec/SPEC.md (assumes the posta/spec repo is a sibling).
  • --feedback-url canonical URL of the /feedback room (e.g. https://posta.no/feedback). Empty disables the room entirely; everything else still works.
  • --feedback-keys path to the room's keys.json (required with --feedback-url). Generate with posta-web genkeys --out <path>.
  • --feedback-db path to the room's SQLite database (required with --feedback-url). Created on first start.
  • --feedback-owner-url URL to pre-seed as a subscriber on first start (optional). Lets the operator's own client see the very first wrapped broadcast end-to-end.

/feedback room

When --feedback-url is set, posta-web mounts a Posta participant at that URL's path. GET returns the actor doc (kind: "room"); POST receives signed envelopes per SPEC §7. The room becomes stateful: SQLite database plus the keys file must live on a persistent volume.

Bootstrap order on a fresh deployment:

mkdir -p /var/lib/posta-web && chown posta:posta /var/lib/posta-web
chmod 0700 /var/lib/posta-web
posta-web genkeys --out /var/lib/posta-web/feedback-keys.json
# Then start the service with:
#   --feedback-url=https://posta.no/feedback
#   --feedback-keys=/var/lib/posta-web/feedback-keys.json
#   --feedback-db=/var/lib/posta-web/feedback.db
#   --feedback-owner-url=https://arne.posta.no

Subsequent restarts re-open the existing files. Pending schema migrations and outbound-row cleanup run automatically on every startup.

How /spec works

  1. The handler asks specCache.render() for the current HTML + TOC.
  2. The cache stats SPEC.md. If mtime hasn't advanced, return the cached HTML. Otherwise re-read, re-parse with goldmark, walk the AST to collect h2 + h3 headings into a TOC, and cache.
  3. The template inlines the rendered HTML and the TOC list.

This means edit SPEC.md and refresh — no rebuild, no JS rendering, no external dependencies at runtime.

Code highlighting

Goldmark's chroma integration emits <span class="ch-…"> tokens. Visual mapping lives in static/style.css under the .ch-chroma rules — the classes are mapped to the project's cream/forest palette directly, so the spec's code blocks share the same look as the home page's quickstart.

Design system

/design documents the palette, type scale, components, and CSS tokens used across both this site and any future surfaces. Treat it as the canonical reference when adding pages.