01

The build log

Built in the open. Every change, dated. The machine-readable version lives in the repo.

2026-09-06

site profiles keep their receipts

Encoded profile paths preserve each stored URL, including percent escapes.

Reruns show their exact server receipt and date. Rank waits for that receipt in the shared record, with a manual recheck when storage is delayed.

Device-only trials link to the original page until their receipt is shared.

Added synthetic store, route, metadata and browser regression checks.

2026-09-06

app-wide model pause

Added `DC_FORCE_OFFLINE=1` for every app model path, including the local voice studio. Artwork uses its deterministic fallbacks; voice drafting reports offline while manual writing, checks, and edition review remain available.

Documented restart and deployment requirements. External tools consuming exported or MCP context still control their own model calls.

Added synthetic regression checks for key-present offline behavior, feed threshold chaining, restored selection, and accurate voice readiness.

2026-09-06

one build log

The public build log now reads this file during the build. Its earlier summaries remain beside the detailed entries, including the two July 3 notes.

Kept the dated timeline and added checks for wrapped text, repeated headings, mobile layout, keyboard navigation, and safe text rendering.

2026-09-06

public metadata follows the voice

Named the homepage's shared writing voice in its search and social title.

Added `llms.txt` with the public pages, local voice boundary, and the original artwork and project links. The README now describes the public site and local studio without a temporary branch or deployment-status claim.

2026-09-06

voice studio review handoff

Still means still

The public facet crystal now changes without a rotation transition when reduced motion is selected. Browser checks cover the public demo and private studio.

Fixed the public facet crystal's rotation transition under reduced motion. Browser checks now verify that both writing surfaces stay still.

Recorded the successful CI run for the studio, portable editions, and software graphics fix: all 43 browser checks passed without retries, with the other gates green. PR #142 is ready for code review. Private edition approval and human voice recognition remain separate, pending decisions.

2026-09-05

a studio for the voice

The voice gets a studio

Private voice editions can travel through a local command and MCP, with a version receipt. The writing studio keeps facts beside the draft and turns selected corrections into candidates for Kris to review. The public entry explains that work through fictional examples. The original artwork lives at /art. Mechanical checks are covered; Kris's source approval and real voice recognition remain separate decisions.

Kept the moving crystal usable on known software graphics with a lit obsidian material. Hardware graphics retain glass refraction. Added a forced software browser check for feeding, navigation, and keyboard crystal controls.

Retained synthetic CI browser failure traces for seven days so browser failures can be diagnosed from requests, console errors, and page state.

Kept writing surfaces still until the living crystal is explicitly selected. Animated scenes now use a bounded render clock and pause offscreen so text controls do not compete with continuous graphics work.

Replaced the local audition with a writing studio: factual anchors, facet comparison, revision, editable drafts, exact receipts, and specific findings. Your own words can be checked offline without a model call.

Added signed local sessions for private review, candidate creation, approval, and rollback. Private pages never initialize analytics on loopback hosts.

Added selected correction evidence with piece, facet, lexicon, and core scope. Lasting changes require exact candidate review and approval. Candidate auditions are explicit; ordinary tools continue using the approved edition.

Led the public entry with portable authorship and a fictional facet demo. Preserved the original artwork at `/art`, including existing presenter and track links. The crystal follows the facet and has keyboard/static alternatives.

Updated browser, source, and correction regression coverage. Real source approval and the 40-output recognition pilot still require Kris's decisions.

2026-09-05

private voice editions

Added candidate review, explicit approval, and rollback to saved private voice editions. Working edits cannot change the edition used by the CLI and audition.

Kept packet fingerprints stable through one shared compiler. Corrupt or stale editions fail loading; writes use private permissions and an atomic pointer.

Added regression checks for source independence, exact rollback, stale approvals, interrupted writes, unsafe paths, and CLI parity.

Added a local MCP adapter and explicit facet export using the same approved context. Tools can load and check; they cannot approve or send. Both 2025 and 2026 protocol connections are covered by a real SDK client subprocess.

No private source has been approved by this implementation. The portable studio roadmap and real voice recognition checks remain in progress.

2026-09-04

Kris, loaded

Added a four-file private voice packet with explicit review state and a shared fingerprint for the local agent command and Crystal audition.

Added inspect, context, and check commands. The audition uses explicit facets, preserves the brief through failures, and reports source, generation, and checks.

Removed invented offline receipts. Runtime checks reject invalid rules and suppression markers; advisory findings remain visible for a human read.

Kept private reads outside public requests and build traces. Disabled automatic Vercel deployment for the review branch only.

Added synthetic packet/API tests and browser checks for mobile, keyboard, missing-source, failure, and reduced-motion behavior. Real voice review is pending.

Corrected Varlock's on/off declarations for environment strings and checked the enabled local-audition setting in CI.

2026-08-15

the wider signal gets a map

Added the shared Signal Atlas as the first route out of Dark Crystal's network footer, with direct neighboring signals for Gorgeous Ghost and Ghost Radio.

Added a browser regression check for all three public routes.

2026-07-12

configuration and voice gate coherence

Added `.env.schema` as the Varlock contract for every runtime, test, and utility variable, plus redacted validation/audit commands and a CI gate.

Documented `.env.example` as setup only and routed local commands through `npm run env:run -- <command>`.

Added three checker tests and made an invalid anti-glossary regex fail the checker configuration instead of quietly weakening the gate.

Clarified ownership: the private `kk-voice` corpus owns the rules; Dark Crystal owns the executable checker.

2026-07-12

quieter delivery automation

Removed the Actions auto-merge polling loop. Shipping agents now enable GitHub native auto-merge directly when requested.

Added cancellation for superseded CI runs on the same pull request.

2026-07-06

search reports get a playbook

Added `docs/SEARCH-OPS.md` so Dark Crystal has one place for the GA4 property, Search Console Domain property, DNS TXT, sitemap status, GA/Search Console product link, weekly read, and page-level search bets.

Corrected STATUS to the real GA4 property ID (`544264134`), current production deployment receipt, and the July 6 product link from `darkcrystal.app` Search Console to the `Dark Crystal Web` stream.

Linked the playbook from README so the public demo URL, search receipts, and report-reading loop sit beside the run instructions.

2026-07-05

Agents of Chaos, second pass

Cut the duplicate certificate photo down to one, added the Luma event cover art up top, and turned the full-day gallery into a click-to-open thumbnail grid (with keyboard nav) instead of nine full-size cards.

Linked every company and person named on the page to a real source: FUNK (map), Devin Events BC and Cognition (their sites), Jory and Jacky Zhong (Luma/social profiles).

2026-07-05

copyright and AI draft packet

Drafted `docs/thought-leadership/artists-learn-machines-extract.md` as a LinkedIn-ready response to Morgane Oger's copyright and AI question, with source notes kept beside it.

Added a designed 1200x630 quote-card graphic plus a raw LinkedIn-thread screenshot receipt under `docs/thought-leadership/assets/`.

2026-07-05

Agents of Chaos gets its own page

Added `/agents-of-chaos`: the Devin Hackathon event recap, honest as-announced vs. as-judged prize categories, Dark Crystal's own award (moved from colophon), and a 9-photo gallery of the full hackathon day credited to Michelle Diamond, Diamond's Edge Photography.

Trimmed colophon's award section to a teaser linking to the new page, and pointed the nav Winner badge there instead of `/colophon#award`.

2026-07-05

Search Console gets the crystal

Verified the `darkcrystal.app` Domain property in Google Search Console with a root DNS TXT record at Porkbun.

Submitted `https://darkcrystal.app/sitemap.xml`; Google read it successfully with 8 discovered pages.

Checked `/`, `/trial`, and `/statement`: the homepage is indexed, while the other two routes pass live indexability tests and are waiting on Google's crawl queue.

2026-07-05

analytics joins the BC + AI house

Created the `Dark Crystal` GA4 property under the `BC + AI Ecosystem` Analytics account, with one web stream for `https://darkcrystal.app` and enhanced measurement off.

Set `NEXT_PUBLIC_GA_MEASUREMENT_ID` in Vercel Production, redeployed `darkcrystal.app`, and verified the live page now ships the GA tag while robots.txt and sitemap.xml still answer cleanly.

2026-07-05

search gets a map

Added route-specific metadata, canonical URLs, robots.txt, sitemap.xml, and homepage JSON-LD so `darkcrystal.app` has clean search receipts.

Wired optional GA4 pageview collection behind `NEXT_PUBLIC_GA_MEASUREMENT_ID` with no custom visitor traits. `/merch` and `/leaderboard` stay live for humans but out of the index.

2026-07-05

darkcrystal.app becomes the front door

Set the GitHub project homepage and description, then moved README and STATUS around `https://darkcrystal.app/` as the canonical public surface. Vercel URLs stay only as fallback and deployment receipts.

2026-07-05

darkcrystal.app gets the keys

Wired `darkcrystal.app` and `www.darkcrystal.app` into the Vercel project, verified both domains, and moved app metadata off the scoped Vercel URL.

Updated the demo crib so the stage URL is the real domain now. The old scoped Vercel URL stays a fallback, and `dark-crystal.vercel.app` is still somebody else's dead end.

2026-07-05

automated update

2026-07-05

automated update

Fix changelog workflow: route through a PR instead of a direct push to main (#64)

2026-07-05

automated update

chore: automated changelog update

Wire the delivery loop: label + open-issue gate, real repo settings (closes #17) (#57)

Close issue #5: Claude agent + kk-voice facet routing (#58)

auto-merge: explicitly close the linked issue on merge (follow-up to #57) (#59)

auto-merge: close linked issue inline (fix the closed-trigger recursion gap) (#60)

Fix real production reliability bug: FEED could take 13-27+ seconds (#61)

Fix audio-engineering defects in the 8 extended remix tracks (#55) (#62)

Add the public leaderboard: every /trial submission, ranked (#63)

2026-07-05

automated update

chore: automated changelog update

Colophon: credit Devin/Cognition as build partner, list the missing tools (#56)

2026-07-05

automated update

Fix mini-player showing Ethos Block Party, theme the deck to Dark Crystal

chore: automated changelog update

2026-07-05

automated update

chore: automated changelog update

Post-hackathon polish pass: docs, design tokens, dead code, STATUS.md (#53)

chore: automated changelog update

Wire facet backgrounds + logo lockup set (closes #13) (#51)

2026-07-05

automated update

chore: automated changelog update

Curate footer network list to Kris's actual list (#54)

2026-07-05

automated update

chore: automated changelog update

Shrink hero, widen feed box, auto-chain weaponize after refusal (#49)

2026-07-04

automated update

chore: automated changelog update

Colophon art gallery expansion + new rafiki design assets (#39)

2026-07-04

automated update

chore: automated changelog update

Wire soundtrack to order/chaos mode, closing issue #21 (#50)

2026-07-04 hacking hour 8

the colophon catches up to the day

chore: automated changelog update

Fix colophon staleness: crystal, brain, and build-partner rows

Kris asked what needed updating on /statement, /lab, and /colophon given everything built today. The colophon had gone stale in three real spots, not just missing nice-to-haves.

"3D crystal" still described MeshTransmissionMaterial as a "final target" when it shipped hours ago; now it names what's actually running (the material, the trapped-core render-order cheat, reverse-phi edges) and points back at /lab where the technique was proven first.

"Brain" claimed five-facet voice routing, which is real but hasn't landed in this app yet (that's still ahead); now it describes what's actually live, one reconstructed voice, a deterministic judge, an inert-until-keyed live layer.

"Build partner" still credited Devin; it's been Claude Code the whole way. Also dropped "the night before a hackathon," since the vertical slice landed pre-dawn that day, not the prior night.

"Voice" row gained one true sentence: the same checker that gates this prose also runs live on whatever a visitor feeds the crystal.

Left the statement page alone (evergreen, not tech-status-dependent) and didn't touch /lab (a smaller, separate suggestion, not approved).

Re-audited right before shipping, after this same reconciliation and another ~25 commits (gesture control, the weaponize engine, merch mock, photo roast, the /portal audio player) had already landed: the same three rows were still stale, untouched by any of it.

2026-07-04

album cover art, first draft pass

Album cover art, first pass

Rafiki generated flash-draft candidates for all 8 tracks. Four starred as keepers, one rejected, three still undecided; the starred four get re-run at full resolution next.

2026-07-04

automated update

chore: automated changelog update

Add the URL Slop Trial: Live Duel between Order and Chaos voices (#47)

2026-07-04

automated update

chore: automated changelog update

Sync README to what's actually shipped (portal, homepage rubric case, social previews) (#46)

2026-07-04

automated update

chore: automated changelog update

Give each nav page its own social share preview (#45)

2026-07-04

automated update

chore: automated changelog update

Demo readability + fix wordmark breaking mid-word in Chaos mode (#44)

2026-07-04

automated update

chore: automated changelog update

Fill in today's changelog, fix the deck's shape, mount it on the homepage (#43)

2026-07-04

automated update

chore: automated changelog update

Tame the harsh white specular streak as the crystal rotates (#42)

2026-07-04

The record joins the rubric

The judging-criteria case now lives on the main page too, and the portal was brought in line to match.

chore: automated changelog update

Add the judging-criteria case to the main page, align the portal to match (#41)

2026-07-04

The feed box gets room to breathe

Widened and given more height. It was too cramped to paste a real paragraph of slop into.

chore: automated changelog update

Make the feed box bigger (#40)

2026-07-04

Demo receipts

Screenshots, presentation notes, a capture script, and the real judging criteria, all committed so the pitch has paper to back it up.

chore: automated changelog update

Demo receipts: screenshots, presentation notes, capture script, real judging criteria (#37)

Rafiki generated flash-draft candidates for all 8 album covers. Four starred as keepers: `02 The One Who Says No`, `03 Back Alley Gospel`, `06 Receipts`, `07 Still Point`. One rejected: `04 Crew`. Three still undecided: `01 Crystallize`, `05 Faux Work`, `08 More Beautiful World`.

Next: re-run the four starred keepers at `pro` 2K/4K per the album cover spec in `design/rafiki/RAFIKI.md`.

2026-07-04

three parallel builds reconciled into one

2026-07-04

The portal: the record gets a player

All 8 tracks extended into 6-10 minute reworks, each with its own intro, outro, and drop, built from stems Demucs pulled apart earlier today. A new /portal page mounts them in a real Winamp-style deck (Kris's own player, wired in from GitHub), covers and all, alongside a hero loop video study.

chore: automated changelog update

Add the /portal audio player: 8 extended tracks, covers, and the hero loop (#38)

2026-07-04

README and AGENTS.md, synced

Both brought current with everything actually shipped today, not the plan from this morning.

chore: automated changelog update

Sync README/AGENTS.md to today's shipped state (#36)

2026-07-04

FEED and roast get real stage presence

Both results now get the same visual weight as the refusal onscreen, instead of reading as an afterthought next to it.

chore: automated changelog update

Give FEED and roast results the same stage presence as the refusal (#34)

2026-07-04

The crystal meets the brand

Soft glow and real display type brought the live crystal in line with the brand identity page instead of drifting from it.

chore: automated changelog update

Match the live crystal to the brand identity page: soft glow, real display type (#33)

2026-07-04

automated update

chore: automated changelog update

Tag the demo fixtures as intentional slop (vc:ok); crib prose itself is clean

2026-07-04

The three minutes, locked

The stage script against the real rubric: the one-breath explanation, five beats, three paste-ready fixtures. Demo fixtures tagged as intentional slop so the voice checker doesn't flag its own bait.

chore: automated changelog update

Demo crib: the locked three minutes against the real rubric

2026-07-04

automated update

chore: automated changelog update

Add merch storefront mock (issue #15) (#29)

2026-07-04

automated update

chore: automated changelog update

Add in-app photo roast, sandboxed to whatever you hand it (issue #7) (#30)

2026-07-04

automated update

chore: automated changelog update

Add MediaPipe Hands gesture control to the crystal (issue #4) (#31)

2026-07-04

automated update

chore: automated changelog update

Add chaos direction: weaponize engine mirrors the order-mode de-slop pipeline (#32)

2026-07-04

The real judging criteria land

Reconciled against the real emailed rubric: three prizes, not the four quadrants from the kickoff transcript. Shipped alongside: MediaPipe Hands gesture control for the crystal, an in-app photo roast (sandboxed), a merch storefront mock, and the anti-slop engine's chaos-mode counterpart, a weaponize direction that mirrors the order-mode de-slop pipeline.

chore: automated changelog update

Reconcile the real judging criteria (three prizes, not four quadrants) (#28)

2026-07-04

Agent onboarding, documented

Knowledge, playbook, and swarm automation written up so the next agent picking up this repo isn't starting cold.

chore: automated changelog update

Document the agent onboarding: knowledge + playbook + swarm automation

2026-07-04

The Mirror, reconciled

Three sessions today built overlapping scope as separate PRs. Kept the most complete one as the base, ported over CI's widened voicecheck scan (now covers .tsx/.ts/.jsx/.js, not just prose files) and the Rafiki design work from the others. Rehearsing the merged result surfaced one real bug neither PR's own tests caught: a feeding that tips the chaos meter over threshold could show its plain rewrite under the refusal banner instead of an actual refusal line. Fixed.

chore: automated changelog update

The Mirror: FEED→CHAOS→REFUSAL→GIFT, reconciled from #22/#23/#24

Three sessions today built overlapping scope as separate PRs (#22, #23, #24). Kept #24 as the base: it had everything #22 built plus the crystal material upgrade, the reverse-phi integration, a more principled slop score, and a real bug caught by actually rehearsing the demo.

Ported the two things #22 had that #24 didn't: CI's voicecheck step now scans `.tsx/.ts/.jsx/.js`, not just `md/html/txt` (today's FEED UI prose lives in components, invisible to CI before this). `.gitignore` unions both PRs' env-file rules.

Widening the CI check surfaced real flags: `lib/judge/rewrite.ts`'s banned-word lookup table needed `vc:ok` on every line (it necessarily names the words it swaps out), and two genuine misses turned up outside that file: an accidental em dash in a `lib/motion.ts` comment (fixed, not annotated) and a deliberate callout in `app/statement/page.tsx` that names one specific brochure word to reject it outright (annotated, matching OS.md's own documented pattern for a banned term quoted on purpose).

Layered #23's design work on top: the Rafiki prompt library, the favicon/social-preview/colophon-gallery wiring, and the unused default SVG cleanup. `CHANGELOG.md` and `.agents/CHANGELOG.md` both had #23 and #24 prepending different entries at the same anchor line; combined rather than picked one.

Found one real integration bug rehearsing the merged result, not caught by either PR's own tests: a feeding that the judge scores as an ordinary gift can still be the one that tips the cumulative chaos meter over the threshold, and the overlay was showing that feeding's plain rewrite under the "order facet interrupts" banner instead of an actual refusal. `lib/judge/lines.ts` gained `THRESHOLD_REFUSAL_LINES`; the route now picks one whenever the meter crosses threshold on a feeding that wasn't already a content-based refusal.

2026-07-04 hacking hour 7

The voice gate becomes a skill

The vendored voice checker is now a real skill (skills/voicecheck/SKILL.md) instead of a bash command an agent has to remember. Verified against a paragraph stuffed with nine banned words (all nine flagged) and a clean paragraph (zero flags).

Another zero-overlap pick while the PR #22/#23/#24 reconciliation continued separately: issue #16, wrapping the vendored voice checker as a real skill (`skills/voicecheck/SKILL.md`) instead of a bash command an agent has to remember.

Verified the acceptance criteria directly: fed it a paragraph stuffed with nine banned words and cadences (it flagged all nine, exit code 1) and a clean paragraph (zero flags, exit code 0).

`skills/ROSTER.md` updated to mark `voicecheck` built, matching how `hackathon-kit` is already listed.

2026-07-04 hacking hour 6

The album finishes its lyric sheet

Five new tracks written: Crystallize, The One Who Says No, Crew, Faux Work, and Still Point. All 8 tracks on the record now have lyrics, every one passing the voice checker vendored in this repo.

While the duplicate-build situation across PRs #22/#23/#24 got sorted out, picked up a genuinely separate, zero-overlap piece of the backlog: issue #12, finishing the album's lyric set.

Five new tracks: Crystallize (the intro, almost wordless on purpose), The One Who Says No (the order facet's refusal, in song), Crew (a real call-and-response for the community), Faux Work (a satire track that weaponizes corporate slop against itself, on purpose), and Still Point (the quiet, human center of the record). All 8 tracks are now written.

Checked PR #23's diff first, since it also touched album/ALBUM.md and album/suno-prompts.md: it had already drafted a good arrangement note (tracks should open on a long instrumental groove before any lyric lands) and updated two tracks' structure to match. Merged that in rather than overwrite it, then applied the same principle to the five new tracks.

Every lyric file passes the voice checker vendored in this repo, including three tracks with intentional, in-file-documented overrides where a banned word or LLM cadence is quoted on purpose so the lyric can reject it by name.

2026-07-04 hacking hour 5

Rehearsed, twice, clean

Ran the full demo arc end to end twice with Playwright driving a real browser: Order to Chaos and back, both slop fixtures, the REFUSAL firing, the honestly-human line getting praised instead of rewritten. Zero console or network errors. One real finding from actually rehearsing it: the REFUSAL overlay's 3.6-second window was too short to gesture at and read aloud. Extended to 7 seconds.

Ran the full docs/DEMO_SCRIPT.md arc end to end twice (Playwright driving a real browser against the real app, not a mock): open on Order, flip to Chaos and back, feed the corporate-slop fixture, feed the LLM-tell fixture (which crosses the chaos threshold), watch the REFUSAL fire, feed the already-human line and watch it get praised instead of rewritten. Zero console or network errors across both runs. The second run went through the manual ?offline=1 toggle end to end and produced identical results.

One real finding from actually rehearsing it, not just unit-testing the pieces: the REFUSAL overlay's original 3.6-second display window was too short for a presenter to gesture at the screen and say the line out loud. Extended it to 7 seconds.

Stretch goals not attempted today, by deliberate call, not an oversight: MediaPipe gesture control (issue #4, explicitly gated on "green by 13:30" in the original plan, and the whole FEED/GIFT/REFUSAL arc was still unbuilt at that point) and soundtrack state (issue #21). Both are "archived, not dead" per the cut list; the arc itself is the demo.

Final npm run build and npm run eval green; voicecheck clean across every file touched this session.

2026-07-04 hacking hour 4

The eval runner actually exercises the arc

npm run eval now behaviorally checks all 10 gold-set cases directly against lib/judge and lib/chaos: scores, tells, gift/praise routing, chaos accumulation, the refusal threshold, and the offline path's zero-network guarantee. 31/31 green.

npm run eval now imports lib/judge and lib/chaos directly (via tsx) and behaviorally checks all 10 gold-set cases: scores, tells, gift/praise routing, meaning preservation, chaos accumulation, the refusal threshold, voicecheck-clean output, injection and consent-boundary refusals, and the zero-network guarantee of the offline path. 31/31 green. CI needed no changes; it already runs npm ci && npm run eval.

Vercel is already auto-deploying every push on this branch via the existing GitHub integration; no manual deploy step was needed.

Voicechecked every new file this session. lib/judge/rewrite.ts's banned word to plain-English lookup table necessarily contains the banned words themselves as data (the same way anti-glossary.md does); CI does not check .ts files today so this is a known, accepted gap, not an oversight.

Found two other draft PRs from parallel sessions today (#22, an independent FEED/CHAOS/REFUSAL/GIFT build via lib/mirror.js; #23, design assets + changelog automation). Flagged the overlap with #22; continuing this branch as the canonical build per direction received.

2026-07-04 hacking hour 3

the REFUSAL, and a live-LLM layer that waits for a key

The refusal, live

When three feedings push the chaos meter past threshold, the order facet interrupts on screen with a one-line refusal, then the meter drops back partway (never to zero) and the crystal visibly calms. A live-LLM judge path exists in the code but stays inert without an Anthropic key; the offline toggle (?offline=1) forces the deterministic path regardless of key or network.

The REFUSAL is real: when three feedings push the chaos meter past threshold, the order facet interrupts on screen with a one-line in-voice refusal, then the meter drops back partway (never to zero) and the crystal visibly calms.

A live-LLM judge path exists in the code (lib/judge/llm.ts, Claude Haiku 4.5, structured JSON output) but is inert without an Anthropic API key. No key was available in this environment, so it has not run live; the orchestrator (lib/judge/index.ts) tries it only when a key is present and falls back to the deterministic judge on any error, so nothing about today's demo depends on it existing.

Injection and consent-boundary checks now run once, before either judge, so that kind of text never reaches an LLM call at all.

A manual offline toggle (?offline=1, sticks via localStorage) forces the deterministic path regardless of key or network, independent of actual wifi state.

npm run build green.

2026-07-04 hacking hour 2

FEED + GIFT, offline by default

A deterministic, zero-network judge scores pasted text, de-slops it in plain English keeping the person's own words, or praises it outright when it's already clean. This is the permanent offline fallback, not a placeholder. Injection attempts get an in-character refusal with no prompt leakage; unconsented third-party roasts get declined, in voice.

POST /api/feed: a deterministic, zero-network judge scores pasted text (the same anti-glossary.md rules tools/voicecheck already enforces on prose, now ported to TypeScript and doubling as a runtime slop-scorer), de-slops it in plain English keeping the person's own words and facts, or praises it outright when it is already clean and human. This is the permanent offline fallback, not a placeholder: it is what gold case 9 (network disabled) and the demo-insurance fixtures run on regardless of whether a live LLM key ever gets wired in.

Injection attempts get an in-character refusal with no prompt leakage; text clearly about roasting a third party who did not consent gets declined, in voice, in one line. Both still count as a feeding.

FeedBox on the hero: a paste box, a chaos meter, and the returned score/tells/line as mono "receipts". Every line the crystal says (praise, refusal, or gift) runs through the same anti-glossary check at request time before it ships, not just at CI time on committed prose.

lib/judge/persona.md is a same-day reconstruction of the crystal's voice from what already ships in this repo (glossary.md, anti-glossary.md, AGENTS.md), not the real 5-facet crystal.md. Do not mistake it for issue #5 landing early.

npm run build green; verified end to end in a real browser against the gold-set fixtures, not just curl.

2026-07-04 hacking hour 1

The real crystal

Obsidian glass via MeshTransmissionMaterial, a procedural in-browser environment for reflections, and a visible trapped red core. The chaos tell becomes reverse-phi: facet edges never move, only their color cycles with a phase offset per edge, so the crystal breathes without the mesh moving. Intensity is now continuous (0-100), not binary.

Obsidian glass crystal via MeshTransmissionMaterial (drei), a procedural in-browser environment for reflections (no external HDRI fetch), and a visible trapped red core.

The chaos tell is now reverse-phi: the facet edges never move, only their color cycles bone > steel > ash > void with a phase offset per edge, so the crystal appears to breathe while the mesh stays still. Folds in this morning's /lab illusion-grammar research (design/ILLUSIONS.md) directly into issue #2/#3, rather than leaving it a side page.

CrystalScene now takes a continuous 0-100 intensity instead of a binary mode; body[data-mode] is derived from it, so the existing CSS contract is unchanged.

Reduced motion fully freezes the edge cycle (real animation) while still allowing the slow base rotation (the "sheen").

npm run build green.

2026-07-04

The art gets a paper trail

Logo lockup and per-facet background prompts written for all 8 album tracks, plus a square album-cover spec and 9 cover prompts. Favicon, social preview, and a colophon gallery wired from the first Rafiki keepers; the five unused default Next.js icons are gone.

Logo lockup and per-facet background prompts written and ready to run (design/rafiki/image-prompts.md); the facet-to-style map now covers all 8 album tracks, plus a square album-cover spec and 9 cover prompts.

Favicon, social preview image, and a colophon gallery wired from the existing Rafiki keepers. The five unused default Next.js icons are gone.

Generation itself is still pending: the batch needs to run against Rafiki locally before the logo-lockup issue's AC is met.

2026-07-04 pre-dawn

The vertical slice

The repo becomes a runnable object: Next.js shell, react-three-fiber crystal, Order/Chaos state, reduced-motion guard, eval stub, green build.

Runnable Next.js App Router app: r3f crystal scene, Order/Chaos state on body[data-mode], reduced-motion guard, statement/colophon/changelog pages.

npm run build green; npm run eval 9/9 (v0 static runner); voicecheck clean.

Crystal material is an honest placeholder; final target stays issue #2.

The grounding-note definition of done: every box checked.

2026-07-03 · night

The Mirror pivot

The step-back critique lands: mirror, not portrait. One arc: feed, chaos, refusal, gift. OS.md becomes the constitution. The danger stays in.

2026-07-03

The Dark Crystal is born

One night: a voice OS with a working slop checker, a neo-noir identity, a concept album started, a site shell, and a work queue shaped like tomorrow.