Use when the friend wants to start a brand-new project's memory — nothing
to scan yet, just a name. Triggers on the /ren:bootstrap-project slash
command. Stamps the shared wiki skeleton (additive) and queues an empty L2
pointer-map for the project. For an EXISTING repo with real code/git
history, use /ren:ingest-project instead.
Installs into .claude/skills of the current project.
Are you the author of Bootstrap Project?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/hazarsozer-bootstrap-project)
---
name: bootstrap-project
description: |
Use when the friend wants to start a brand-new project's memory — nothing
to scan yet, just a name. Triggers on the /ren:bootstrap-project slash
command. Stamps the shared wiki skeleton (additive) and queues an empty L2
pointer-map for the project. For an EXISTING repo with real code/git
history, use /ren:ingest-project instead.
version: 0.8.8
license: MIT
framework_version: "0.8.8"
schema_version: 1
type: skill
execution_tier: deterministic
contract:
required_outputs:
- "Any missing shared wiki dirs/files stamped (additive, never overwrite)"
- "If projects/<slug>/map.md doesn't exist yet: one Proposal queued (ADD, an empty L2 map). If it already exists: no proposal is queued and the existing map is left untouched."
- "When bootstrapping inside a project repo: <repo_root>/AGENTS.md written (portability pointer surface)"
- "Confirmation line printed to user including the queue id (or a 'map already exists' notice on the skip path)"
budgets:
turns: 2
files_written: 0
duration_seconds: 15
permissions:
read:
- "~/.renos/wiki/**"
- "wiki-skeleton/**"
write: []
execute: []
completion_conditions:
- "Either a QueueEntry exists at state_dir()/queue/<qid>.json with status=applied, op=ADD, page=projects/<slug>/map.md — or the map already existed and bootstrap() returned None with no new queue entry"
output_paths: []
tags: [onboarding, project, l2-map, bootstrap, queue]
related_skills: [ingest-project, install, interview]
references_required: []
references_on_demand: []
---
# bootstrap-project
The fresh-project half of the L2 pair. `/ren:ingest-project` scans an existing repo for facts; this skill is for a project with nothing to scan yet — just a name and an empty map to grow into.
## When to use this skill
- Friend invokes `/ren:bootstrap-project <slug>` for a new project with no existing code/history
- Friend says: "start tracking a new project called X", "set up memory for my new idea"
## When NOT to use this skill
- The project already has real code/git history to mine → `/ren:ingest-project [path]` instead (it produces a POPULATED map, not an empty one)
- The friend wants to look something up, not create a project → `/ren:recall`
## Behavior
1. Resolve `project_slug` (kebab-case) and the active `session` id. If bootstrapping inside a project repo (the common case), resolve `repo_root=Path.cwd()`.
2. Call `importlib.import_module("skills.bootstrap-project.lib").bootstrap(project_slug, session, repo_root=repo_root)`:
- Stamps the shared skeleton (`lib/skeleton.py` against `wiki-skeleton/manifest.yaml`'s `master` profile) into the wiki root — additive only; an already-onboarded wiki is untouched.
- Only when `projects/<slug>/map.md` does NOT exist yet: assembles an empty L2 map (`importlib.import_module("skills.ingest-project.lib").assemble_l2` — same frozen schema `ingest` uses, just with empty `knowledge`/`pointers` and a single "project bootstrapped" log line) and proposes it (`ADD`) at `lib.memory.queue`. If the map already exists, this step is skipped entirely — no proposal, no write — and `bootstrap()` returns `None`. The map is only ever SEEDED once; its real content is grown over time by other writers (`/ren:ingest-project`, `/ren:wrap`, `/ren:pin`), and bootstrap must never re-run over that growth.
- Stamps the manifest's `project` profile under `projects/<slug>/`: `overview.md` (the guaranteed wake-up orientation page) and, as of 0.6.2, the project-wiki skeleton — the empty `knowledge/` tree (the sanctioned home for this project's durable distilled pages, `type: project-knowledge`, `schema_version: 1`, `project: <slug>`; arbitrary-depth subdirectories, each with a hub named after the folder — `<topic>/<topic>.md`), a `schema.md` template stub (`type: project-schema` — the project's own SCHEMA document: taxonomy tree, naming conventions, what `raw/` holds; the ingest worker drafts the real taxonomy, bootstrap only marks the slot), and the empty `raw/` directory for immutable source material. Bootstrap only *creates* the skeleton; `/ren:ingest-project` and later sessions fill it, and the L2 map's Decision-map pointers index it (hubs and top-level pages, not deep leaves). Project-specific pages must NOT go in root-level `decisions/`·`patterns/`·`research/` — that's the promotion-gated instruction plane (`docs/decisions/2026-08-01-project-knowledge-subtree.md`, amended by `2026-08-01-hierarchical-project-wiki.md`).
- Always `producer="promotion"`, `writer="human"` — a human directly asked for this, so it's never quarantined on apply.
- When `repo_root` is given, also writes `<repo_root>/AGENTS.md` via `lib.portability.agents_surface.write_agents_md` — the thin, harness-neutral pointer file foreign coding agents (e.g. Codex) read to find this project's wiki map (Codex D5: the surface existed but had zero production callers before this wiring). A failure writing AGENTS.md never breaks bootstrap itself; omit `repo_root` (default `None`) to skip it entirely.
- Also writes `<repo_root>/CLAUDE.md` via `lib.adapter.claude_md.write_project_claude_md(repo_root, project_slug)` — stamps the thin RenOS pointer block (managed `ren:` markers) pointing at the project's L2 map, preserving any surrounding user content. Wired as of 0.4.3 (closes a 0.2 finalize claim that had zero production callers). Same failure isolation as `AGENTS.md`: a failure never breaks bootstrap itself.
3. `ingest-project`'s `lib.ingest()` also stamps `CLAUDE.md` now (issue #15) when given `repo_root=` — same additive marker-block contract. Both skills additionally record the repo-path↔slug pair in `state_dir()/projects.json` via `ren_paths.record_project_repo` (issue #19), so `detect_project` finds the project even when the checkout dir is named differently from the slug.
4. Confirm to the user: `Queued <qid> — bootstrapped projects/<slug>/map.md`. On the skip path (map already existed, `bootstrap()` returned `None`), instead confirm: `projects/<slug>/map.md already exists — left untouched.`
## Why this reuses `ingest-project`'s `assemble_l2`
Both skills produce the SAME frozen L2 schema (`type: l2-map`, Knowledge / Decision map / Log sections) — bootstrap just starts it empty. Rendering logic lives once in `skills/ingest-project/lib`, reached here via `importlib.import_module("skills.ingest-project.lib")` (the hyphenated directory name isn't a valid Python identifier segment, so a plain dotted `import` statement can't reach it — `importlib.import_module` resolves the string path without that restriction).
## What this skill does NOT do
- Scan anything. There's no repo to scan yet — that's `/ren:ingest-project`'s job.
- Write to the wiki directly. Both the skeleton stamp (additive-only, idempotent) and the map proposal go through their respective owning mechanisms (`lib/skeleton.py`, `lib.memory.queue`) — this skill orchestrates, it doesn't write.
- Populate the Knowledge or Decision map sections. They start empty; `/ren:ingest-project`, `/ren:pin`, or `/ren:wrap` fill them in over time.
## Failure-degradation modes
| Failure | Behavior | User-visible |
|---|---|---|
| No slug given | Refuse, prompt for a name | "What should this project be called? Usage: /ren:bootstrap-project <slug>" |
| A map already exists for this slug | Map write skipped entirely — no proposal queued, existing content (however much it's grown) is untouched | "projects/<slug>/map.md already exists — left untouched." |
| Skeleton stamp finds existing user files | Skipped, reported, nothing overwritten | (silent per-file; only new entries are queued) |
## References
- Task 4.4 (`skills/ingest-project/lib/__init__.py`) — `assemble_l2`, the shared L2 renderer
- Task 0.3 (`lib/skeleton.py`, `wiki-skeleton/manifest.yaml`) — the additive skeleton stamp
- Task 2.1 (`lib/memory/queue.py`) — the single write-queue this skill's only write path
- Spec §3.1 L2 — the pointer-map definition