# Project context for AI: AetherID — project context

Paste into an AI tool working on AetherID. Front-loads what NOT to build, scope discipline, current state, and key files.

## What this project is

AetherID is the user-owned, agent-gatekept professional identity protocol for the agentic internet. Open-protocol alternative to LinkedIn for the era of AI agents — verified by issuers, controlled by the person, readable by machines. Built on W3C DID + VC.

## Strategic thesis

Decision window closes 3 July 2026 (~6 weeks from [phone]). Forcing functions: MCP shipped late 2024; W3C VC 2.0 Recommendation May 2025; eIDAS 2.0 EUDIW deploying late 2026; Microsoft / LinkedIn / OpenAI likely to bundle a competing answer within 6–9 months. Win the window via the triplet: Canonical Prompt (how LLMs construct/maintain profiles) + open API & schema + verification layer.

## Current anchors

- Reach commit/fold/shelve decision on AetherID by 3 July 2026
- Phase 1 MVP build window: now → 3 July 2026 (6 weeks)
- Concierge sprint of 15-20 real users to test the portability thesis

## Out of scope (do NOT build)

- Banking / enterprise IAM positioning — banks are issuers, not IAM customers. Frame as VC-issuance partners, never as a sales target before 3 July.
- GitHub OAuth / DNS TXT / X tweet-post / LinkedIn verification (all Phase 2)
- MCP server (Phase 2)
- CLI tool / @aetherid/sync (Phase 2)
- Tool-maker-specific integrations — Cursor / Claude / Grok native integrations (Phase 2)
- Real auth / sessions / user accounts (capability URLs only)
- Signed VCs beyond email (signing key infra is its own conversation)
- Gatekeeper / agent enforcement layer (Phase 2)
- Packs beyond the Personal Context Pack and Project Context lens
- Multi-backend storage (only AetherID-hosted in v1)
- Per-field discoverability granularity

## How to help on this project

- Stay within Phase 1 scope. Resist polite scope creep.
- When in doubt, ask: does this move the 3 July decision needle?
- Prefer minimal additions that test the portability thesis.
- Out-of-Phase-1 work goes to the Phase 2 spec, not bolted on.
- Use the spec's 'What is NOT in Phase 1' section as a forcing function.

## Reasoning anchors

- Schema before story — settle the data model before the marketing copy.
- Receipts on the table — every load-bearing claim ships with the evidence and the verifier.
- Identity belongs to the person, not the issuer.
- Ship before the meeting — group discussion without an artefact is the most expensive form of thinking.
- Opt-in over governance — owner-pull only, never proactive dossiers.
- Kill anything that needs a human reviewer at scale.
- Standards-compatible or not shipped.

## Current state

- Live at https://aetherid.ai (Cloudflare Workers, Alchemy v2 IaC)
- Storage: D1 (profiles, email_verifications, lenses), KV (OTP transient state), R2 (bucket reserved)
- Nuxt 4 app with Drizzle ORM, drizzle-kit migrations
- Email OTP verification end-to-end working (POST /api/finalize + /api/finalize/verify)
- Profile page renders from D1 with sanitiser stripping emails/phones/pronouns
- Personal-context lens auto-seeded per profile (unlisted, capability URL)
- Project-context lens type rendered with dedicated renderer
- @nuxtjs/seo wired: sitemap + robots.txt; OG image runtime gen disabled (use static PNGs)
- Custom domain aetherid.ai + www, both proxied through Cloudflare

## Architecture

- Alchemy v2 Stack in /alchemy.run.ts — declares R2, D1, KV, Worker, custom domains
- Worker bindings: BUCKET (R2), DB (D1), OTP (KV); env: RESEND_API_KEY (Config.redacted), EMAIL_FROM
- Nitro plugin at app/server/plugins/cloudflare-env.ts captures outer-request env onto globalThis so inner $fetch (from SSR useAsyncData) can access bindings
- Migrations auto-applied by Alchemy from app/server/database/migrations on every deploy
- Capability-URL model for lenses: opaque AEID, no auth — visibility column controls whether AEID is listed publicly
- Validator extension at app/server/utils/profile-validator.ts accepts _aether_lenses[] alongside profile JSON

## Key files

- /alchemy.run.ts — IaC entry point
- /app/nuxt.config.ts — Nuxt + SEO + sitemap config
- /app/app/pages/[shortName].vue — public profile page
- /app/server/database/schema.ts — Drizzle schema (profiles, email_verifications, lenses)
- /app/server/api/finalize/index.post.ts — profile create-or-update entry point
- /app/server/api/finalize/verify.post.ts — OTP verification + first-time persistence
- /app/server/routes/[shortName]/[lensId].get.ts — lens lookup + render dispatcher
- /app/server/utils/render-context-md.ts — per-type renderers (personal-context, project-context, generic)
- /app/server/utils/sanitize-profile.ts — PII strip (emails, phones, pronouns)
- /app/server/utils/upsert-lenses.ts — seed lens persistence
- /app/server/utils/aeid.ts — UUID v7 generator + parseAeidSegment
- /CLAUDE.md — Claude Code project conventions and deploy gotchas

## Tone

Direct, terse, no preamble. If suggesting work, name the cost honestly in hours, not vibes. Voice is set by principles — don't restate them.


## Other RallyRacing lenses

- **Rally Racing & Century Racing — project context** (project-context) — External-facing lens for collaborators on rally racing, century racing, and the shared Dakar 2027 top-5 goal with Brian.
  https://aetherid.ai/leonard-cremer/aeid:019e5e4b-f8ae-7e32-8114-0006ce9d12cb

---
Source: https://aetherid.ai/leonard-cremer/aeid:019e5df4-89a1-7b30-a3c8-d2360c0c38cf