# Project Bifrost — Pilot Hub

**Owner:** Fenja AI
**Purpose:** A private, invite-only hub for participants of the Project Bifrost pilot.
**Status:** Pre-build specification. This is the source of truth for what we are building and why. Everything in `CLAUDE.md` refers back to this.

---

## 1. What this is

Project Bifrost is Fenja AI's first product pilot — the foundation for a sovereign, customer-hosted AI platform for Denmark and, in time, the EU. The *hub* is the private website where pilot participants and Customer Advisory Board members live during the pilot: it is where they read what we are building, shape it, ask questions, and meet.

The hub is not a marketing site. It is a working room. It should feel like being invited into a small, serious project — closer to a research group's private workspace than a product landing page.

The name carries weight. *Bifrost* — the rainbow bridge between worlds in Norse mythology — is the bridge between what Fenja is building and the organisations that will first depend on it. The hub is where that bridge is walked.

---

## 2. Vision copy (verbatim, for the site)

### Fenja AI

> Fenja enables the safe, sovereign use of Artificial Intelligence in organisations where data is highly sensitive, operations are mission-critical, and strict data privacy is essential. We are building the premier solution for public authorities and companies operating in heavily regulated industries — pharmaceuticals, critical infrastructure, finance — where standard AI solutions hosted on foreign-owned public clouds are simply not a viable or compliant option.
>
> Many organisations are eager to harness the transformative power of AI but cannot accept the risk of their data, workflows, and critical functions becoming dependent on external providers with foreign ownership and control. Fenja directly addresses this gap by enabling highly advanced, customer-hosted AI within the client's own secure infrastructure. Data remains under absolute, localised control while we deliver the robust security, traceability, and documentation demanded by the market.
>
> As the global demand for digital sovereignty accelerates, Fenja is positioned to generate profound societal value. We are making cutting-edge AI safely usable in the most critical of functions without ever compromising security or compliance. Backed by investment from the Innovation Fund, we are accelerating product development, executing high-impact pilot projects, and establishing foundational customer cases. Our long-term ambition is to establish Fenja as the definitive Danish and European platform for secure, locally controlled AI in regulated environments.

### Project Bifrost

> Project Bifrost is one of the first stones in the foundation of Denmark and the EU's sovereign AI platform — a platform controlled by its customers, that understands not just your business, but you and your department, and builds on that knowledge automatically. Open-source LLMs in a modern, secure, customer-hosted environment.
>
> This is Project Bifrost.

### What comes after Bifrost

A preview section, written in reserved language (no dates, no promises):

- Full developer agentic experience
- Agentic data extraction and analysis
- Self-service agent work automation

---

## 3. Audience & access

### Roles

| Role | Who | What they can do |
|---|---|---|
| **Pilot participant** | People from the ~2 organisations running the paid pilot | Full hub access; contribute ideas, ask questions, attend CAB meetings, see roadmap |
| **Advisory Board member** | People from the other ~3 organisations following & advising | Same hub access as pilot participants, except they see a *CAB* badge and the roadmap may mark some items as pilot-only |
| **Fenja internal** | Us | Everything above + admin panel |

**Note:** Everyone in the hub sees each other's contributions. The "fully shared" community model is deliberate — the value of the hub is that participants see they are not alone, and ideas compound.

### Scale

- ~14 people at launch, across ~5 organisations
- Designed to grow to ~50 without re-architecture
- Not designed for public scale — this stays invite-only

### Invitation flow

1. Fenja admin (you) opens the admin panel, enters name + organisation + email + role
2. System generates a one-time signed invite link and shows it to you
3. You send the link personally (email, signal, in person — your choice; the hub does not send emails)
4. Invitee clicks link → lands on a branded "Welcome, *Mette*" screen that asks them to set a password
5. From then on they log in with email + password
6. Invite links expire 14 days after generation and are single-use

**No self-registration. No "forgot password" email flow for v1** — if someone needs a reset, you issue them a new invite link from the admin panel. Simpler and more secure for 14 people.

---

## 4. Information architecture

Eight surfaces. No more.

1. **Welcome** `/` — Personalised landing ("Welcome, Mette."). Short orientation. Three or four quiet cards pointing to the other surfaces. Latest update teaser.
2. **Vision** `/vision` — The Fenja vision, the Bifrost vision, "what comes after" — all from §2.
3. **Updates** `/updates` — Reverse-chronological log of progress posts written by Fenja. Each post is a markdown file. Permalinks.
4. **Roadmap** `/roadmap` — Editorial, timeline-style view of what is being built. Three horizons: *In progress*, *Next*, *Later*. Not a Trello board — closer to a museum plaque for each item.
5. **Calendar** `/calendar` — CAB meetings and milestones. Big, typographic, unrushed. One month per view. Click a meeting → its page (agenda before, notes after).
6. **Contribute** `/contribute` — Where participants post ideas, inspiration, and questions. Everyone sees everyone. Three tabs or filters: *Ideas*, *Inspiration*, *Questions*. Markdown-lite text input. Fenja can reply. Others can react (simple "+1" style, no threaded debates — this is a suggestion book, not a forum).
7. **Product preview** `/preview` — "Coming soon" for Fenja AI and Fenja Knowledge. Restrained prose about what's being built. When the MVP is ready, this page becomes the gateway.
8. **Participants** `/participants` — A directory of who is in the hub, by organisation. Reinforces the "you are in good company" feeling. Shows role badges. No contact info beyond what each participant chooses to share.

### Admin-only

9. **Admin** `/admin` — Behind auth + role check. Two tabs: *Invitations* (generate/list/revoke) and *Participants* (view, change role, deactivate). No content editing here — content lives in markdown, committed to git.

---

## 5. Feature specifications

### 5.1 Welcome page

Personal, spare. Above the fold: the Fenja wordmark (small), then a single oversized editorial greeting — *"Welcome, Mette."* — set against generous whitespace. Below it, one or two sentences framing what Bifrost is and what the hub is for. Further down, three quiet navigation cards (*Latest update*, *Next CAB meeting*, *Contribute an idea*). That's it. No hero image, no CTA chrome.

### 5.2 Updates

- Posts are markdown files in `/content/updates/YYYY-MM-DD-slug.md`
- Frontmatter: `title`, `date`, `author` (defaults to "Fenja AI"), `summary`
- Rendered with proper editorial typography — generous line height, serif body text if the design system permits, large margins
- Each post has a permalink; RSS feed at `/updates.xml` (low effort, high signal of seriousness)

### 5.3 Roadmap

- One markdown file: `/content/roadmap.md`
- Structured as three sections: *In progress*, *Next*, *Later*
- Each item is a few lines — a name, a one-sentence description, optionally a status tag
- No Gantt charts, no percentages. If an item is pilot-only, that's marked with a small tag

### 5.4 Calendar

This is the showpiece. It should *feel* like the best page on the site.

- Month view by default. Arrow keys navigate months. Today is marked with a subtle tonal shift, not a coloured pill.
- Meetings are written as markdown files in `/content/meetings/YYYY-MM-DD-slug.md`
- Each meeting's detail page shows: date, time, location (physical or video link), attendees (roles, not individuals, unless specified), agenda (before), notes (after), any attached documents
- Before a meeting, the page shows the agenda. After, notes appear below.
- Attendees can mark "I will attend" / "I cannot attend" — a simple tally, not a hard RSVP. Shown only to Fenja.

### 5.5 Contribute

- Participants write markdown-lite text (bold, italic, links, lists, code blocks — nothing exotic)
- Each contribution has an author, organisation, timestamp, type (*Idea* | *Inspiration* | *Question*), and body
- Reactions: a single "+1" style acknowledgement (a small mark, not a heart). Count shown.
- Fenja replies appear directly under the contribution, typographically distinct
- Contributions can be edited by author within 10 minutes of posting, then locked
- No deletion by authors. Admins can hide (soft-delete) anything.
- Default sort: newest. Also: *most acknowledged*.

### 5.6 Product preview

A single page. A restrained block of copy explaining what is coming (Fenja AI, Fenja Knowledge — a "Karpathy-style" wiki that lets the system understand the context you work in). No screenshots yet. When the MVP ships, this page will gain a "Request early access" path.

### 5.7 Participants

- Grouped by organisation. Each organisation shown with its name and participant cards.
- Each card: name, role, short self-written bio (optional, max 280 chars), role badge (*Pilot* / *CAB* / *Fenja*)
- Participants edit their own bio from `/account` (tiny page, just name display preference + bio)

### 5.8 Admin panel

- **Invitations tab:** form (name, email, organisation, role) → generates a signed link → shows it once, copy-to-clipboard. Table below lists outstanding invites, who they're for, when they expire, with *Revoke* and *Regenerate* actions.
- **Participants tab:** table of all users with role, last-seen, and actions (change role, deactivate, issue new password reset link)

---

## 6. Design direction

The visual language comes from the Fenja design system, which lives locally in the `design/` folder. That folder is the single source of truth for colours, typography, spacing, components, iconography, fonts, and logo assets. It contains:

- `design/SKILL.md` — instructions for Claude Code on how to use the design system
- `design/README.md` — human-readable overview
- `design/ICONOGRAPHY.md` — icon style and usage
- `design/colors_and_type.css` — authoritative colour and type tokens
- `design/assets/` — logo and brand assets
- `design/fonts/` — font files
- `design/preview/`, `design/screenshots/`, `design/ui_kits/` — reference material

Claude Code reads `design/SKILL.md` first and follows its instructions. The code in `src/` consumes the design system through `src/styles/tokens.css`, which is derived from `design/colors_and_type.css`. Fonts and logo assets are copied into `public/` during initial setup.

The aesthetic the design system expresses — and that every page of the hub must respect — is **authoritative quietude**:

> A rejection of the frantic, neon-soaked tropes of "Deep Tech" AI in favour of a timeless, academic, and human-centric aesthetic. Data treated like a high-end research publication; interface treated like a piece of minimalist Danish furniture. Intentional asymmetry, oversized editorial margins, a radical commitment to negative space. Separation comes from tonal shifts and "ghost layering" rather than borders. An interface that breathes, inviting contemplation rather than consumption.

Practical implications for the build (these hold unless the design system specifies otherwise):

- **No visible borders** on cards or sections. Separation = tonal background shift + whitespace.
- **No drop shadows** by default. If elevation is needed, use a near-imperceptible tonal shift.
- **Typography does the work.** Headline sizes are editorial-scale. Body copy has room to breathe.
- **Asymmetry is intentional.** Most pages use 2 or 3 optical zones with deliberate weight, not centred symmetry.
- **Motion is minimal.** Transitions are short, slow, ease-out. No parallax. No auto-playing anything.
- **Light mode primary.** Dark mode is a nice-to-have for v1.1, not v1.

If the design system contradicts any of the above, the design system wins — flag the contradiction for review.

---

## 7. Technical approach (proposed)

Everything here is a recommendation. Overrule before the first build.

### 7.1 Stack

- **Framework:** [Astro](https://astro.build) with a few server endpoints. Astro is content-first, produces mostly static HTML, and treats markdown as a first-class citizen — ideal for the editorial aesthetic. Server routes handle only what needs a server (auth, contributions, admin).
- **Language:** TypeScript throughout.
- **Styling:** Vanilla CSS with design tokens (CSS custom properties) defined in `src/styles/tokens.css`, derived from `design/colors_and_type.css`. *No Tailwind.* Tailwind's utility soup runs against the editorial, bespoke aesthetic we want.
- **Database:** SQLite via [better-sqlite3](https://github.com/WiseLibs/better-sqlite3). For 14–50 users, SQLite is the right tool. One file, atomic backups, no daemon.
- **Auth:** Custom, minimal. Session cookie + bcrypt password hashes + signed invite tokens. No third-party auth provider — sovereignty matters.
- **Content:** Markdown files in `/content/{updates,meetings,roadmap}`. Parsed with Astro's built-in content collections (with `zod` schemas).
- **Package manager:** pnpm.
- **Node version:** 22 LTS.

### 7.2 Data model (SQLite)

```
users
  id, email (unique), password_hash, name, organisation,
  role ('pilot' | 'cab' | 'fenja'), bio, created_at, last_seen_at, active

invites
  id, token_hash (unique), email, name, organisation, role,
  expires_at, used_at, created_at, created_by_user_id

sessions
  id, user_id, expires_at, created_at

contributions
  id, user_id, type ('idea' | 'inspiration' | 'question'),
  body_md, created_at, edited_at, hidden_at

reactions
  id, user_id, contribution_id, created_at
  (unique on user_id + contribution_id)

replies
  id, contribution_id, user_id, body_md, created_at
  (only fenja role can create)

attendance
  id, user_id, meeting_slug, status ('yes' | 'no'), updated_at
  (unique on user_id + meeting_slug)
```

That's the whole schema. No ORM — plain SQL in typed query functions.

### 7.3 Hosting

- **Single VPS on Hetzner Cloud**, Helsinki region (fi-hel1) — EU, renewable power, closest Hetzner DC to Denmark. CAX11 (ARM, 2 vCPU, 4 GB) is sufficient; ~€4/month.
- **Reverse proxy:** Caddy, automatic HTTPS via Let's Encrypt.
- **Process manager:** systemd unit running the Node server.
- **Backups:** `sqlite3 .backup` nightly cronjob → Hetzner Storage Box, 30-day retention.
- **Deploys:** `git push` to the VPS's bare repo triggers a `post-receive` hook that builds and restarts. Or, GitHub Actions → rsync. Claude Code can set up either.
- **Domain:** something like `bifrost.fenja.ai` (confirm with Fenja DNS owner).

### 7.4 Why not fully static

A fully static site cannot:
- Authenticate users
- Accept and display user submissions
- Track invite usage
- Mark attendance

Those features are core to the hub, so a small backend is non-negotiable. The backend stays small: fewer than ~15 server routes, one SQLite file, no external services.

---

## 8. Out of scope for v1

Listed so Claude Code does not wander into them:

- Email sending (invites are copied manually; no transactional email provider)
- File uploads from participants (they write text; Fenja attaches documents to meetings via git)
- Rich-text editor beyond markdown-lite
- Threaded discussion on contributions (replies from Fenja only, one level deep)
- Dark mode
- Mobile app
- Search
- Analytics beyond a small self-hosted Plausible instance (optional; skip for v1)
- Internationalisation (English only)
- Two-factor authentication (considered for v1.1)
- Public-facing pages (everything sits behind auth except the invite-redeem and login routes)

---

## 9. Decisions made on your behalf

Please overrule any of these before Claude Code starts:

1. **Framework = Astro.** If you prefer SvelteKit or Next.js, say so — the spec adapts cleanly.
2. **CSS = vanilla with tokens.** Tailwind is available if you'd rather trade the editorial purity for build speed.
3. **Database = SQLite.** Postgres is overkill for 14 users but available if you want it.
4. **No email service.** You send invite links personally.
5. **No forgot-password flow.** Admin re-issues invite links instead.
6. **Hetzner Helsinki** over Falkenstein — personal call based on renewable power and latency to Denmark. Falkenstein is fine too.
7. **Light mode only for v1.**
8. **No public marketing site at the same domain.** The hub sits at `bifrost.fenja.ai` or similar.

---

## 10. Definition of done for v1

The hub is done when:

- An admin can generate an invite link and a new user can redeem it, set a password, and log in
- All eight surfaces in §4 render correctly, personalised where relevant, with copy from §2
- A participant can post an *Idea*, *Inspiration*, or *Question*, and every other participant sees it, can acknowledge it, and Fenja can reply
- A meeting can be created as a markdown file and appears on the calendar; attendance can be marked; notes appear after the meeting
- The roadmap renders from its markdown file
- The whole thing runs on a Hetzner CAX11, backed up nightly, with HTTPS
- The visual language faithfully applies the design system in `design/` without requiring further design review

When all of the above is true and you have sent the first batch of invite links — Bifrost is live.
