Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
93 commits
Select commit Hold shift + click to select a range
c0b2cbe
docs: update preferred external port design in TODO
dr-bonez Feb 6, 2026
8f809da
docs: add user-controlled public/private and port forward mapping to …
dr-bonez Feb 8, 2026
2e03a95
docs: overhaul interfaces page design with view/manage split and per-…
dr-bonez Feb 9, 2026
1974dfd
docs: move address enable/disable to overflow menu, add SSL indicator…
dr-bonez Feb 9, 2026
2ee403e
chore: remove tor from startos core
dr-bonez Feb 10, 2026
8204074
chore: flatten HostnameInfo from enum to struct
dr-bonez Feb 10, 2026
e1915bf
chore: format RPCSpec.md markdown table
dr-bonez Feb 10, 2026
73274ef
docs: update TODO.md with DerivedAddressInfo design, remove completed…
dr-bonez Feb 10, 2026
4e638fb
feat: implement preferred port allocation and per-address enable/disable
dr-bonez Feb 11, 2026
2a54625
feat: replace InterfaceFilter with ForwardRequirements, add WildcardL…
dr-bonez Feb 12, 2026
8ef4ecf
outbound gateway support (#3120)
MattDHill Feb 12, 2026
da75b84
Merge branch 'next/major' of github.com:Start9Labs/start-os into feat…
MattDHill Feb 12, 2026
638ed27
feat: replace SourceFilter with IpNet, add policy routing, remove MAS…
dr-bonez Feb 12, 2026
89d3e0c
Merge branch 'feat/preferred-port-design' of github.com:Start9Labs/st…
dr-bonez Feb 12, 2026
339e5f7
build ts types and fix i18n
MattDHill Feb 12, 2026
4decf93
fix license display in marketplace
MattDHill Feb 12, 2026
db7f334
wip refactor
dr-bonez Feb 12, 2026
61f820d
Merge branch 'feat/preferred-port-design' of github.com:Start9Labs/st…
dr-bonez Feb 13, 2026
3765465
chore: update ts bindings for preferred port design
dr-bonez Feb 13, 2026
49d4da0
feat: refactor NetService to watch DB and reconcile network state
dr-bonez Feb 13, 2026
d5c74bc
re-arrange (#3123)
MattDHill Feb 14, 2026
098d927
new service interfacee page
MattDHill Feb 14, 2026
3a63f3b
feat: add mdns hostname metadata variant and fix vhost routing
dr-bonez Feb 14, 2026
2f19188
looking good
MattDHill Feb 14, 2026
3518ecc
feat: add port_forwards field to Host for tracking gateway forwarding…
dr-bonez Feb 14, 2026
d97ab59
update bindings for API types, add ARCHITECTURE (#3124)
MattDHill Feb 16, 2026
cfbace1
fix: add CONNMARK restore-mark to mangle OUTPUT chain
dr-bonez Feb 17, 2026
6a1b162
chore: reserialize db on equal version, update bindings and docs
dr-bonez Feb 17, 2026
c9468dd
fix: include public gateways for IP-based addresses in vhost targets
dr-bonez Feb 17, 2026
1abad93
fix: add TLS handshake timeout and fix accept loop deadlock
dr-bonez Feb 17, 2026
52272fe
fix: switch BackgroundJobRunner from Vec to FuturesUnordered
dr-bonez Feb 17, 2026
ccafb59
chore: update bindings and use typed params for outbound gateway API
dr-bonez Feb 17, 2026
6814111
feat: per-service and default outbound gateway routing
dr-bonez Feb 17, 2026
bc4478b
refactor: manifest wraps PackageMetadata, move dependency_metadata to…
dr-bonez Feb 17, 2026
5fbc737
fix: replace .status() with .invoke() for iptables/ip commands
dr-bonez Feb 17, 2026
313b2df
feat: add check-dns gateway endpoint and fix per-interface routing ta…
dr-bonez Feb 17, 2026
4cae00c
refactor: rename manifest metadata fields and improve error display
dr-bonez Feb 18, 2026
e25e0f0
chore: bump sdk version to 0.4.0-beta.49
dr-bonez Feb 18, 2026
74e10ec
chore: add createTask decoupling TODO
dr-bonez Feb 18, 2026
a22707c
chore: add TODO to clear service error state on install/update
dr-bonez Feb 18, 2026
485fced
round out dns check, dns server check, port forward check, and gatewa…
MattDHill Feb 18, 2026
675a03b
chore: add TODOs for URL plugins, NAT hairpinning, and start-tunnel O…
dr-bonez Feb 18, 2026
783ce4b
version instead of os query param
MattDHill Feb 18, 2026
dce9754
interface row clickable again, bu now with a chevron!
MattDHill Feb 19, 2026
9c3053f
feat: implement URL plugins with table/row actions and prefill support
dr-bonez Feb 19, 2026
d562466
feat: split row_actions into remove_action and overflow_actions for U…
dr-bonez Feb 19, 2026
84149be
touch up URL plugins table
MattDHill Feb 19, 2026
5a292e6
show table even when no addresses
MattDHill Feb 19, 2026
4527046
feat: NAT hairpinning, DNS static servers, clear service error on ins…
dr-bonez Feb 19, 2026
7909941
feat: builder-style InputSpec API, prefill plumbing, and port forward…
dr-bonez Feb 19, 2026
66b5bc1
fix: propagate host locale into LXC containers and write locale.conf
dr-bonez Feb 20, 2026
9af5b87
chore: remove completed URL plugins TODO
dr-bonez Feb 20, 2026
35f3274
feat: OTA updates for start-tunnel via apt repository (untested)
dr-bonez Feb 20, 2026
135afd0
fix: publish script dpkg-name, s3cfg fallback, and --reinstall for apply
dr-bonez Feb 20, 2026
8c1a452
chore: replace OTA updates TODO with UI TODO for MattDHill
dr-bonez Feb 20, 2026
80cb2d9
feat: add getOutboundGateway effect and simplify VersionGraph init/un…
dr-bonez Feb 20, 2026
6a01b5e
frontend start-tunnel updates
MattDHill Feb 20, 2026
7879668
chore: remove completed TODO
dr-bonez Feb 20, 2026
c7a4f0f
feat: tor hidden service key migration
dr-bonez Feb 20, 2026
31352a7
chore: migrate from ts-matches to zod across all TypeScript packages
dr-bonez Feb 20, 2026
0724989
feat(core): allow setting server hostname
dr-bonez Feb 23, 2026
bee8a0f
send prefill for tasks and hide operations to hidden fields
MattDHill Feb 23, 2026
b7da7cd
fix(core): preserve plugin URLs across binding updates
dr-bonez Feb 24, 2026
5294e8f
minor cleanup from patch-db audit
MattDHill Feb 24, 2026
d116227
clean up prefill flow
MattDHill Feb 24, 2026
86ecc4c
frontend support for setting and changing hostname
MattDHill Feb 24, 2026
3974c09
feat(core): refactor hostname to ServerHostnameInfo with name/hostnam…
dr-bonez Feb 24, 2026
d4e019c
add comments to everything potentially consumer facing (#3127)
MattDHill Feb 24, 2026
d69e5b9
implement server name
MattDHill Feb 24, 2026
33a51bc
setup changes
dr-bonez Feb 24, 2026
3743a0d
Merge branch 'feat/preferred-port-design' of github.com:Start9Labs/st…
dr-bonez Feb 24, 2026
b466e71
clean up copy around addresses table
MattDHill Feb 25, 2026
8da9d76
feat: add zod-deep-partial, partialValidator on InputSpec, and z.deep…
dr-bonez Feb 25, 2026
803dd38
fix: header color in zoom (#3128)
waterplea Feb 25, 2026
8274585
update snake and add about this server to system general
MattDHill Feb 26, 2026
72d573d
chore: bump sdk to beta.53, wrap z.deepPartial with passthrough
dr-bonez Feb 26, 2026
7e8be58
reset instead of reset defaults
MattDHill Feb 26, 2026
7f66c62
action failure show dialog
MattDHill Feb 26, 2026
d422cd3
chore: bump sdk to beta.54, add device-info RPC, improve SDK abort ha…
dr-bonez Feb 26, 2026
e74f8db
fix: add --no-nvram to efi grub-install to preserve built-in boot order
dr-bonez Feb 26, 2026
6c86146
update snake
MattDHill Feb 26, 2026
d0ac073
Merge branch 'feat/preferred-port-design' of github.com:Start9Labs/st…
MattDHill Feb 26, 2026
b1c533d
diable actions when in error state
MattDHill Feb 27, 2026
011a3f9
chore: split out nvidia variant
dr-bonez Mar 2, 2026
f004c46
misc bugfixes
dr-bonez Mar 3, 2026
0e15a6e
create manage-release script (untested)
dr-bonez Mar 3, 2026
b51bfb8
fix: preserve z namespace types for sdk consumers
dr-bonez Mar 3, 2026
6778f37
sdk version bump
dr-bonez Mar 3, 2026
16a2fe4
new checkPort types
dr-bonez Mar 3, 2026
e999d89
multiple bugs and better port forward ux
MattDHill Mar 4, 2026
cdf3019
fix link
MattDHill Mar 4, 2026
ee7f77b
chore: todos and formatting
dr-bonez Mar 4, 2026
2fd8729
fix build
dr-bonez Mar 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
6 changes: 1 addition & 5 deletions .claude/settings.json
Original file line number Diff line number Diff line change
@@ -1,5 +1 @@
{
"attribution": {
"commit": ""
}
}
{}
17 changes: 16 additions & 1 deletion .github/workflows/startos-iso.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,13 @@ on:
- ALL
- x86_64
- x86_64-nonfree
- x86_64-nvidia
- aarch64
- aarch64-nonfree
- aarch64-nvidia
# - raspberrypi
- riscv64
- riscv64-nonfree
deploy:
type: choice
description: Deploy
Expand Down Expand Up @@ -65,10 +68,13 @@ jobs:
fromJson('{
"x86_64": ["x86_64"],
"x86_64-nonfree": ["x86_64"],
"x86_64-nvidia": ["x86_64"],
"aarch64": ["aarch64"],
"aarch64-nonfree": ["aarch64"],
"aarch64-nvidia": ["aarch64"],
"raspberrypi": ["aarch64"],
"riscv64": ["riscv64"],
"riscv64-nonfree": ["riscv64"],
"ALL": ["x86_64", "aarch64", "riscv64"]
}')[github.event.inputs.platform || 'ALL']
}}
Expand Down Expand Up @@ -125,7 +131,7 @@ jobs:
format(
'[
["{0}"],
["x86_64", "x86_64-nonfree", "aarch64", "aarch64-nonfree", "riscv64"]
["x86_64", "x86_64-nonfree", "x86_64-nvidia", "aarch64", "aarch64-nonfree", "aarch64-nvidia", "riscv64", "riscv64-nonfree"]
]',
github.event.inputs.platform || 'ALL'
)
Expand All @@ -139,18 +145,24 @@ jobs:
fromJson('{
"x86_64": "ubuntu-latest",
"x86_64-nonfree": "ubuntu-latest",
"x86_64-nvidia": "ubuntu-latest",
"aarch64": "ubuntu-24.04-arm",
"aarch64-nonfree": "ubuntu-24.04-arm",
"aarch64-nvidia": "ubuntu-24.04-arm",
"raspberrypi": "ubuntu-24.04-arm",
"riscv64": "ubuntu-24.04-arm",
"riscv64-nonfree": "ubuntu-24.04-arm",
}')[matrix.platform],
fromJson('{
"x86_64": "buildjet-8vcpu-ubuntu-2204",
"x86_64-nonfree": "buildjet-8vcpu-ubuntu-2204",
"x86_64-nvidia": "buildjet-8vcpu-ubuntu-2204",
"aarch64": "buildjet-8vcpu-ubuntu-2204-arm",
"aarch64-nonfree": "buildjet-8vcpu-ubuntu-2204-arm",
"aarch64-nvidia": "buildjet-8vcpu-ubuntu-2204-arm",
"raspberrypi": "buildjet-8vcpu-ubuntu-2204-arm",
"riscv64": "buildjet-8vcpu-ubuntu-2204",
"riscv64-nonfree": "buildjet-8vcpu-ubuntu-2204",
}')[matrix.platform]
)
)[github.event.inputs.runner == 'fast']
Expand All @@ -161,10 +173,13 @@ jobs:
fromJson('{
"x86_64": "x86_64",
"x86_64-nonfree": "x86_64",
"x86_64-nvidia": "x86_64",
"aarch64": "aarch64",
"aarch64-nonfree": "aarch64",
"aarch64-nvidia": "aarch64",
"raspberrypi": "aarch64",
"riscv64": "riscv64",
"riscv64-nonfree": "riscv64",
}')[matrix.platform]
}}
steps:
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@ secrets.db
/build/lib/firmware
tmp
web/.i18n-checked
agents/USER.md
docs/USER.md
101 changes: 101 additions & 0 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# Architecture

StartOS is an open-source Linux distribution for running personal servers. It manages discovery, installation, network configuration, backups, and health monitoring of self-hosted services.

## Tech Stack

- Backend: Rust (async/Tokio, Axum web framework)
- Frontend: Angular 20 + TypeScript + TaigaUI
- Container runtime: Node.js/TypeScript with LXC
- Database/State: Patch-DB (git submodule) - storage layer with reactive frontend sync
- API: JSON-RPC via rpc-toolkit (see `core/rpc-toolkit.md`)
- Auth: Password + session cookie, public/private key signatures, local authcookie (see `core/src/middleware/auth/`)

## Project Structure

```bash
/
├── assets/ # Screenshots for README
├── build/ # Auxiliary files and scripts for deployed images
├── container-runtime/ # Node.js program managing package containers
├── core/ # Rust backend: API, daemon (startd), CLI (start-cli)
├── debian/ # Debian package maintainer scripts
├── image-recipe/ # Scripts for building StartOS images
├── patch-db/ # (submodule) Diff-based data store for frontend sync
├── sdk/ # TypeScript SDK for building StartOS packages
└── web/ # Web UIs (Angular)
```

## Components

- **`core/`** — Rust backend daemon. Produces a single binary `startbox` that is symlinked as `startd` (main daemon), `start-cli` (CLI), `start-container` (runs inside LXC containers), `registrybox` (package registry), and `tunnelbox` (VPN/tunnel). Handles all backend logic: RPC API, service lifecycle, networking (DNS, ACME, WiFi, Tor, WireGuard), backups, and database state management. See [core/ARCHITECTURE.md](core/ARCHITECTURE.md).

- **`web/`** — Angular 20 + TypeScript workspace using Taiga UI. Contains three applications (admin UI, setup wizard, VPN management) and two shared libraries (common components/services, marketplace). Communicates with the backend exclusively via JSON-RPC. See [web/ARCHITECTURE.md](web/ARCHITECTURE.md).

- **`container-runtime/`** — Node.js runtime that runs inside each service's LXC container. Loads the service's JavaScript from its S9PK package and manages subcontainers. Communicates with the host daemon via JSON-RPC over Unix socket. See [container-runtime/CLAUDE.md](container-runtime/CLAUDE.md).

- **`sdk/`** — TypeScript SDK for packaging services for StartOS (`@start9labs/start-sdk`). Split into `base/` (core types, ABI definitions, effects interface, consumed by web as `@start9labs/start-sdk-base`) and `package/` (full SDK for service developers, consumed by container-runtime as `@start9labs/start-sdk`).

- **`patch-db/`** — Git submodule providing diff-based state synchronization. Uses CBOR encoding. Backend mutations produce diffs that are pushed to the frontend via WebSocket, enabling reactive UI updates without polling. See [patch-db repo](https://github.com/Start9Labs/patch-db).

## Build Pipeline

Components have a strict dependency chain. Changes flow in one direction:

```
Rust (core/)
→ cargo test exports ts-rs types to core/bindings/
→ rsync copies to sdk/base/lib/osBindings/
→ SDK build produces baseDist/ and dist/
→ web/ consumes baseDist/ (via @start9labs/start-sdk-base)
→ container-runtime/ consumes dist/ (via @start9labs/start-sdk)
```

Key make targets along this chain:

| Step | Command | What it does |
|---|---|---|
| 1 | `cargo check -p start-os` | Verify Rust compiles |
| 2 | `make ts-bindings` | Export ts-rs types → rsync to SDK |
| 3 | `cd sdk && make baseDist dist` | Build SDK packages |
| 4 | `cd web && npm run check` | Type-check Angular projects |
| 5 | `cd container-runtime && npm run check` | Type-check runtime |

**Important**: Editing `sdk/base/lib/osBindings/*.ts` alone is NOT sufficient — you must rebuild the SDK bundle (step 3) before web/container-runtime can see the changes.

## Cross-Layer Verification

When making changes across multiple layers (Rust, SDK, web, container-runtime), verify in this order:

1. **Rust**: `cargo check -p start-os` — verifies core compiles
2. **TS bindings**: `make ts-bindings` — regenerates TypeScript types from Rust `#[ts(export)]` structs
- Runs `./core/build/build-ts.sh` to export ts-rs types to `core/bindings/`
- Syncs `core/bindings/` → `sdk/base/lib/osBindings/` via rsync
- If you manually edit files in `sdk/base/lib/osBindings/`, you must still rebuild the SDK (step 3)
3. **SDK bundle**: `cd sdk && make baseDist dist` — compiles SDK source into packages
- `baseDist/` is consumed by `/web` (via `@start9labs/start-sdk-base`)
- `dist/` is consumed by `/container-runtime` (via `@start9labs/start-sdk`)
- Web and container-runtime reference the **built** SDK, not source files
4. **Web type check**: `cd web && npm run check` — type-checks all Angular projects
5. **Container runtime type check**: `cd container-runtime && npm run check` — type-checks the runtime

## Data Flow: Backend to Frontend

StartOS uses Patch-DB for reactive state synchronization:

1. The backend mutates state via `db.mutate()`, producing CBOR diffs
2. Diffs are pushed to the frontend over a persistent WebSocket connection
3. The frontend applies diffs to its local state copy and notifies observers
4. Components watch specific database paths via `PatchDB.watch$()`, receiving updates reactively

This means the UI is always eventually consistent with the backend — after any mutating API call, the frontend waits for the corresponding PatchDB diff before resolving, so the UI reflects the result immediately.

## Further Reading

- [core/ARCHITECTURE.md](core/ARCHITECTURE.md) — Rust backend architecture
- [web/ARCHITECTURE.md](web/ARCHITECTURE.md) — Angular frontend architecture
- [container-runtime/CLAUDE.md](container-runtime/CLAUDE.md) — Container runtime details
- [core/rpc-toolkit.md](core/rpc-toolkit.md) — JSON-RPC handler patterns
- [core/s9pk-structure.md](core/s9pk-structure.md) — S9PK package format
- [docs/exver.md](docs/exver.md) — Extended versioning format
- [docs/VERSION_BUMP.md](docs/VERSION_BUMP.md) — Version bumping guide
123 changes: 18 additions & 105 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,142 +2,55 @@

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview
## Architecture

StartOS is an open-source Linux distribution for running personal servers. It manages discovery, installation, network configuration, backups, and health monitoring of self-hosted services.
See [ARCHITECTURE.md](ARCHITECTURE.md) for the full system architecture, component map, build pipeline, and cross-layer verification order.

**Tech Stack:**
- Backend: Rust (async/Tokio, Axum web framework)
- Frontend: Angular 20 + TypeScript + TaigaUI
- Container runtime: Node.js/TypeScript with LXC
- Database/State: Patch-DB (git submodule) - storage layer with reactive frontend sync
- API: JSON-RPC via rpc-toolkit (see `agents/rpc-toolkit.md`)
- Auth: Password + session cookie, public/private key signatures, local authcookie (see `core/src/middleware/auth/`)
Each major component has its own `CLAUDE.md` with detailed guidance: `core/`, `web/`, `container-runtime/`, `sdk/`.

## Build & Development

See [CONTRIBUTING.md](CONTRIBUTING.md) for:

- Environment setup and requirements
- Build commands and make targets
- Testing and formatting commands
- Environment variables

**Quick reference:**

```bash
. ./devmode.sh # Enable dev mode
make update-startbox REMOTE=start9@<ip> # Fastest iteration (binary + UI)
make test-core # Run Rust tests
```

## Architecture

### Core (`/core`)
The Rust backend daemon. Main binaries:
- `startbox` - Main daemon (runs as `startd`)
- `start-cli` - CLI interface
- `start-container` - Runs inside LXC containers; communicates with host and manages subcontainers
- `registrybox` - Registry daemon
- `tunnelbox` - VPN/tunnel daemon

**Key modules:**
- `src/context/` - Context types (RpcContext, CliContext, InitContext, DiagnosticContext)
- `src/service/` - Service lifecycle management with actor pattern (`service_actor.rs`)
- `src/db/model/` - Patch-DB models (`public.rs` synced to frontend, `private.rs` backend-only)
- `src/net/` - Networking (DNS, ACME, WiFi, Tor via Arti, WireGuard)
- `src/s9pk/` - S9PK package format (merkle archive)
- `src/registry/` - Package registry management

**RPC Pattern:** See `agents/rpc-toolkit.md`

### Web (`/web`)
Angular projects sharing common code:
- `projects/ui/` - Main admin interface
- `projects/setup-wizard/` - Initial setup
- `projects/start-tunnel/` - VPN management UI
- `projects/shared/` - Common library (API clients, components)
- `projects/marketplace/` - Service discovery

**Development:**
```bash
cd web
npm ci
npm run start:ui # Dev server with mocks
npm run build:ui # Production build
npm run check # Type check all projects
```

### Container Runtime (`/container-runtime`)
Node.js runtime that manages service containers via RPC. See `RPCSpec.md` for protocol.

**Container Architecture:**
```
LXC Container (uniform base for all services)
└── systemd
└── container-runtime.service
└── Loads /usr/lib/startos/package/index.js (from s9pk javascript.squashfs)
└── Package JS launches subcontainers (from images in s9pk)
```

The container runtime communicates with the host via JSON-RPC over Unix socket. Package JavaScript must export functions conforming to the `ABI` type defined in `sdk/base/lib/types.ts`.

**`/media/startos/` directory (mounted by host into container):**

| Path | Description |
|------|-------------|
| `volumes/<name>/` | Package data volumes (id-mapped, persistent) |
| `assets/` | Read-only assets from s9pk `assets.squashfs` |
| `images/<name>/` | Container images (squashfs, used for subcontainers) |
| `images/<name>.env` | Environment variables for image |
| `images/<name>.json` | Image metadata |
| `backup/` | Backup mount point (mounted during backup operations) |
| `rpc/service.sock` | RPC socket (container runtime listens here) |
| `rpc/host.sock` | Host RPC socket (for effects callbacks to host) |

**S9PK Structure:** See `agents/s9pk-structure.md`

### SDK (`/sdk`)
TypeScript SDK for packaging services (`@start9labs/start-sdk`).

- `base/` - Core types, ABI definitions, effects interface (`@start9labs/start-sdk-base`)
- `package/` - Full SDK for package developers, re-exports base
## Operating Rules

### Patch-DB (`/patch-db`)
Git submodule providing diff-based state synchronization. Changes to `db/model/public.rs` automatically sync to the frontend.

**Key patterns:**
- `db.peek().await` - Get a read-only snapshot of the database state
- `db.mutate(|db| { ... }).await` - Apply mutations atomically, returns `MutateResult`
- `#[derive(HasModel)]` - Derive macro for types stored in the database, generates typed accessors

**Generated accessor types** (from `HasModel` derive):
- `as_field()` - Immutable reference: `&Model<T>`
- `as_field_mut()` - Mutable reference: `&mut Model<T>`
- `into_field()` - Owned value: `Model<T>`

**`Model<T>` APIs** (from `db/prelude.rs`):
- `.de()` - Deserialize to `T`
- `.ser(&value)` - Serialize from `T`
- `.mutate(|v| ...)` - Deserialize, mutate, reserialize
- For maps: `.keys()`, `.as_idx(&key)`, `.as_idx_mut(&key)`, `.insert()`, `.remove()`, `.contains_key()`
- Always verify cross-layer changes using the order described in [ARCHITECTURE.md](ARCHITECTURE.md#cross-layer-verification)
- Check component-level CLAUDE.md files for component-specific conventions. ALWAYS read it before operating on that component.
- Follow existing patterns before inventing new ones
- Always use `make` recipes when they exist for testing builds rather than manually invoking build commands

## Supplementary Documentation

The `agents/` directory contains detailed documentation for AI assistants:
The `docs/` directory contains cross-cutting documentation for AI assistants:

- `TODO.md` - Pending tasks for AI agents (check this first, remove items when completed)
- `USER.md` - Current user identifier (gitignored, see below)
- `rpc-toolkit.md` - JSON-RPC patterns and handler configuration
- `core-rust-patterns.md` - Common utilities and patterns for Rust code in `/core` (guard pattern, mount guards, etc.)
- `s9pk-structure.md` - S9PK package format structure
- `i18n-patterns.md` - Internationalization key conventions and usage in `/core`
- `exver.md` - Extended versioning format (used across core, sdk, and web)
- `VERSION_BUMP.md` - Guide for bumping the StartOS version across the codebase

Component-specific docs live alongside their code (e.g., `core/rpc-toolkit.md`, `core/i18n-patterns.md`).

### Session Startup

On startup:

1. **Check for `agents/USER.md`** - If it doesn't exist, prompt the user for their name/identifier and create it. This file is gitignored since it varies per developer.
1. **Check for `docs/USER.md`** - If it doesn't exist, prompt the user for their name/identifier and create it. This file is gitignored since it varies per developer.

2. **Check `docs/TODO.md` for relevant tasks** - Show TODOs that either:

2. **Check `agents/TODO.md` for relevant tasks** - Show TODOs that either:
- Have no `@username` tag (relevant to everyone)
- Are tagged with the current user's identifier

Expand Down
Loading