# cameron.stream Personal site for [cameron.stream](https://cameron.stream). Built with Hono + JSX, server-rendered, deployed to Fly.io. Blog content is stored as `site.standard.document` records on ATProtocol (PDS), not as local files. ## Setup ```bash pnpm install ``` The site needs no credentials for local or production reads. Blog and other protocol-native surfaces use public PDS APIs. The following are set in `fly.toml` for production but can be overridden locally: | Variable | Default | Description | |----------|---------|-------------| | `CAMERON_DID` | `did:plc:gfrmhdmjvxn2sjedzboeudef` | Author DID | | `PUBLICATION_URI` | (see fly.toml) | AT-URI of the `site.standard.publication` record | | `PORT` | `3002` (dev) / `8080` (prod) | Server port | | `HOST` | `0.0.0.0` | Server bind address | | `SITE_URL` | `https://cameron.stream` | Canonical site URL (used for OG tags) | | `SEMBLE_HANDLE` | `cameron.stream` | Bluesky handle for Semble page | | `ENABLE_MARGIN` | unset | Set to `"true"` to enable margin notes | The Git-backed About and Knowledge projection worker reads `CAMERON_BSKY_APP_PASSWORD` from its private systemd environment file. Do not put that credential in the repository or the Fly runtime. ## Development ```bash pnpm dev ``` Starts the dev server at `http://localhost:3002` with file watching. ## Type checking ```bash pnpm typecheck ``` ## Custom typefaces Around is the site's custom geometric unicase display face. Its source geometry, build environment, generated fonts, specimen, and design notes are all kept in this repository. See [`docs/around-typeface.md`](docs/around-typeface.md) before changing or regenerating it. Processional is a separate monumental unicase face derived from the Cosmic Liturgical Brutalism style guide. Its specimen is at `/type/processional`; the source and proofing workflow live in [`docs/processional-typeface.md`](docs/processional-typeface.md). ## Blog authority Blog posts stay in Leaflet. The repository contains no Blog Markdown copies and does not write or reconcile Blog records. Cameron.stream reads the Leaflet publication directly from the PDS at runtime. Create and edit posts in Leaflet. The About page is intentionally separate: `content/about.md` is Git-backed and projects to `stream.cameron.about/self`. See [`docs/public-content.md`](docs/public-content.md) for the authority split. ## Public knowledge Public Knowledge is a file-backed, linked knowledge base at `/knowledge`. It opens on a public NOW note and includes Entries, Semble Links, and Margin Annotations. Private Obsidian notes never enter the production build directly. Canonical architecture and operations: [`docs/public-knowledge.md`](docs/public-knowledge.md). ```bash # Convert an allowlisted Coil note into an ignored local draft. pnpm knowledge:stage "$HOME/Documents/The Coil/lessons/example.md" \ --summary "Public summary" \ --source "Primary source=https://example.com" # Validate staged and published entries. pnpm knowledge:check -- --include-drafts # Preview ignored drafts locally. Production never enables this flag. KNOWLEDGE_INCLUDE_DRAFTS=1 pnpm dev # After Cameron reviews the exact rendered draft and supplies a receipt. pnpm knowledge:promote example \ --reviewed-by Cameron \ --content-digest sha256:reviewed-file-digest \ --review-receipt-digest sha256:private-receipt-digest \ --confirm-public # Preview the reviewed Standard.site Knowledge projection without writing. pnpm knowledge:sync -- --all # After reviewed source reaches main, run the credential-provisioned worker. systemctl --user start cameron-site-content-sync.service systemctl --user show cameron-site-content-sync.service \ --property=ActiveState,SubState,Result,ExecMainStatus --no-pager # Install or refresh the isolated worker checkout and user units. deploy/systemd/install-content-sync-worker.sh ``` `knowledge/policy.json` is default-deny and owns the Obsidian source mappings. Draft Markdown is gitignored under `knowledge/staged/`. The Docker image copies only `knowledge/published/`, so a local draft cannot leak through a broad build context. Canonical Knowledge remains reviewed local Markdown. The projection worker reconciles only approved entries recorded through the review pipeline and stores public URI, CID, source-digest, and review-digest receipts in `knowledge/atproto-manifest.json`. The public file stores only a digest of the private route-scoped review receipt. Promotion, protocol mirroring, and deployment are separate actions joined by the worker. ## Deployment Deployed to Fly.io as `cameron-stream`. The normal Git-backed content path is the credential-provisioned worker above. A direct Fly deployment updates the site image only; it does not reconcile About or Knowledge records on ATProto: ```bash fly deploy ``` The Fly runtime does not need a PDS credential. Projection writes happen only through the guarded local worker. Do not invoke `scripts/sync-git-backed-content-from-origin.sh` from an ordinary shell: that shell normally lacks the worker credential and can deploy Fly successfully before failing at ATProto reconciliation. The installed service operates from a dedicated checkout under `~/.local/share/cameron-site/deploy-checkout`; human and agent work in `/home/cameron/code/cameron-site-tangled` cannot make the deploy checkout dirty or ahead of Tangled `main`. ## Stack - **Hono** -- HTTP framework with JSX support - **tsx** -- TypeScript execution (no build step) - **marked** + **shiki** -- Markdown rendering with syntax highlighting - **@atproto/api** -- ATProtocol client for PDS reads/writes - **ioredis** -- Optional caching layer ## Project structure ``` src/ index.tsx -- Routes and page shell data.ts -- Leaflet/PDS Blog and Bluesky data fetching leaflet-reader.ts -- Read-only Leaflet block conversion markdown.ts -- Markdown rendering pipeline cache.ts -- Redis/memory cache components/ -- Page components (JSX) public/ site.css -- Main stylesheet host-primitives.css host-theme.css theme.js -- Dark/light mode toggle knowledge/ policy.json -- Default-deny source mappings and privacy rules published/ -- Explicitly reviewed entries included in production content/ about.md -- Cameron-owned About source ```