- Svelte 77.1%
- TypeScript 16.4%
- CSS 2.7%
- Python 2.1%
- HTML 1.1%
- Other 0.6%
Serves the JWKS at /.well-known/http-message-signatures-directory (path fixed by draft-meunier-web-bot-auth-architecture). Without this published, our RFC 9421 signatures verify nowhere — and a signed request a verifier cannot check is worse than an unsigned one, because it looks like a forgery. keyid (RFC 7638 JWK thumbprint): sFczaNjlREmSBvu9CyAt5zEXxtKmQTXq6ngjZM3tdFY Public key only. The private half lives in the crawler's environment (CRAWLER_SIGNING_KEY) and is never committed. Why: 4 of 15 authoritative hosts hard-403 ArgandBot, and a stock Chrome UA is refused IDENTICALLY — so this is not a UA blocklist and spoofing buys nothing. The door only opens for verified identity. Cloudflare's Verified Bots program is free and explicitly prioritises applicants signing with HTTP Message Signatures. We already pass on forward-confirmed rDNS; this is the part that jumps the queue. We decline pay-per-crawl: if a host still says no, we take the no. |
||
|---|---|---|
| .forgejo/workflows | ||
| content | ||
| docs | ||
| listmonk | ||
| scripts | ||
| src | ||
| static | ||
| .gitignore | ||
| .npmrc | ||
| energy-check.png | ||
| homepage-check.png | ||
| lighthouserc.json | ||
| package.json | ||
| pnpm-lock.yaml | ||
| presstrace-intro.png | ||
| principal-check.png | ||
| README.md | ||
| svelte.config.js | ||
| tsconfig.json | ||
| vite.config.ts | ||
| vitest.config.ts | ||
argand.org — pre-launch site
The public pre-launch site for Argand, an independent, privacy-first search engine built in pure Rust by one person. This repo is the marketing/landing site only; it is public on purpose, and is part of the project's trust story — so it is held to the same bar as the rest of Argand.
Live: https://argand.org
What's public here
- The full source of the landing site (SvelteKit +
adapter-static). - The deploy script (
scripts/deploy.sh). - The self-hosted double-opt-in email template (
listmonk/optin-welcome.html). - Trust artifacts:
security.txt, PGP key, and the genesis warrant canary (static/.well-known/).
What stays private until launch
- The search engine itself and its ~59 microservices / ~47 Rust crates.
- The crawl, index, ranking models, and the Argand Plane vector store.
- The
/api/newsletter-subscribeendpoint implementation (a same-origin proxy to a self-hosted Listmonk instance on Argand's own infrastructure).
Stack
- SvelteKit 2 (Svelte 5 runes) + TypeScript,
@sveltejs/adapter-static(fully prerendered — no server at runtime). - A strict Content-Security-Policy, self-hosted fonts/images, no third-party scripts.
vitestfor unit tests.
Develop
pnpm install
pnpm dev # local dev server
pnpm check # svelte-check / type check
pnpm test # vitest
pnpm build # prerender to ./build
pnpm preview # preview the production build
Node 22+, pnpm 10+.
Project structure
src/
routes/ # one folder per page (all prerendered)
+layout.svelte # site nav, footer, global <head>, JSON-LD
+page.svelte # short, conversion-focused homepage
benchmarks/ privacy/ presstrace/ roadmap/ about/ updates/
security-policy/ accessibility/ press/
sitemap.xml/+server.ts # generated at build time
feed.xml/+server.ts # generated at build time
lib/
components/ # SeoHead, OnThisPage, PageHeader, sections/, decks
data/ # services + updates (build log) data
nav/site.ts # routes, nav links, absolute-url helper
seo/ # pure sitemap + feed builders (unit-tested)
static/
fonts/ images/ icons/ # self-hosted assets
robots.txt opensearch.xml site.webmanifest
.well-known/ # security.txt, pgp key, warrant canary
The waitlist flow
Both signup forms (newsletter + early-accounts) are progressively enhanced:
they are real <form method="POST" action="/api/newsletter-subscribe"> elements
with native HTML validation, and JavaScript only layers on inline success/error
feedback. With JS disabled, the browser performs a normal POST and lands on a
real confirmation page.
How both paths complete (the /api/newsletter-subscribe endpoint is a
same-origin Caddy proxy to a self-hosted Listmonk; config outside this repo):
- JS path —
fetchposts JSON ({ email, list_uuids }). Caddy routesContent-Type: application/jsonto Listmonk's/api/public/subscription, which returns JSON; the component renders inline success/error. - No-JS path — the native form posts
application/x-www-form-urlencoded(email, plus a hiddenl= the list UUID, Listmonk's public-form param). Caddy routes urlencoded posts to Listmonk's/subscription/form, which subscribes and renders a real HTML confirmation page. Caddy also serves Listmonk's/subscription/*(confirm / unsubscribe / manage-prefs) and/public/static/*on-origin so those pages — and the unsubscribe links in emails (Listmonkroot_url=https://argand.org) — resolve under the brand domain. Admin (/admin, authed/api/*) is not proxied.
SEO & discovery
sitemap.xml,feed.xml: prerendered endpoints;<lastmod>/<lastBuildDate>are stamped from the build timestamp (vite.config.ts__BUILD_TIME__), so freshness never needs hand-editing.robots.txt: static; disallows/api/and points at the sitemap.- Structured data (JSON-LD): site-wide
Organization+WebSitein the layout<head>, plus a per-subpageBreadcrumbList(Home → page) emitted bySeoHeadfrom the route's nav label, all serialised through a<script>-safe helper (src/lib/seo/jsonld.ts). - Icons / PWA: regenerate with
uv run --with pillow --with fonttools --with brotli scripts/gen-icons.py(renders from the site's own Atkinson Hyperlegible woff2). opensearch.xmlis kept in the repo but intentionally not advertised via<link rel="search">until the engine is live.
Trust & policy
- Vulnerability disclosure:
/security-policy, machine-readable at/.well-known/security.txt. - Warrant canary:
/.well-known/canary.json(+ detached signature). Rotation ops are documented indocs/CANARY.md. - Privacy architecture:
/privacy. - Accessibility statement:
/accessibility.
Deploy
scripts/deploy.sh builds, packages, SHA-256-verifies the upload, extracts to a
timestamped release on the datalake, then atomically flips the current
symlink (keeping previous for rollback). Caddy serves current.
./scripts/deploy.sh
Quality / CI
CI (.forgejo/workflows/ci.yml) runs on every push: pnpm check, pnpm test,
pnpm build, plus an advisory Lighthouse pass. To run the Lighthouse audit
locally against a production build:
pnpm build
pnpm dlx @lhci/cli autorun # uses lighthouserc.json
Reporting issues
- Security: nic@argand.org (PGP welcome — see
/security-policy). - Accessibility: nic@argand.org — see
/accessibility. - Anything else: nic@argand.org.
License
Pre-launch. The site content and brand assets are © 2026 Nic Weyand, all rights reserved, unless noted otherwise.