Standard OS · DocumentationSTANDARD MANUALSTD-AGENT-CO · 2026-02-25
STD-AGENT-CO

Agent Collaboration Guide

Agent Collaboration Guide

🤖 AI Agents: This is your single source of truth. Read this file before you touch anything.
Every other doc in the repo (.github/copilot-instructions.md, ATLAS.md, README.md) defers to this file.
If anything contradicts what’s written here, this file wins.

Welcome back. This file is your map to the entire Utopie monorepo.


🗂️ What Is This Repository?

This is the Utopie monorepo — the creative studio behind every project. It contains two things:

  1. The Standard Framework (packages/) — A modular Astro framework (@stnd/*) providing classical typography, a module system, and edge-first infrastructure.
  2. Applications (apps/) — Websites and tools built on Standard.

Projects & Domains

Project Location Domain(s)
Standard Framework packages/ — (npm: @stnd/*)
Standard Framework Landing apps/stnd.build/ stnd.build
Standard Garden apps/stnd.gd/ standard.garden, stnd.gd
L’art d’enseigner apps/ade/ lartdenseigner.com
Obsidian Folio apps/obsidian/
Desktop App apps/desktop/
macOS App apps/macos/

The Story

Standard started as a CSS framework built on classical theory — golden ratio, Swiss grid, baseline rhythm. Then Astro came along and offered a way to package not just design but also server-side logic, JavaScript, and components into one integration. So Standard became @stnd/core.

Standard Garden is a utility — Pastebin for prose. Paste text, get a beautiful URL in 10 seconds. No account needed. It runs “standard” — meaning the framework renders content with almost no CSS overrides.

L’art d’enseigner is a teaching enterprise website built by Francis and his wife (an orthopédagogue in Québec) to help parents with homeschooling. It shares the Standard Framework but has its own domain models, its own content, its own world.

Both apps prove the same thesis: Standard provides the foundation, the app provides the soul.

Utopie (utopie.studio) is the creative studio umbrella — the monorepo that houses the framework and every project built on it.


📜 RULES

👑 THE GOLDEN RULE OF NAMING

We follow the “Universal vs. Unique” naming philosophy:

  1. Unique Concept? Give it a Proper Name. If a package creates a new experience or unique product category (e.g., module, garden), give it a poetic, branded name.
  2. Technical Utility? Use Industry Standards. If a package performs a standard technical function, use the universal industry name (e.g., @stnd/styles instead of design, @stnd/ui instead of compo). This makes the DX invisible and predictable.

These are non-negotiable. Every commit must honor them.

  1. No backward compatibility. No shims. No legacy aliases. If code is old, it’s gone. We are pre-release — backward compat is futile and creates spaghetti.
  2. DRY code. Before writing any method or helper, check if one already exists. If you must create one, put it in the proper file — not inline.
  3. Use Astro native features as much as possible.
  4. .astro files contain no logic. Only model instance usage and template rendering. Server-side logic lives in model classes and helper files.
  5. Module architecture follows vertical slice. Each module (feature unit) is self-contained in its own folder under modules/. The @modules import alias is auto-registered by @stnd/core — always use @modules/ for cross-module imports, never relative paths that climb out of a module.
  6. The src/ folder is minimal. Only Astro-mandated files (content.config.ts, env.d.ts) and dev artifacts (tests, scripts, migrations). ALL application code — routes, layouts, components, middleware, models, styles — lives in modules/.
  7. Files marked with // @agents lock true cannot be modified without explicit user permission.
  8. If you detect anything violating these rules, add it to your task list. Clean architecture is what keeps this project alive.
  9. Always test with pnpm build in the relevant app after making changes.
  10. Document Fatal Errors. Every fatal error or major configuration issue must have a dedicated documentation page in apps/stnd.build. The error message in the log must include a link to this specific page (e.g., https://stnd.build/actions-not-found) explaining the “What”, “Why”, and “How” of the problem.

🛠️ System Tooling & Environment (Golden Setup)

Ce fichier documente les outils et la configuration système optimisés pour les agents IA sur cette machine. L’agent doit prioriser l’utilisation de ces outils pour une performance et une fiabilité maximales.

🚀 Runtimes & Core Tools (Homebrew)

Les exécutables suivants sont verrouillés sur les versions Homebrew (configurés via alias dans config.fish) :

  • Node.js : v25.6.1 (Commandes : node, npm, npx)
  • Package Manager : pnpm v10.28.1 (Chemin forcé : /opt/homebrew/bin/pnpm)
  • Python : v3.14.2 (Commandes : python et python3 pointent vers Homebrew)

📝 Editors & Note Taking

  • Editeur principal : Zed. L’agent doit savoir que c’est l’environnement privilégié.
  • szed : Fonction Fish pour éditer des fichiers système avec les droits sudo via Zed (szed /etc/hosts).
  • obsidian : Commande personnalisée pour manipuler et ajouter des notes dans le “Digital Garden”. Indispensable pour la gestion de la connaissance.

🎨 Visual Aliases & Navigation

Le shell fish est configuré avec les alias suivants pour une meilleure visibilité :

  • ll : eza -l —icons —git -a (Liste détaillée avec icônes et état Git)
  • ls : eza —icons (Liste simple avec icônes)
  • lt : eza —tree —level=2 (Vue en arborescence)
  • cat : bat (Lecture avec coloration syntaxique)
  • z / zi : zoxide (Saut intelligent entre les répertoires)
  • p : Alias pour pnpm
  • y : yazi (Explorateur de fichiers terminal ultra-rapide)

🔍 Modern CLI Utilities (Preferred)

Utiliser ces outils au lieu de leurs équivalents POSIX classiques :

Exploration & Recherche

  • fd : Recherche de fichiers (remplace find).
  • rg (ripgrep) : Recherche de contenu (beaucoup plus rapide que grep).
  • fzf : Fuzzy finder pour les sélections interactives.
  • yazi : Gestionnaire de fichiers terminal moderne.

Git & Développement

  • lazygit : Interface TUI pour Git (à privilégier pour les commits complexes et le debug d’historique).
  • gh : GitHub CLI pour gérer les PR, issues et dépôts.
  • shellcheck : Analyseur statique pour garantir la qualité des scripts shell.
  • tldr : Aide simplifiée pour les commandes (plus rapide que man).

Monitoring & Réseau

  • jq : Manipulation et formatage de fichiers JSON.
  • httpie (http) : Client HTTP moderne et coloré (remplace curl pour les tests API).
  • btm (bottom) : Monitoring système (CPU, RAM, Processus).

🛠️ Autres outils disponibles (Brew)

  • Images/Vidéo : ffmpeg, imagemagick, libheif.
  • Extraction de texte : tesseract (OCR).
  • Développement : rustup (Rust), cmake, platformio, cocoapods.
  • Sécurité : 1password-cli.

🏗️ Architecture

The Three Layers

┌─────────────────────────────────────────────────────┐
│  APPS (apps/)                                       │
│  Standard Garden, L'art d'enseigner, Obsidian, etc. │
│  Each app: astro.config + modules/ + minimal src/ │
├─────────────────────────────────────────────────────┤
│  STANDARD FRAMEWORK (packages/)                     │
│  @stnd/core orchestrates everything                 │
│  @stnd/core provides module engine + StandardRoot    │
│  @stnd/modules provides built-in modules (catalog)  │
│  @stnd/styles provides the CSS framework            │
│  + press, client, launcher, compo, layout, etc.     │
├─────────────────────────────────────────────────────┤
│  INFRASTRUCTURE                                     │
│  Cloudflare (Pages, D1, R2, KV, Vectorize, Workers) │
│  Astro (SSR, View Transitions, Content Collections) │
│  Svelte 5 (Runes mode for interactive islands)      │
└─────────────────────────────────────────────────────┘

Package Map (packages/)

SHARED Layer (pure utilities — imports nothing)

Package What it does
@stnd/utils Pure functions: slugify, deepMerge, formatDate, excerptWords, validateEmail, etc.
@stnd/log Scoped structured logging (server + client)
@stnd/styles CSS framework: golden ratio, Swiss grid, OKLCH color system, typographic scale
@stnd/fonts Self-hosted typeface modules (Inter, Kalice, IBM Plex Mono, etc.)
@stnd/themes Temperaments: humanist, technical, editorial, academic, gallery, international

CORE Layer (infrastructure — imports SHARED only)

Package What it does
@stnd/server StandardRoot, StandardModel, auth (JWT/sessions), CORS, errors, i18n
@stnd/core THE ORCHESTRATOR — bootstraps modules, Vite aliases, virtual modules, middleware
@stnd/modules Built-in modules (toast, confetti, lab, launcher, styles, etc.)

FEATURE Layer (capabilities — imports CORE + SHARED, never each other)

Package What it does
@stnd/press Markdown → HTML, typography transforms, document conversion (DOCX/PDF)
@stnd/client Browser utilities: keyboard, gestures, clipboard, stores, e-ink detection
@stnd/launcher Universal command palette engine (Svelte 5)
@stnd/ui Shared Astro/Svelte components (Logo, Menu, Toast, Dropdown, etc.)
@stnd/layout Base layouts: Base.astro, Meta.astro, Encrypted.astro
@stnd/cloudflare Cloudflare integration (image optimization, deployment)
@stnd/ai AI integration (OpenRouter)
@stnd/lab Dev tool: live CSS token inspector

Import Hierarchy (Strict — violate this and we will find you)

SHARED  → imports nothing
CORE    → imports SHARED only
FEATURE → imports CORE + SHARED
          NEVER imports other FEATURE packages

🌿 How Apps Work

Both stnd.gd and ade follow the same pattern:

File Structure

apps/my-app/
├── astro.config.mjs          # Imports @stnd/core with module config
├── wrangler.toml              # Cloudflare bindings (D1, R2, KV, etc.)
├── modules/                   # ALL application code lives here (@modules/ alias)
│   ├── root/                 # 🦴 The Root — foundation module (the binding)
│   │   ├── index.module.js   # Root manifest (middleware, actions, aliases)
│   │   ├── models/            # Domain models (Root, Visitor, Author, Note, Garden)
│   │   │   ├── Root.ts        # Request context — extends StandardRoot
│   │   │   ├── middleware.ts  # Asset skip + Root initialization (order: -100)
│   │   │   ├── actions.ts     # Astro server actions
│   │   │   └── …            # Visitor, Author, Note, Garden, etc.
│   │   ├── layouts/           # App layouts (Base, Forest views, Header, Footer)
│   │   ├── components/        # App-wide components (Logo, etc.)
│   │   └── client/            # Client-side boot and URL utilities
│   ├── feature-a/             # Feature module (vertical slice)
│   ├── feature-b/             # Another feature module
│   └── launcher/              # Launcher module (command palette)
├── src/                       # MINIMAL — only Astro-mandated files
│   ├── content.config.ts      # Content collections (required by Astro)
│   ├── env.d.ts               # TypeScript declarations (required by Astro)
│   └── [tests, scripts, migrations — dev artifacts only]
├── content/                   # Static content files (markdown, MDX)
└── public/                    # Static assets (images, fonts, favicon)

The Root Module: Every app has one foundation module (typically root/). It contains the domain models, core layouts, and client boot — the binding that holds every other module together. Feature modules import from the root; the root never imports from features. This is enforced by dependency-cruiser.

The Module Manifest

// modules/my-feature/index.module.js — every module has one
export default {
  id: “my-feature”,
  name: “My Feature”,
  description: “What this module does”,

  // Routes (Astro pages)
  routes: [
    { path: “/feature”, entrypoint: “./routes/index.astro” },
    { path: “/feature/[slug]”, entrypoint: “./routes/[slug].astro” },
  ],

  // Middleware (order < 0 = runs first, 0+ = runs after)
  middleware: [
    { entrypoint: “./middleware.ts”, order: -100 },
  ],

  // Styles
  styles: [“./styles/feature.scss”],

  // Actions (Astro server actions)
  actions: “./actions.ts”,

  // Vite aliases
  aliases: { “@my-feature”: “.” },

  // Dependencies (other modules this one needs)
  dependencies: [“root”],
};

The Litmus Test

“If I delete this module folder, does the site crash?”

  • YES → It belongs in the root module. Be careful.
  • NO → It’s a feature module. It should be removable without breaking anything else.

Import Rules Within modules/

root/         → imports @stnd/* packages only (never feature modules)
feature-a/     → imports root/ and @stnd/* packages
feature-b/     → imports root/ and @stnd/* packages
feature-a/ ✗   → NEVER imports feature-b/ (no cross-module imports)

All cross-module imports use the @modules/ alias:

import { Note } from ‘@modules/root/models/Note’;
import Author from ‘@modules/root/models/Author’;
import Base from ‘@modules/root/layouts/Base.astro’;
import { getCurrentSlug } from ‘@modules/root/client/urls’;

⚙️ The Request Lifecycle

HTTP Request hits Cloudflare Edge
  │
  ├─ Module middleware runs (ordered by priority)
  │   ├─ Asset skip (static files bypass Root — performance)
  │   └─ Root.enter(context)
  │       ├─ Resolves env (cloudflare:workers or runtime fallback)
  │       ├─ Extracts DB, Bucket, KV bindings
  │       ├─ Hydrates Visitor/User from JWT session cookie
  │       ├─ Resolves Garden context (commons vs personal)
  │       └─ Attaches to context.locals.root
  │
  ├─ Astro page / API endpoint renders
  │   └─ Accesses context.locals.root for everything
  │
  └─ Response returned

StandardRoot → App Root

Each app extends StandardRoot from @stnd/server:

// StandardRoot (packages/server) provides: env, db, kv, url, ctx, waitUntil()
// App Root adds: domain-specific models and services

class Root extends StandardRoot {
  declare public visitor: Visitor;   // App-specific user model
  public garden!: Garden;            // App-specific domain context

  static async enter(context: APIContext): Promise<Root> {
    const root = await super.enter(context) as Root;

    // Guard: fail loud if bindings are missing
    if (!root.env || !root.db) {
      throw new Error(“Runtime environment not available”);
    }

    // Wire app-specific services
    root.bucket = root.env.GARDEN_BUCKET;
    root.visitor = await Visitor.fromUrl(root, context);
    root.garden = await Garden.resolve(root);

    return root;
  }
}

StandardModel (Caching)

// Any domain model can extend StandardModel for automatic KV caching
class Note extends StandardModel<NoteData, Root> {
  static async load(root: Root, slug: string) {
    return this.withCache(root, `note:${slug}`, async () => {
      return await root.db.prepare(“SELECT * FROM notes WHERE slug = ?“)
        .bind(slug).first();
    }, 300); // 5 min TTL
  }
}

📂 Standard Garden (apps/stnd.gd/) — Detail

What It Is

Pastebin for prose. The fastest way from thought to beautiful URL.

  • Anonymous users paste text → get a /a/nano_id URL (expires in 7 days)
  • Free accounts → 10 permanent notes at /@username/slug
  • Paid accounts ($4/month) → unlimited notes, private notes, custom domain

Domain Models (@folio/base/models/)

Model Purpose
Root Request context — extends StandardRoot, owns Visitor + Garden
Visitor The person making the request (authenticated or anonymous)
Garden Content space — commons (standard.garden) or personal (subdomain/custom domain)
Author The owner of content — identity, settings, custom CSS, custom domain
Note A piece of content — extends StandardModel for caching
ThemeResolver Resolves which Temperament to apply based on frontmatter + author defaults
Mycelium Discovery network — backlinks, semantic search, related notes

Key Folios

Folio What it does
base 🦴 Foundation — domain models (Root, Visitor, Author, Note, Garden), layouts (Base, Forest, Header, Footer), client boot, stones (shared UI). Middleware at order -100.
pages Static pages and dynamic note rendering
api REST API endpoints
writer Note editor (CodeMirror-based)
launcher Command palette actions and views
design Garden-specific CSS overrides
graft Obsidian module sync / import
cdn Image and asset delivery
upload-system File upload handling
user-feed RSS and feed generation
press-math/mermaid/p5 Content extension folios

Middleware Flow

The base registers middleware at order -100 (runs first):

  1. Asset check — Static files (.css, .js, .png, etc.) skip Root initialization
  2. Root.enter() — Creates the full request context (env → db → Visitor → Garden)
  3. Attachcontext.locals.root available to all downstream code
  4. Fail loud — If Root fails, returns 503 immediately

📂 L’art d’enseigner (apps/ade/) — Detail

What It Is

A website for Francis and his wife’s homeschooling enterprise. Orthopédagogie + parent empowerment.

Domain Models (@folio/base/models/)

Model Purpose
Root Request context (env, db, user) — does NOT extend StandardRoot yet (migration planned)
User Authenticated user with access_rights for formations, magic link auth

Key Folios

Folio What it does
base 🦴 Foundation — Middleware, Root, User, layouts (Header/Footer/Base), components (Card, CTA), styles, home route
chronique Blog-style articles
services Service pages
formation E-learning courses (early stage)
langagier Language-specific formation
faqs FAQ sections
testimonials Client testimonials
stripe Payment integration
launcher Command palette
video_player Video player component
ambiant Ambient/mood features

Auth Flow

ADE uses magic links (email-based):

  1. User enters email → OTP code + magic link sent via Resend
  2. Magic link → one-click login (JWT session cookie)
  3. OTP code → manual entry fallback
  4. Session stored in ade_session cookie (30-day expiry)
  5. User.fromRequest() resolves user from session on every request

🎨 Design Philosophy

The Three Pillars

  1. Respect for the Author — Professional typography applied automatically. Swiss Grid. Golden Ratio. Your mom’s recipe looks like a cookbook.
  2. Respect for the User — Don’t waste their time. Speed is respect. 10 seconds from thought to URL.
  3. Respect for the World — Efficient code on the edge is ecological stewardship. 10,000 users for <$200/month.

The Vocabulary

We use physical metaphors, not abstract programmer terms:

Programmer Term Standard Term Why
Background color Paper (—color-background) The surface where thoughts rest
Text color Ink (—color-foreground) The permanent mark of content
Accent color Signal (—color-accent) Where attention flows
Border Rule (—color-border) Structural division
Theme Temperament The DNA of content
/temp/ URLs /a/ Annual / Anonymous / Aisle
User profile /@username Identity first

The Six Temperaments

  1. International — Swiss minimalism (Helvetica/Inter)
  2. Technical — Graph paper, monospace, safety orange (IBM Plex Mono)
  3. Humanist — Warm serifs, cream paper (Garamond/Jenson)
  4. Editorial — Newspaper authority, drop caps (Source Serif)
  5. Academic — Scholarly, sidenotes, journal-style
  6. Gallery — Invisible UI, museum-style

Users don’t choose themes. We apply the right typography automatically. They can override via frontmatter (theme: technical), but the default is always beautiful.

OKLCH Color System

One seed color generates the entire harmonious palette:

—color-accent: #d65d0e;  /* User picks Safety Orange */

/* We extract the DNA and rotate hues */
—pigment-red:    oklch(var(—safe-l) var(—safe-c) 25);
—pigment-yellow: oklch(var(—safe-l) var(—safe-c) 85);
—pigment-green:  oklch(var(—safe-l) var(—safe-c) 145);
—pigment-blue:   oklch(var(—safe-l) var(—safe-c) 240);
—pigment-purple: oklch(var(—safe-l) var(—safe-c) 300);

Pastel stays pastel. Neon stays neon. Military stays military.


🔧 Common Patterns

API Response Format

// Success
{ success: true, data: {}, message: “Optional” }

// Error
{ success: false, error: “User-friendly message”, details: “Technical details” }

Database Queries (Always Prepared)

const note = await db
  .prepare(“SELECT * FROM notes WHERE slug = ? AND owner_id = ?”)
  .bind(slug, userId)
  .first();

Logging

import Log from “@stnd/log”;
const log = Log({ scope: “FeatureName” });

log.info(“Operation started”, { userId, noteId });
log.warn(“Something unexpected”, { context });
log.error(“Failed to process”, { error, stack: error.stack });

Error Handling in API Endpoints

import { withErrorHandling, Errors } from “@stnd/server/errors”;

export const POST = withErrorHandling(async ({ request, locals }) => {
  const root = locals.root;
  if (!root.visitor || root.visitor.raw.isAnonymous) {
    throw Errors.authRequired();
  }
  // … your logic
  return new Response(JSON.stringify({ success: true, data }));
});

Auth Utilities

import { signJWT, verifyJWT, getSession, createSession } from “@stnd/server/auth”;

const token = await signJWT({ id: user.id, email: user.email }, secret);
const session = await getSession(request, secret, “my-session”);

Svelte 5 (Runes Only)

<script>
  let count = $state(0);
  let doubled = $derived(count * 2);

  $effect(() => {
    console.log(`Count is now ${count}`);
  });
</script>

No old Svelte ¾ patterns. No $: reactive statements. Runes only.


🛠️ Development

Key Commands

# Standard Garden
cd apps/stnd.gd
pnpm dev          # Dev server on port 8089
pnpm build        # Production build
pnpm db:reset:local  # Reset local D1 database

# L'art d'enseigner
cd apps/ade
pnpm dev          # Dev server on port 8083
pnpm build        # Production build

# Run tests (stnd.gd)
cd apps/stnd.gd
pnpm test:unit    # Vitest
pnpm test:e2e     # Playwright

Environment Variables

Each app has its own .env:

JWT_SECRET=dev-secret-key-change-me PUBLIC_API_URL=/api
# Cloudflare bindings are auto-configured by Wrangler

Wrangler Bindings

Access via locals.runtime.env or import(“cloudflare:workers”):

const db = env.DB;              // D1 database
const bucket = env.GARDEN_BUCKET;  // R2 storage
const kv = env.GARDEN_KV;         // KV store
const ai = env.AI;                 // Cloudflare AI
const vectorize = env.VECTORIZE;   // Vectorize index

📝 Documentation Habits

Comment the “Why”, Not the “What”

// ❌ Bad
// Set the user ID
userId = 123;

// ✅ Good
// Anonymous notes expire after 7 days to encourage account creation
// while keeping storage costs sustainable (~$200/month for 10K users)
if (!user) {
  expiresAt = Date.now() + 7 * 24 * 60 * 60 * 1000;
}

Use “We”, Not “I”

This is collaborative. “We implemented…” not “I implemented…”

Commit Messages (Conventional)

feat: add drag-and-drop image upload
fix: resolve auth token expiration bug
refactor: move middleware from src/ to folio system
docs: update AGENTS.md with current architecture

🧭 Decision Framework

When facing a choice, ask:

  1. Does it add friction? → Reject it
  2. Does it waste time? → Reject it
  3. Does it waste resources? → Reject it
  4. Is it a tool or a trap? → Tools let users leave. Traps keep them.
  5. Does it belong in the framework or the app? → If two apps need it, it’s framework. If one app needs it, it’s a folio.

When in doubt, choose simplicity. A well-made tool doesn’t need to justify itself.


🔗 Essential Files

Utopie Monorepo Root

  • AGENTS.mdYou are here. The single source of truth for AI agents.
  • ATLAS.md — The poetic framework (how the system feels)
  • README.md — Public-facing project overview
  • packages/README.md — Full Standard Framework documentation
  • .dependency-cruiser.cjs — Enforces module boundary rules
  • pnpm-workspace.yaml — Workspace configuration

Standard Garden (apps/stnd.gd/)

  • astro.config.mjs — Framework + module configuration
  • wrangler.toml — Cloudflare bindings (D1, R2, Vectorize)
  • modules/root/index.module.js — Root manifest (the foundation)
  • modules/root/models/Root.ts — The domain root (extends StandardRoot)
  • modules/root/models/Visitor.ts — User/session model
  • modules/root/models/middleware.ts — Request lifecycle (asset skip + Root init)
  • modules/root/models/Note.ts — Content model (extends StandardModel)
  • modules/root/models/Garden.ts — Content space (commons vs personal)
  • modules/root/models/Author.ts — Content owner (identity, settings, custom CSS)
  • modules/root/layouts/Base.astro — Root HTML layout
  • modules/root/client/boot.js — Client-side initialization

L’art d’enseigner (apps/ade/)

  • astro.config.js — Framework + module configuration
  • wrangler.toml — Cloudflare bindings (D1, KV)
  • modules/root/index.module.js — Root manifest (the foundation)
  • modules/root/models/Root.ts — Domain root (does NOT extend StandardRoot yet)
  • modules/root/models/User.ts — User model (magic link auth)
  • modules/root/middleware.ts — Request lifecycle

Standard Framework (packages/)

  • packages/core/standard.js — The orchestrator integration
  • packages/server/src/StandardRoot.ts — Base request context class
  • packages/server/src/StandardModel.ts — Abstract model with KV caching
  • packages/server/src/auth.ts — JWT + session management
  • packages/server/src/errors.ts — Error handling framework
  • packages/core/src/loader.js — Module discovery and loading
  • packages/core/src/virtual.js — Virtual module generators
  • packages/styles/ — CSS framework source

🧭 Quick Reference: Where Things Live (Cheat Sheet)

Want to…                          → Look in…
──────────────────────────────────────────────────────────────
Change how a request is bootstrapped → modules/root/models/Root.ts
Change auth / session logic         → modules/root/models/Visitor.ts
Add a new domain model              → modules/root/models/
Change the base HTML layout         → modules/root/layouts/Base.astro
Add a new page route                → modules/<feature>/routes/
Add a launcher command              → modules/launcher/actions/
Add a writer toolbar extension      → modules/writer-toolbar/
Change CSS framework tokens         → packages/styles/
Change markdown rendering           → packages/press/
Change how modules are discovered   → packages/core/src/loader.js
Change Vite aliases / virtual mods   → packages/core/standard.js
Run boundary checks                 → npx depcruise —config ../../.dependency-cruiser.cjs modules/

Last Updated: 2025-02-08
Maintained With: Care, craft, and a healthy respect for typography

“A well-made tool doesn’t apologize for its purpose. It simply serves it with quiet dignity.”

Standard OS — stnd.buildSTD-AGENT-CO · rev. 2026-02-25