- Add working-directory rule to root and all project docs
- Generalize root from "HTTP web services" to "independent projects"
- Add @../CLAUDE.md inheritance to nbd, edu, quotesdb project docs
- Remove sections duplicated from root in project-level docs
- Wrap all sections in semantic XML tags for clearer agent parsing
- Rename Tech Stack → Common Patterns (framed as defaults, not requirements)
- Rename Running Services Locally → Running Projects Locally
**Always run commands from the root of the project you are working on** — not from the repository root. Each project is self-contained and its commands (`cargo`, `mdbook`, `trunk`, `tofu`, etc.) must be run from within that project's directory.
</working-directory-rule>
<repository-structure>
## Repository Structure
## Repository Structure
This is a mono-repo of self-contained HTTP web services. Each service lives in its own top-level folder and is an independent Rust crate (no Cargo workspace). There is no cross-service communication — each service is a standalone application.
This is a mono-repo of independent projects. Each project lives in its own top-level folder. Projects may be Rust HTTP services, CLI tools, static sites, frontends, or anything else — there is no single template. Projects do not communicate with each other.
```
```
vibed/
vibed/
@ -10,37 +16,57 @@ vibed/
├── README.md # repo-wide overview with descriptions of each project
├── README.md # repo-wide overview with descriptions of each project
├── LICENSE-APACHE
├── LICENSE-APACHE
├── LICENSE-MIT
├── LICENSE-MIT
├── flake.nix # base Nix flake — all services inherit or extend this
├── flake.nix # base Nix flake — projects may inherit or extend this
This imports the root conventions (validation, git, code style, license, task tracking) so they don't need to be duplicated. Project files should only contain project-specific overrides or additions.
</inheritance>
<common-patterns>
## Common Patterns
These are defaults that apply **when relevant** — not every project uses all of them. Rust CLI tools don't need Axum; static sites don't need SQLx. Apply the patterns that fit the project.
<language-and-tooling>
### Language & Tooling
### Language & Tooling
- **Language:** Rust (all software)
- **Language:** Rust (preferred; exceptions are documented per-project)
- **Local development:** Nix with Nix Flakes for dependency management
- **Local development:** Nix with Nix Flakes for dependency management
- **Infrastructure:** OpenTofu with the Cloudflare provider (stored in each service's `infra/` subfolder)
- **Infrastructure:** OpenTofu with the Cloudflare provider (stored in each project's `infra/` subfolder)
- **Formatting:** Default `rustfmt` conventions (no custom `rustfmt.toml`)
- **Formatting:** Default `rustfmt` conventions (no custom `rustfmt.toml`)
</language-and-tooling>
<backend-pattern>
### Backend
### Backend
- **Framework:** Tower + Axum
- **Framework:** Tower + Axum
@ -50,6 +76,10 @@ vibed/
- **API format:** JSON-encoded request and response payloads
- **API format:** JSON-encoded request and response payloads
- **API spec:** Each backend service must have an auto-generated OpenAPI spec. _TODO: choose tooling crate._
- **API spec:** Each backend service must have an auto-generated OpenAPI spec. _TODO: choose tooling crate._
</backend-pattern>
<frontend-pattern>
### Frontend
### Frontend
- **Framework:** Yew (Rust compiled to Wasm)
- **Framework:** Yew (Rust compiled to Wasm)
@ -57,24 +87,32 @@ vibed/
- **Compile target:**`wasm32-unknown-unknown` (included in the Nix dev shell via rust-overlay)
- **Compile target:**`wasm32-unknown-unknown` (included in the Nix dev shell via rust-overlay)
- **Hosting:** Cloudflare Pages
- **Hosting:** Cloudflare Pages
</frontend-pattern>
<infrastructure-pattern>
### Infrastructure
- **Provider:** OpenTofu with the Cloudflare provider
The `common/` crate is a shared library for types, utilities, and definitions reused across services. Individual services depend on it via a path dependency in their `Cargo.toml`:
```toml
<chosen-crates>
[dependencies]
common = { path = "../common" }
```
## Chosen Crates
### Chosen Crates
When a crate is chosen to solve a problem, it becomes the standard for that purpose across all services. Add new entries here as decisions are made.
When a crate is chosen to solve a problem, it becomes the standard for that purpose across all projects. Add new entries here as decisions are made.
| Purpose | Crate | Notes |
| Purpose | Crate | Notes |
|---|---|---|
|---|---|---|
@ -82,25 +120,44 @@ When a crate is chosen to solve a problem, it becomes the standard for that purp
_This table is intentionally empty. Populate it as crate decisions are made during development._
_This table is intentionally empty. Populate it as crate decisions are made during development._
</chosen-crates>
</common-patterns>
<secrets-and-configuration>
## Secrets & Configuration
## Secrets & Configuration
- **Local:**`.env` files for local secrets. **Never commit `.env` files to the repository.**
- **Local:**`.env` files for local secrets. **Never commit `.env` files to the repository.**
- **Production:** Wrangler secrets (`wrangler secret put <KEY>`).
- **Production:** Wrangler secrets (`wrangler secret put <KEY>`).
- Add `.env` to `.gitignore` at both the repo root and service level.
- Add `.env` to `.gitignore` at both the repo root and project level.
</secrets-and-configuration>
## Running Services Locally
<running-projects>
## Running Projects Locally
Commands vary by project type. Run all commands from within the project directory.
```sh
```sh
# Backend service (from the service directory)
# Rust backend
cargo run
cargo run
# Frontend service (from the service directory)
# Rust frontend
trunk serve
trunk serve
# Static site (mdBook)
mdbook serve
```
```
</running-projects>
<validation>
## Validation
## Validation
Run these commands **in order** from the service directory before committing changes:
Run these commands **in order** from the **project directory** before committing changes:
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
# CLAUDE.md — edu
<working-directory>
All commands in this file are run from the `edu/` directory.
</working-directory>
<project-overview>
## What This Project Is
## What This Project Is
`edu` is an [mdbook](https://rust-lang.github.io/mdBook/)-based static site called **Vibed Learning** — a collection of self-guided courses and technical references. There is no Rust code here; all content is Markdown. The generated `book/` directory is gitignored.
`edu` is an [mdbook](https://rust-lang.github.io/mdBook/)-based static site called **Vibed Learning** — a collection of self-guided courses and technical references. There is no Rust code here; all content is Markdown. The generated `book/` directory is gitignored.
</project-overview>
<commands>
## Commands
## Commands
```sh
```sh
@ -20,6 +30,10 @@ nix develop
# or automatically via direnv: cd into the directory
# or automatically via direnv: cd into the directory
```
```
</commands>
<content-structure>
## Content Structure
## Content Structure
- `src/SUMMARY.md` — mdbook table of contents; controls site navigation. **Every new page must be listed here.**
- `src/SUMMARY.md` — mdbook table of contents; controls site navigation. **Every new page must be listed here.**
@ -28,67 +42,16 @@ nix develop
To add a new page: create `src/<name>.md`, then add it to `src/SUMMARY.md` under the appropriate section heading.
To add a new page: create `src/<name>.md`, then add it to `src/SUMMARY.md` under the appropriate section heading.
## Task Tracking with nbd
</content-structure>
`nbd` is a CLI tool for managing work tickets, designed for agent workflows.
### Initialisation
<conventions>
```sh
nbd init
```
Run once in the project root. Creates `.nbd/tickets/`. Safe to run multiple times.
### Core commands
```sh
# Create a new ticket (use --ftype md for a human-readable body)
- Use `--deps id1,id2` to express blockers — tickets that must be done first.
- Create tickets *before* starting non-trivial tasks, not after.
Ticket IDs appear in commit messages in `[<id>]` format.
## Conventions
## Conventions
Inherits all Git and general conventions from the parent [`../CLAUDE.md`](../CLAUDE.md) (Conventional Commits, dual Apache-2.0/MIT license, Nix for dev, etc.).
All commands in this file are run from the `nbd/` directory.
</working-directory>
<project-overview>
`nbd` is a CLI tool for managing work tickets, primarily targeted at agent workflows. It is an independent Rust crate within the `vibed` mono-repo.
`nbd` is a CLI tool for managing work tickets, primarily targeted at agent workflows. It is an independent Rust crate within the `vibed` mono-repo.
</project-overview>
<project-structure>
## Project Structure
## Project Structure
```
```
@ -24,6 +36,10 @@ nbd/
└── README.md
└── README.md
```
```
</project-structure>
<tech-stack>
## Tech Stack
## Tech Stack
- **Language:** Rust (edition 2021)
- **Language:** Rust (edition 2021)
@ -32,6 +48,10 @@ nbd/
- **Serialization:**`serde` + `serde_json`
- **Serialization:**`serde` + `serde_json`
- **Test utilities:**`tempfile` (dev-dependency)
- **Test utilities:**`tempfile` (dev-dependency)
</tech-stack>
<data-model>
## Data Model
## Data Model
Tickets are stored as `.json` files in `.nbd/tickets/{id}.json`, where `id` is a 6-character hex string (e.g. `a3f9c2`). The `.nbd/` root is found by traversing up from cwd, like `git` finds `.git/`.
Tickets are stored as `.json` files in `.nbd/tickets/{id}.json`, where `id` is a 6-character hex string (e.g. `a3f9c2`). The `.nbd/` root is found by traversing up from cwd, like `git` finds `.git/`.
> Inherits all conventions from [@../CLAUDE.md](../CLAUDE.md). This file adds project-specific workflow, structure, and agent dispatch rules.
<working-directory>
Run all commands from the relevant sub-directory within `quotesdb/` (e.g., `api/`, `ui/`, `infra/`) — not from the repository root or the `quotesdb/` root.