Build log

Public, dated, short. Each milestone appends one entry; the marketing site renders this file.

2026-10-17 — Design settled

Brain and mouthpiece split, personalities inside a noggin, privacy levels, the router and cost optimiser, console and ops, outbound actions as human-only. Starter package assembled. Next: milestone 0, the shared UI on the design tokens.

2026-10-17 — Milestone 00: Monorepo scaffold and shared UI

pnpm workspaces for packages/ui, app, console, ops and site, plus a brain/ Python 3.12 project on uv. packages/ui has all thirteen components from the brand system, built only on design/tokens.css, with a light and a dark Storybook story for each; measured sizes, colours and radii match the design reference. Tests guard the tokens: no hex colour, font name or numeric radius anywhere in packages/ui, and tokens.json must agree with tokens.css. pnpm install && pnpm test && pnpm storybook work; the app, console, ops and site each build and render the wordmark. Next: milestone 01, the brain core.

2026-10-17 — Milestone 01: Brain core

The brain runs in Docker against Ollama on the host: pair with a one-time code, list voices, open a session and stream a reply from the local Reading coach over SSE (token, run, done), all from curl. Voices load from Markdown with a validated schema, and new ones are written from the short form; the starter voices are copied in on first start. memory.db holds sessions, messages and memory with nomic-embed-text embeddings in sqlite-vec, and a voice can only read its own scope plus shared. Every model call is written to an append-only runs.db before it is made, and only adapters/ may import a network client; both are tested, along with pairing and memory scoping. Next: milestone 02, the router, cloud connectors, redaction, consent and costs.

2026-10-17 — Milestone 02: Router, cost optimiser, audit and cloud adapters

Every reply is now routed: the privacy gate first (a Local only voice cannot reach a cloud model under any fallback or bias, tested across every combination), then what the host can run, the quality floor from rules.yaml, and the cheapest remaining model, with a session bias from the new adviser (Performance, Quality, Cost). Anthropic (official SDK) and one OpenAI-compatible host are wired in, with keys kept only in an Argon2id-encrypted secrets.enc. An Asks before sharing voice is redacted first (patterns, the owner’s names list, and a local model for other names) and asks once per session before its first cloud call; if redaction cannot run, the turn stays local. Each reply reports its model, tokens and cost, GET /v1/costs totals them from the append-only runs.db, ratings record learned weights for later, and scheduled jobs run through the same path, with Asks cloud jobs held until consent. Next: milestone 03, the talkto.allmynoggins.com PWA.

2026-10-17 — Milestone 03: talkto.allmynoggins.com (PWA)

From a phone with nothing installed but a browser, talkto.allmynoggins.com (Cloudflare Pages) pairs with the noggin on the founder’s Mac at noggin-mac.allmynoggins.net, lists the voices, streams a local reply with its model and cost, takes a rating, and installs to the home screen. The app has the voice picker with a New voice form, chat with the session adviser and the once-per-session consent card, and a settings sheet; theme and adviser choices are kept on the noggin, and the device stores only the pairing token and the address, which a test enforces. Each noggin now runs with its own Cloudflare Tunnel sidecar; Tailscale is out of the product, and end-to-end encryption is planned as milestone 05b. Next: milestone 04, speech and talk mode.

2026-10-17 — Milestone 04: Speech and talk mode

Talk mode works end to end from a phone on the Mac noggin: Whisper on the brain hears the owner, the local model answers, and Kokoro reads the reply aloud sentence by sentence over the /v1/sessions/{id}/audio WebSocket, with a SpeechRun committed before every engine call and the processing caption built from the backends actually chosen. Talk is a conversation after one tap: a pause ends each turn, the mic reopens when the voice finishes, a silent turn closes it, and a tap interrupts the voice; a friction test holds a five-turn conversation to one tap. The chat composer’s mic opens talk mode. ElevenLabs, Deepgram and OpenAI speech are built and tested against recorded request shapes; the live ElevenLabs check for a Uses the web voice waits for the owner’s key. Clips are sent as WAV or MP3 per engine rather than Opus. Next: milestone 05, export, import, personality archives and packaging.

2026-10-17 — Milestone 05: Export, import, personality archives and packaging

A noggin moves as one encrypted archive: export from one folder, import into another, start it and pair a new device with a fresh code (proved locally, with the command line and the binary); a single voice travels on its own with its memory, prompts, learned weights and ratings. memory.db can be encrypted at rest with SQLCipher and an Argon2id key (opt-in, noggin encrypt), every deletion leaves no residue in the files, and the app’s settings sheet offers export, voice deletion, clearing the audit log and a wipe beside the ownership statement. noggin doctor names each problem with its fix, noggin update backs up first and rolled itself back from a deliberately broken image in a real Docker trial, backups run daily and keep 7, and a voice missing its model shows Install llama3.1:8b (4.9 GB) with progress. The image builds for arm64 and amd64 with a health check, and a 28 MB binary runs without Docker. Waiting for the owner: publishing the image and binaries (the allmynoggins GitHub organisation), the move to the Hetzner server, and turning on encryption and backups on the Mac noggin with a passphrase. Next: milestone 05b, end-to-end encryption.

2026-10-17 — Milestone 05b: End-to-end encryption

The owner can turn on end-to-end encryption between the app and a noggin (e2e: off | on | required in config.yaml, or the switch in the app’s settings): the app pairs by SPAKE2 over the one-time code, which never crosses the network, keeps one pairing secret in place of its token, and sends every request sealed with XChaCha20-Poly1305 inside one envelope route, with replies, streams and talk-mode audio sealed the same way. A recording proxy in front of the brain sees no message, reply, route, id or key through a full chat and talk session; a wrong code or a substituted exchange fails pairing; changed, replayed or cut frames are refused; with e2e: off nothing changes. Settings and noggin safety-number show the same safety number, and Settings says plainly what stays visible: that a call was made, when, and how big. The Python and browser sides are checked against shared vectors, but the protocol code has not been independently reviewed yet. Waiting for the owner: turning it on for the Mac noggin and re-pairing the phone, a security review, and the [decide] on console-paired devices. Next: milestone 06.

2026-10-18 — Milestone 06: Console and accounts

The console signs owners up and in with a passkey or through Auth.js with Google and Apple, keeps one HTTP-only session on the base domain, claims a subdomain (with the reserved list), and keeps pointers to noggins with their status (online, offline since, paused, unavailable), Create with Run it myself steps, and Manage (rename, pause, export, move, link, remove with export offered first beside the ownership statement, which is also accepted at sign-up and at the first noggin). A schema test holds Postgres to pointers and settings. Open mints a five-minute, single-use Ed25519 pairing token and opens talkto.allmynoggins.com with it in the fragment; the brain verifies it with only the console’s public key, which noggin link gives it along with an authenticated 60-second heartbeat. Proved locally end to end: a passkey sign-up, a linked brain on a temporary folder showing online, one tap on Open, and the app paired and listing voices. Waiting for the owner: Google and Apple credentials, the Neon database, the console’s secrets, and where to deploy it (the Cloudflare adapters now need Next 15 and React 19; next build works). Next: milestone 06b, the install package generator.

2026-10-18 — Milestone 06b: Install packages

Run it myself now gives one download per platform (Mac, Windows, Linux, a server, a cloud server), rendered from one set of templates: the console makes the noggin’s Cloudflare Tunnel, route and <name>.allmynoggins.net record itself, so the owner never opens Cloudflare or sees a token, and the package’s only secrets are its five-minute link and the tunnel key. The installer links first, installs or reuses Docker and Ollama, pulls the model for the machine’s memory, starts the noggin with its tunnel and at every start, firewalls servers, ends with Paired and a QR code for the app’s new Scan pairing code; the console page turns Online by itself. Proved in throwaway containers: every Linux target dry-runs on Debian, a second run on an installed host changes nothing, a third repairs a stopped noggin and a missing model, and PowerShell parses and dry-runs the Windows installer; the console’s Cloudflare client is tested against a stand-in API, and Playwright links a real brain with a downloaded package’s link. Waiting for the owner: a Cloudflare API token, publishing the image, and a first real install on a Mac, a Windows PC, a VPS and a cloud VM (none was run for real here). Next: milestone 07.

2026-10-18 — Milestone 07: Ops console and provider adapters

Ops runs at ops.<base> as its own Next.js app on the console’s database: staff sign in only with a passkey registered to an address at exactly allmynoggins.com or allmynoggins.net (checked at creation, every sign-in and every request; no OIDC), the first one made by an ops-user command on the server; providers, tiers, accounts (search, suspend, delete with export offered first and two-person approval), fleet, templates, settings, audit and health all work, and every action writes an audit row. The HostingProvider interface and an experimental Hetzner Cloud adapter live in console/lib/providers/, tested against a stand-in API, with credentials read by name from the worker’s secret store and never stored in Postgres; none is enabled. Proved in Playwright against a throwaway Postgres: a domain-only bootstrap, passkey enrolment and sign-in, a tier configured, and Host it for me hidden, shown once Hetzner Cloud is enabled, hidden again once disabled. Waiting for the owner: deploying ops beside the console, the first ops user (and a second), and a real trial of the Hetzner adapter before enabling it; creating hosted noggins is not built. Next: milestone 08.

2026-10-18 — Milestone 08: Marketing site and designer

allmynoggins.com is an Astro site with the build log and every doc rendered from docs/, a privacy page (email only, no tracking, server-side counts only) and the interest-list form posting to Buttondown; it loads nothing from any third party (self-hosted fonts, no framework code, a content security policy), and tests prove it. The home page is deliberately a placeholder while the owner designs a new one; the redacted voice-card pipeline is built and tested, showing the starter templates as labelled stand-ins. The designer works: a short interview, a drafted system prompt to edit or revise, and a personality archive sealed in the browser with made_with. In the app (New voice → Design it with me) the noggin’s own built-in _designer voice drafts it and Add to my noggin imports it; at designmynoggin the trial runs on POST /v1/designer/session, capped per session and per address and logging token counts only, and the visitor downloads the voice. The brain opens an archive written by the browser. Waiting for the owner: the new home page design, which real voices to show, Buttondown, the Pages projects and domains, and the trial’s API key (without it a visitor without a noggin cannot design yet). Next: the owner’s items above.

2026-10-18 — Milestone 09: allmynoggins.com home page

The home page is built to the design (hero A, light and dark with a remembered switch, phone and desktop): a scroll-driven How it works drawn by one small first-party script, which becomes a static list of the four steps with a still of each under reduced motion or without a script; principles and the three privacy levels; Meet my noggins from the redacted voice cards, each ending with a model and cost line; Run it anywhere; owner responsibility; the newest three build-log entries; and Follow the build. Every line is true today: learning, web reading, installers and hosting are worded as what is built, the hero strip comes from a data file, and hosting and console sign-in sit behind build flags, tested both ways. The interest list moved from Buttondown to our own Pages Function and Cloudflare D1, storing email and date only, rate-limited without storing anything more; an address submitted through the page under wrangler pages dev landed in a local D1 table. The site still loads nothing from any third party. Waiting for the owner: creating the D1 database and deploying (infra/SETUP.md), which real voices to show, and turning the flags on when the console and hosting are live. Next: milestone 10.

2026-10-18 — Milestone 10: Console to the design

The console now lives at <slug>.allmynoggins.com/console (the root and the old paths redirect) and follows the design in light and dark, phone and desktop: a split sign-in with passkeys, Google and Apple (no password), Your noggins with model spend by voice, Add a noggin (Bring your own noggin; Move in with us only behind the ops hosting flag, with placeholder servers and nothing that can be bought), Pair a phone (a QR code of the console’s own single-use pairing link, with its countdown) and Manage (voices table, Export, Move house, Delete). A noggin’s heartbeat now carries this month’s spend, replies and main model per voice; the console holds them in memory only (a test watches every statement and every stored row), shows them only while the noggin is online, and a brain with e2e: required does not send them. Delete and Move house hand off to the app, since the console has no path to a brain; Remove from console only stays. curl -fsSL https://get.allmynoggins.com/<one-time-code> | sh serves a noggin’s server installer once, minted by the console for ten minutes. Waiting for the owner: deploying the console with get.allmynoggins.com on its tunnel, and the real hosting catalogue. Next: milestone 10b.

2026-10-18 — Milestone 10b: talkto sign-in

talkto now signs in with the console account: Sign in goes to the console’s own page (passkey, Google or Apple) and straight back, the app lists your noggins with their live status, and tapping one pairs the phone without a code by exchanging a single-use console token at the noggin; a refused token is renewed silently while signed in, and an end-to-end noggin asks once for an E2- code instead. The phone still stores only each noggin’s address and token, plus the console’s HTTP-only cookie that no script can read; Sign out forgets every token and ends the session, and the console’s Account → Signed-in devices can sign any browser out (which stops new pairing tokens; tokens a phone already holds are cut only at the noggin, for now by a wipe). Codes and Scan pairing code remain, a phone paired before this carries on unchanged, and without a reachable console the app is the code-only app it was. Proved locally with the console’s Playwright test on *.noggins.localhost and a real brain; it cannot be tried at talkto.allmynoggins.com until the console is deployed. Next: milestone 11

2026-10-18 — Milestone 11: Ops to the design

Ops now opens on the design’s four tabs, light and dark, phone and desktop: Overview (interest list, owner consoles, noggins online, installer downloads by platform and install-to-pair, 30-day sign-ups; hosted noggins only behind the hosting flag), Consoles (searchable, masked email, every search audited), Hosting (capacity per catalogue server, warning above 85%, behind the flag) and Site status; the milestone 07 screens sit in a second row. Every number is real or says Not measured yet. The console counts packages by platform and first heartbeats that follow one (a number per metric per day, nothing else); ops probes the platform’s own public addresses once a minute and keeps 30 days of counts and latency histograms, and the incident banner shows only what those probes found. The interest list’s size comes from a token-protected count endpoint on the site’s Pages Function, so no address reaches ops. The console’s rare live.test.ts failure was a timestamp’s milliseconds containing the test’s 0.92, now fixed. Waiting for the owner: deploying ops and the console, the INTEREST_COUNT_TOKEN secret on the site and ops, and the real hosting catalogue. Next: the owner’s choice.

2026-10-24 — Try-out fixes

The local try-out (console, talkto, the demo noggin, the site) ran end to end: account by passkey, a noggin linked by noggin link, Online in the console, opened in talkto without a code. What it found, all fixed: the console’s sign-in now makes Create an account a button and explains a passkey prompt that finds nothing; the copy buttons fall back when the browser offers no clipboard (http on *.localhost) and select the command if both fail, instead of failing silently; Link by hand leads with the plain noggin link command and no longer names brain/docker-compose.yml, which on a machine with several noggins links the wrong one (on this Mac, noggin-mac; nothing was changed there); the Manage and Pair pages name the configured talkto address. The brain now tells every voice what it really knows (an empty memory is said out loud, recalled memories are the only ones) and that it has no tools yet, after llama3.1:8b invented a remembered passport and hotel searches for the travel agent; talkto keeps a reply’s line breaks and shows Markdown bold, and spoken replies drop Markdown marks. The tour in docs/RESUME.md matches the screens. Owner decisions taken: Read tools as milestone 12b, including site logins under safeguards still to decide. Tests: brain 543, console 295 + 29 Playwright, ops 177, app 155, ui 123, site 80, designer 10. Next: milestone 12.

2026-10-24 — Milestone 12: Shared speech services and the gpu-server preset

A machine that runs several noggins now shares one Whisper and one Kokoro between them on a private Docker network, engines, with no port on the machine: new whisper_http and kokoro_http adapters (same host, so every privacy level may use them), probed with the host snapshot and listed at /v1/health and, by name and state only, in the heartbeat. A new install target, gpu-server, starts the services from one compose file whose cpu and cuda profiles are chosen by /srv/engines/.env, joins each noggin to the network with the built-in speech engines off, lets the containers reach the host’s Ollama behind a firewall rule, and noggin doctor checks both services. Proved on this Mac with the CPU images: two noggins in Docker heard “Try the old wives’ tale and keep the chapters short.” exactly and answered aloud through the shared services; with the services stopped both fell back to the device’s voice and said so on the talk screen; started again, they picked them back up by themselves. The same files validate for ENGINES_DEVICE=cuda. Tests: brain 561, console 305 (including the installers run in containers, the gpu-server dry run in Debian among them) + 29 Playwright, ops 177, app 155, ui 123, site 80, designer 10. Next: gpu-1 on Monday (check the Speaches CUDA image on the Blackwell card, infra/SETUP.md), then milestone 12b or 12c.