Menu
Public repository / c2f43d4988686a5b5142bb6dd4255f9b473792dc
AkurAI-Notes / .plan/epics/E01-scaffold-and-framework-bootstrap.md
Latest change f1d9b8cc6ff48113d891a2d95fd79b2c49f1f4ff - Initial plan and .plan directory by Claude Code
# E01 — Scaffold + Framework bootstrap + repo
## Goal
Create the AkurAI-Notes workspace, populated by the AkurAI-Framework bootstrap
scaffolder (`akurai new`), with the right crate skeleton and `VERSION=0.0.1`.
## Pre-flight (run before starting)
```bash
which akurai && akurai --version # AkurAI-Framework CLI is on PATH
ls ~/Projects/AkurAI-Framework/crates/{http,json,storage,router,collections,vector,markdown,template,schema,i18n}
gh auth status # we'll need gh for deploy.sh
cd ~/Projects
```
## Steps
### 1. Scaffold the Framework site/ (uses the bootstrap script)
The Framework ships `akurai new <dir>` for this (read
`~/Projects/AkurAI-Framework/crates/cli/src/cmd_new.rs:1-58` — it bakes the
template files in with `include_str!` and lays down `frontend/`, `backend/`,
`data/`, and `.gitignore`). We want its output in the Notes `site/`
subdirectory:
```bash
cd ~/Projects/AkurAI-Notes
# Bootstrap a Framework-shaped site/ directory (created blank above).
akurai new site
ls site/
# Expect: frontend/ backend/ data/ .gitignore
```
This gives us the Framework's canonical no-build frontend — `header.html`,
`footer.html`, `styles.css`, `app.js`, `index.html`, `page.json`,
`collections.toml`, `akurai.toml`. Do not modify these yet — E02 owns the
landing page.
### 2. Initialise the Rust workspace
The Notes workspace sits ABOVE the scaffolded `site/` directory. The CRM
project (`~/Projects/akurai-crm/`) is the 1:1 silhouette — same nesting,
same path-dep strategy.
```bash
cd ~/Projects/AkurAI-Notes
mkdir -p crates/notes-core/src/{entities,metadata}
mkdir -p crates/notes-api/src/{auth,handlers}
mkdir -p crates/notes-api/tests
mkdir -p crates/notes-cli/src
mkdir -p crates/notes-mcp/src
mkdir -p .references
```
Then write the workspace `Cargo.toml` exactly as in
`CODE-PATTERNS.md §1a` (the **only** workspace `version = "0.0.1"` is the
starting point).
### 3. Write per-crate `Cargo.toml` files
For each of the four crates, emit a `Cargo.toml` modelled on the lines of
`CODE-PATTERNS.md §1b`. The path deps **must** point at
`../../AkurAI-Framework/crates/<crate>` (two levels up from
`crates/<name>/Cargo.toml` → `~/Projects/AkurAI-Framework/crates/`).
### 4. Write the four crate `lib.rs` / `main.rs` skeletons
The bare minimum that compiles. Do NOT implement handlers yet — just empty
module declarations.
`crates/notes-core/src/lib.rs`:
```rust
#![forbid(unsafe_code)]
pub mod entities;
pub mod metadata;
pub mod error;
pub mod types;
```
`crates/notes-api/src/lib.rs`:
```rust
#![forbid(unsafe_code)]
pub mod auth;
pub mod error;
pub mod handlers;
pub mod router_setup;
pub use router_setup::{build_router, NotesState, Route};
```
`crates/notes-cli/src/main.rs`: emit the `main.rs` skeleton from
`CODE-PATTERNS.md §3` with empty `cmd_serve::run` / `cmd_mcp::run` /
`cmd_seed::run` returning `Ok(())` — they'll be filled in by E03/E04/E05/E06.
Just make sure `cargo build -p akurai-notes` compiles.
`crates/notes-mcp/src/lib.rs`:
```rust
#![forbid(unsafe_code)]
pub mod server;
pub mod tools;
```
### 5. Write `rust-toolchain.toml` (copy from `~/Projects/akurai-crm/rust-toolchain.toml`)
Keeps the build host pin in sync with the rest of the AkurAI suite.
### 6. Write `VERSION`, `CHANGELOG.md`, `LICENSE`, `README.md`
- `VERSION` — contains single line `0.0.1`.
- `CHANGELOG.md`:
```markdown
# Changelog
All notable changes to AkurAI-Notes are documented here.
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to SemVer. Pre-1.0, minor versions may break.
## [Unreleased]
### Added
- Initial pure-Rust workspace scaffolded from AkurAI-Framework's `akurai new`
bootstrap. Server-rendered HTML frontend, declarative collections schema in
`site/backend/collections.toml`, and stub crates for `notes-cli`, `notes-api`,
`notes-core`, `notes-mcp`.
```
- `LICENSE` — MIT, full text copied from `~/Projects/akurai-crm/LICENSE` (CRM uses the same MIT).
- `README.md` — a 20-line stub: what the project is, the public URL
(`https://akurai-notes.olibuijr.com`), the build+deploy commands (`./deploy.sh patch`),
the constraint (pure-Rust, zero-runtime-deps, AkurAI-Framework-based).
### 7. Write the repo-local `AGENTS.md` + `ISA.md`
Copy the shape of `~/Projects/akurai-crm/AGENTS.md` (it's tiny — 12 lines:
project structure, key files). Rename CRM → Notes. Add `.plan/` to the
structure list. Same for a one-page `ISA.md` — see
`~/Projects/akurai-crm/ISA.md` for the size; just the *Goal*, *Vision*,
*Principles*, *Constraints*.
### 8. Verify the workspace compiles
```bash
cd ~/Projects/AkurAI-Notes
cargo build --workspace 2>&1 | tail -10
cargo tree --workspace --edges normal | rg -v '^\s*(├|└|│|\s)*.*(akurai-|notes-)' || echo "✓ zero external deps"
```
The first command must end with `Finished` (warnings OK). The second must print
the `✓ zero external deps` line — if any other crate name leaks through, **do
not proceed to E02** — backtrack and add a `notes-*` crate for that dependency.
### 9. Initial commit
```bash
cd ~/Projects/AkurAI-Notes
git add -A
git commit -m "Bootstrap AkurAI-Notes v0.0.1 — pure-Rust workspace via AkurAI-Framework 'akurai new'"
# Do NOT push yet, do NOT create the GitHub repo yet — deploy.sh does that on
# the first release in E07.
```
## Acceptance
```bash
cd ~/Projects/AkurAI-Notes
# Worktree maintains the zero-runtime-deps invariant:
cargo tree --workspace --edges normal --prefix none \
| awk '{print $1}' | sort -u \
| grep -Ev '^(akurai-[a-z]+$|notes-[a-z]+$|$)' \
| grep -v '^$' && echo "FAIL: external dep detected" || echo "PASS: zero external deps"
# All four crates are listed and version = 0.0.1:
cargo metadata --format-version 1 --no-deps \
| jq -r '.packages[] | "\(.name) \(.version)"'
# Expect:
# akurai-notes 0.0.1
# notes-api 0.0.1
# notes-cli 0.0.1
# notes-core 0.0.1
# notes-mcp 0.0.1
# The bootstrap scaffolder populated site/:
[ -f site/frontend/index.html ] && echo "PASS: site/frontend exists"
[ -f site/backend/collections.toml ] && echo "PASS: site/backend/collections.toml exists"
# VERSION + Cargo.toml lockstep:
[ "$(cat VERSION)" = "0.0.1" ] && echo "PASS: VERSION=0.0.1"
grep -q '^version = "0.0.1"$' Cargo.toml && echo "PASS: Cargo.toml=0.0.1"
```
## Files touched
```
site/ ← from `akurai new site`
crates/notes-core/Cargo.toml, src/{lib.rs,entities/mod.rs,metadata/mod.rs,error.rs,types.rs}
crates/notes-api/Cargo.toml, src/{lib.rs,auth/mod.rs,error.rs,handlers/mod.rs,router_setup.rs}
crates/notes-cli/Cargo.toml, src/{main.rs,cmd_serve.rs,cmd_mcp.rs,cmd_seed.rs}
crates/notes-mcp/Cargo.toml, src/{lib.rs,server.rs,tools.rs}
.references/.gitkeep
Cargo.toml
rust-toolchain.toml
VERSION
CHANGELOG.md
LICENSE
README.md
AGENTS.md
ISA.md
.gitignore
```
## Time
≈ 10 minutes.
## Depends on
Nothing. This is the foundation.