diff --git a/.githooks/commit-msg b/.githooks/commit-msg new file mode 100755 index 0000000..8ec4704 --- /dev/null +++ b/.githooks/commit-msg @@ -0,0 +1,6 @@ +#!/usr/bin/env sh + +set -eu + +subject=$(sed -n '1p' "$1") +exec node scripts/check-commit-message.mjs "$subject" diff --git a/.github/workflows/git-policy.yml b/.github/workflows/git-policy.yml new file mode 100644 index 0000000..62b329b --- /dev/null +++ b/.github/workflows/git-policy.yml @@ -0,0 +1,76 @@ +# Git policy — enforces the Clean Flow branching model +# (spec: https://github.com/wgtechlabs/clean-flow) and the Clean Commit +# subject format (spec: https://github.com/wgtechlabs/clean-commit). +# Both specs ship as documentation only; this workflow is the enforcement. +name: Git policy + +on: + pull_request: + branches: + - dev + - main + push: + branches: + - dev + - main + +permissions: + contents: read + +jobs: + validate-pull-request: + if: github.event_name == 'pull_request' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} + fetch-depth: 0 + - name: Validate Clean Flow branch direction + env: + BASE_REF: ${{ github.event.pull_request.base.ref }} + HEAD_REF: ${{ github.head_ref }} + run: | + if [ "$BASE_REF" = "dev" ]; then + case "$HEAD_REF" in + feature/*|fix/*|docs/*|chore/*|test/*|refactor/*) ;; + *) + echo "PRs into dev must come from an approved short-lived work branch." + exit 1 + ;; + esac + elif [ "$BASE_REF" = "main" ] && [ "$HEAD_REF" != "dev" ]; then + echo "Only dev may open a PR into main." + exit 1 + fi + - name: Validate Clean Commit subjects in the pull request + env: + BASE_REF: ${{ github.event.pull_request.base.ref }} + BASE_SHA: ${{ github.event.pull_request.base.sha }} + PR_NUMBER: ${{ github.event.pull_request.number }} + PR_TITLE: ${{ github.event.pull_request.title }} + run: | + if [ "$BASE_REF" = "dev" ]; then + git fetch origin "pull/$PR_NUMBER/head:refs/remotes/origin/pr-head" + git log --no-merges --format=%s "$BASE_SHA..origin/pr-head" | node scripts/check-commit-message.mjs + else + node scripts/check-commit-message.mjs "$PR_TITLE" + fi + + validate-protected-push: + if: github.event_name == 'push' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Validate Clean Commit subjects pushed to protected branches + env: + BEFORE_SHA: ${{ github.event.before }} + AFTER_SHA: ${{ github.sha }} + run: | + if [ "$BEFORE_SHA" = "0000000000000000000000000000000000000000" ]; then + git log --no-merges --format=%s -1 "$AFTER_SHA" | node scripts/check-commit-message.mjs + else + git log --no-merges --format=%s "$BEFORE_SHA..$AFTER_SHA" | node scripts/check-commit-message.mjs + fi diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6435061 --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +# macOS +.DS_Store + +# Node +node_modules/ +*.log + +# Environment +.env +.env.* diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..47b46ae --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,69 @@ +# AGENTS.md + +This file is the entry point for AI agents working on this repository. Humans: start at `book/README.md`. + +## Project overview + + + +This project runs on the **BoCode workflow**: `code/` holds the source, `book/` holds the documentation stream and knowledge base. The highest architecture guidance lives inside the repository: long-term boundaries and hard constraints in `book/guidelines/architecture.md`, implementation snapshots in `book/docs/architecture/`. Internal documents never defer to external docs for authority. + +## Repository layout + +``` +/ +├── code/ # source code +└── book/ # documentation stream and knowledge base +``` + +**code and book are the project's two half-brains — neither is optional.** The relationship runs both ways: + +- **book → code**: plans drive implementation; guidelines provide the baseline; learn entries supply experience to consult before coding; issues provide direction for later iterations. +- **code → book**: after code changes, check whether book needs syncing; when a feature completes, write its summary / learn / issue back into book. + +**Core principle: the more complete the book, the more reference value for humans and agents.** Summaries are written for humans as reports; learn entries are written as searchable knowledge for both. + +**Book entry point: `book/README.md` — the master index, script-generated. Read it before reading anything else in book.** After any book change run `cd code && npm run book:index` to refresh it; every new document must carry a frontmatter `description` (one plain-language line about the content). + +## Workflow + +Feature development strictly follows the six-phase gate workflow — see `book/guidelines/workflow.md`. + +Git commits and branching strictly follow `book/guidelines/git-workflow.md`: every non-merge commit uses the Clean Commit format; independent big features branch from `dev`; small verified fixes may commit to `dev` directly; PRs serve multi-contributor work and the `dev → main` release, which only ever merges. Never commit or push directly to `main`. + +## Document routing + +| Output | Location | Audience | +|--------|----------|----------| +| Feature report | `book/notes/summary/YYYY-MM/` | Humans first | +| Experience & knowledge | `book/notes/learn/YYYY-MM/` | Humans + agents | +| Potential problems | `book/notes/issue/YYYY-MM/` | Humans + agents | +| Task tracking | `book/notes/task/` | Humans + agents | +| Architecture decisions | `book/docs/decisions/` | Humans first | +| Implementation plans | `book/plans/` | Agents first | +| Change log | `book/changelogs/YYYY-MM/` | Humans first | + +**Writing style**: everything in book is written plain — see `book/guidelines/writing-style.md`. + +## code ↔ book interaction rules + +1. **Before coding**: read `book/guidelines/` for the baseline; search `book/notes/learn/YYYY-MM/` for related experience. +2. **While coding**: new experience or pitfalls go straight into the current month's `book/notes/learn/YYYY-MM/`. +3. **After coding**: check the book — is the plan's status updated, is a summary needed, do new issues exist? +4. **Plans drive code**: `book/plans/` documents are the input to implementation. Read the plan, build in `code/`, write back to `book/`. +5. **Issues feed code**: `book/notes/issue/` entries are the direction of later improvements. + +`changelogs/` and `notes/{summary,learn,issue}/` archive under `YYYY-MM/`; the month is a physical grouping, retrieval happens through `book/README.md`, frontmatter, and links. `book/` opens directly as an Obsidian vault. + +## Hard constraints + +- Step 0 (the structured requirements brief) is required before any code +- No skipping between phases +- Phase 2 designs proceed only after user approval +- Problems found in Phase 5 / Phase 6 are **recorded, never fixed** +- Feature work touches no code outside its scope: no opportunistic refactors, no new abstractions + +## Tooling + +- `cd code && npm run book:index` — regenerate `book/README.md` after any book change (do not edit by hand; missing frontmatter `description` warns and exits 1) +- `node scripts/check-commit-message.mjs ""` — validate a commit subject against Clean Commit diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..1b716c0 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,3 @@ +# CLAUDE.md + +Read [AGENTS.md](AGENTS.md) — it is the single entry point for AI agents on this repository. Everything there applies in full: the six-phase gate workflow, the code↔book interaction rules, and the hard constraints. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..a598087 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Focus + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..fcacc0a --- /dev/null +++ b/README.md @@ -0,0 +1,180 @@ +# BoCode + +**A project template where documentation drives code, and code writes back.** + +BoCode gives a repository two half-brains — `code/` for the source, `book/` for the documentation stream and knowledge base — wired together in both directions. It is built for the way software is actually written now: by a human and AI coding agents together, where agents are fast but stateless, and the difference between a project that compounds and one that resets every session is whether its knowledge lives somewhere durable. + +Clone it, run one script, install three skills, and your project gains: a gated development workflow, a self-indexing knowledge base, a write-back discipline that turns every feature into accumulated experience, and a git policy that keeps history readable. + +--- + +## Why BoCode exists + +### The problem + +Three failures show up in almost every project built with AI agents: + +1. **Agents are stateless.** Every session starts from zero. Knowledge that isn't written down somewhere durable gets re-derived, re-asked, and re-broken — at full price, every time. +2. **Documentation rots.** Written once at the start, updated never. Because updating it pays off later and skipping it pays off now, it always loses. Eventually nobody trusts it, and reasonably so. +3. **Humans lose the wheel.** An agent will implement what you asked plus twelve things you didn't. Speed without gates means scope drifts, decisions go unrecorded, and the project's "why" evaporates. + +Each failure points at the same root: knowledge and control need a place to live that isn't chat history or someone's memory. + +### Two half-brains + +BoCode's answer is structural. A project has two halves: + +- **`code/`** is the executable truth — it answers *"how does it work right now?"* +- **`book/`** is the navigable truth — it answers *"why does it work this way, what did we decide, and what have we learned?"* + +Neither is optional. Code without a book is write-only: it runs, but nobody — human or agent — can cheaply find out why it's shaped the way it is. A book without code is a diary. The two live side by side at the top level, forever visible, so neither can be quietly forgotten. + +### The flywheel + +The halves drive each other: + +``` + book/ (knowledge base + driving force) + ┌─────────────────────────────────────┐ + │ plans/ → drives implementation │ + │ guidelines/ → provides the baseline │ + │ learn/ → provides experience │ + │ issue/ → provides direction │ + │ decisions/ → provides context │ + └──────────────┬──────────────────────┘ + │ drives + ▼ + code/ + │ produces + ▼ + ┌─────────────────────────────────────┐ + │ summary/ ← feature reports │ + │ learn/ ← new experience │ + │ issue/ ← new problems found │ + │ changelogs/ ← change records │ + │ plans/ ← completion status │ + └─────────────────────────────────────┘ +``` + +**book → code:** before implementation, the agent reads the plan (the construction blueprint), the guidelines (the baseline), the relevant learn entries (accumulated experience), and the open issues (known landmines). + +**code → book:** when the work is done, the wrap-up writes back — a summary a human can read without opening the diff, learn entries the next session will search, issues for problems found but deliberately not fixed, a changelog entry, and a regenerated index. + +This is the flywheel: every cycle leaves the book more complete than it found it, so every session — human or agent, today or in a year — starts from everything learned so far. **The more complete the book, the more it's worth to everyone who touches the project next.** Development compounds instead of resetting. + +--- + +## The method + +### Gates, not brakes + +Every feature runs a six-phase workflow with hard gates (`book/guidelines/workflow.md`, enforced in behavior by the `feature-flow` skill): + +| Phase | Output | Gate | +|-------|--------|------| +| Step 0 — requirements brief | background, scope, exclusions, requirement | Every slot filled — **the exclusions list is required**, an empty one is the top cause of out-of-scope changes | +| 1 — Analysis | impact map + risk list | No code changed | +| 2 — Design | data flow, files, interfaces | **User approval required** | +| 3 — Implementation | the code | Nothing outside the approved scope | +| 4 — Testing | tests, written first | All green, no weakened assertions | +| 5 — Review | findings list | Recorded, never fixed | +| 6 — Wrap-up | summary, learn, issues, changelog, index | Recorded, never fixed | + +The design intent: agents compress implementation to minutes, which moves the bottleneck to decisions and scope. The gates put human hands exactly there — Step 0 fills in what the request didn't say, Phase 2 is where a person approves direction, and Phases 5–6 enforce the separation of observing and fixing. **A problem found at review becomes a recorded issue; fixing it is separate work.** The gate that didn't let you fix it in passing is the same gate that keeps the review honest. + +### Write for the reader + +Book documents are routed by audience, not by kind of artifact (`book/notes/`): + +| Type | Written for | Shape | +|------|-------------|-------| +| `summary/` | Humans first | A report: background → what was done → why → outcome | +| `learn/` | Humans + agents | A searchable knowledge entry with tags — including symptom tags like "timeout" | +| `issue/` | Humans + agents | Problem + reproduction + suggested direction | +| `task/` | Working memory | A checklist | + +A summary that requires reading the diff isn't a summary. A learn entry whose title doesn't answer the question won't be found by the next session. The templates in `book/notes/README.md` encode the quality bar. + +### The index contract + +A knowledge base you can't navigate is a write-only disk. BoCode makes discoverability a build check: + +- Every book document starts with a frontmatter `description` — one plain-language line about the *content*, not the genre. +- `code/tools/gen-book-index.mjs` (zero dependencies, plain Node) regenerates `book/README.md` — the master index of every document, grouped by directory. +- A document missing its description makes the build **fail** (exit 1). Zero warnings is the only passing state. + +`book/README.md` doubles as the entry point: agents read it first to get the map; the folder also opens directly as an [Obsidian](https://obsidian.md) vault. + +### Speak human + +Documentation is read for years and written in minutes, so the style rule is strict and short (`book/guidelines/writing-style.md`): write like a specific person in a specific situation — professional is fine, templated is not. Cut filler openers and empty summaries; keep the facts locked — numbers, commands, names, and responsibility attribution never move. For Chinese writing, the full ruleset is the [shuorenhua](https://github.com/MrGeDiao/shuorenhua) skill; the guideline file is the language-agnostic default. + +### Clean git flow + +The git history is part of the book (`book/guidelines/git-workflow.md`). Every non-merge commit follows the [Clean Commit](https://github.com/wgtechlabs/clean-commit) format — `📦 new (index): add book index generator` — and branching follows the [Clean Flow](https://github.com/wgtechlabs/clean-flow) model (`work → dev → main`). The specs themselves ship no tooling; BoCode closes that gap with a zero-dependency validator running locally (`.githooks/`) and in CI (`.github/workflows/git-policy.yml`). Branching in practice: `dev` is the solo-developer integration branch where small verified fixes land directly; big features cut work branches; `main` only ever receives merge commits from `dev`. + +### Built with itself, shipped clean + +BoCode is its own first user: the foundation went through a structured requirements brief, an approved design plan, phased implementation with per-step verification, and a Clean Commit history — the whole story is readable in the git log. The template you receive is clean: no dated records, no leftover plans — an empty book waiting for yours. One example ships on purpose: [ADR-001](book/docs/decisions/ADR-001-adopt-bocode.md), the decision to run on this workflow — the first decision your project will re-affirm. + +--- + +## Quick start + +```bash +# 1. Create your repo from this template (GitHub "Use this template") +# or clone it: +git clone myproject && cd myproject + +# 2. Turn the template into your project (name, description, clean records): +bash scripts/init-project.sh myproject "What it does, in one line" + +# 3. Install the three skills for your AI agent: +cp -r skills/bocode skills/feature-flow skills/book-writeback / +# (ZCode: ~/.zcode/skills/ · Claude Code: ~/.claude/skills/ — see skills/README.md) + +# 4. Point your agent at AGENTS.md — most tools read it automatically. +# Then build something. The skills will drive the workflow. +``` + +Requirements: `bash` and `node` for the two scripts. No packages, no install step, no lockfile — the tooling is deliberately boring. + +## Repository tour + +| Path | What it is | +|------|------------| +| `AGENTS.md` | The entry point for AI agents — structure, rules, hard constraints | +| `book/guidelines/` | The rulebook: workflow, writing style, git, review | +| `book/README.md` | The master index (generated — start here) | +| `book/plans/` | Implementation blueprints | +| `book/notes/{summary,learn,task,issue}/` | The four note types | +| `book/docs/{architecture,api,decisions}/` | Snapshots, contracts, ADRs | +| `skills/` | `bocode`, `feature-flow`, `book-writeback` | +| `code/tools/gen-book-index.mjs` | The index generator | +| `scripts/init-project.sh` | Template → your project | +| `scripts/check-commit-message.mjs` | Clean Commit validator (+ `.githooks/`) | + +## FAQ + +**I have an existing project. Can I adopt BoCode?** +Yes — copy `book/`, `skills/`, `scripts/`, `.githooks/`, `AGENTS.md`, and `code/tools/` into it, merge your existing docs into the book, and run the index generator. No migration tooling needed; `init-project.sh` is only for fresh clones. + +**Does it lock me into a language or stack?** +No. The book is Markdown; the two scripts are plain Node with zero dependencies. Your `code/` can hold anything — the template's own `code/` contains only the tooling. + +**Which AI tools does it work with?** +Anything that reads `AGENTS.md` as its instruction file and supports the `SKILL.md` format (ZCode, Claude Code, and compatible agents). The workflow degrades gracefully without skills: the guidelines carry the same rules in prose. + +**What if I don't regenerate the index?** +Nothing breaks at runtime — but a stale index erodes the discoverability the whole system rests on, which is why the check makes missing descriptions fail loudly. + +**Why `YYYY-MM/` folders instead of per-feature folders?** +Months are stable, low-maintenance physical grouping. Features are found through the index, frontmatter, and links — not through directory nesting that fragments every multi-month effort. + +## Credits + +BoCode's git discipline builds on two open standards by WGTech Labs — [Clean Commit](https://github.com/wgtechlabs/clean-commit) (commit message format) and [Clean Flow](https://github.com/wgtechlabs/clean-flow) (branching model) — and adds the enforcement tooling both specs describe but don't ship. The plain-language writing standard draws on [shuorenhua](https://github.com/MrGeDiao/shuorenhua) by MrGeDiao. + +## License + +[MIT](LICENSE) diff --git a/README.zh-CN.md b/README.zh-CN.md new file mode 100644 index 0000000..18b129f --- /dev/null +++ b/README.zh-CN.md @@ -0,0 +1,180 @@ +# BoCode + +**一个文档驱动代码、代码回写文档的项目模板。** + +BoCode 给仓库装上两个半脑——`code/` 放源代码,`book/` 放文档流与知识库——并且双向连接。它面向的是现在软件真实的写法:人和 AI coding agent 一起开发。agent 快,但没有状态;一个项目是复利增长还是每个会话都从零开始,取决于它的知识有没有落在一个耐用的地方。 + +Clone、跑一条命令、装三个 skill,你的项目就有了:带关卡的六阶段开发流程、自动建索引的知识库、把每个功能变成经验沉淀的回写纪律、保持提交历史可读的 git 规范。 + +--- + +## 为什么需要 BoCode + +### 问题 + +用 AI agent 开发的项目几乎都会撞上三件事: + +1. **Agent 无状态。** 每个会话从零开始。没写下来的知识会被重新推导、重新提问、重新踩坑——每次都付全价。 +2. **文档腐烂。** 立项写一次,之后永不更新。更新文档的收益在将来,跳过的收益在眼前,所以它总是输。最后没人信文档,也确实不该信。 +3. **人失去方向盘。** agent 会实现你要求的,外加十二件你没要求的。没有关卡的速度意味着作用域漂移、决策失载、项目的"为什么"蒸发。 + +三个问题指向同一个根:知识和控制需要住在聊天记录和人脑之外的地方。 + +### 双半脑 + +BoCode 的答案是结构性的。一个项目有两半: + +- **`code/`** 是可执行的真相——回答"它现在是怎么运作的" +- **`book/`** 是可导航的真相——回答"它为什么这样运作、我们做过什么决定、学到了什么" + +缺一不可。没有 book 的 code 是只写的:它能跑,但任何人(人或 agent)都难以低成本地搞清它为什么长这样。没有 code 的 book 是日记。两半并排放在顶层,永远看得见,谁也不会被悄悄忘掉。 + +### 飞轮 + +两半互相驱动: + +``` + book/ (知识库 + 驱动源) + ┌─────────────────────────────────────┐ + │ plans/ → 驱动代码实现 │ + │ guidelines/ → 提供编码基线 │ + │ learn/ → 提供经验参考 │ + │ issue/ → 提供改进方向 │ + │ decisions/ → 提供决策上下文 │ + └──────────────┬──────────────────────┘ + │ 驱动 + ▼ + code/ + │ 产出 + ▼ + ┌─────────────────────────────────────┐ + │ summary/ ← 功能完成报告 │ + │ learn/ ← 新增经验沉淀 │ + │ issue/ ← 新增潜在问题 │ + │ changelogs/ ← 变更记录 │ + │ plans/ ← 标记完成状态 │ + └─────────────────────────────────────┘ +``` + +**book → code**:实现之前,agent 先读 plan(施工图)、guidelines(基线)、相关的 learn 条目(积累的经验)、开放的 issue(已知的雷)。 + +**code → book**:工作完成后收尾回写——人类不看 diff 也能读懂的 summary、下个会话能检索到的 learn、只记录不修复的 issue、一条 changelog、刷新过的索引。 + +这就是飞轮:每转一圈,book 都比上一圈更完整,于是每个会话——人或 agent,今天或一年后——都站在全部既有经验之上。**book 越完整,对下一个接触项目的人越值钱。** 开发变成复利,而不是重置。 + +--- + +## 方法 + +### 是关卡,不是刹车 + +每个功能走六阶段流程,每阶段是硬关卡(`book/guidelines/workflow.md`,由 `feature-flow` skill 在行为层执行): + +| 阶段 | 产出 | 关卡 | +|------|------|------| +| Step 0 需求 Brief | 背景、作用域、排除项、需求 | 每个槽位填实——**排除清单必填**,空白排除项是越界改动的头号原因 | +| 1 需求分析 | 影响图 + 风险清单 | 不改任何代码 | +| 2 设计 | 数据流、文件清单、接口 | **用户确认后才推进** | +| 3 实现 | 代码 | 严格按批准的作用域 | +| 4 测试 | 先写测试 | 全绿,不削弱断言 | +| 5 Review | 问题清单 | 只记录,不修复 | +| 6 收尾 | summary、learn、issue、changelog、索引 | 只记录,不修复 | + +设计意图:agent 把实现压缩到分钟级,瓶颈于是转移到决策和作用域。关卡把人的手正好放在那里——Step 0 补上需求没说的话,Phase 2 由人批准方向,Phase 5/6 强制"观察"与"行动"分离。**Review 时发现的问题变成一条记录的 issue,修复是另一件事。** 不让你顺手修的这道门,和让 review 保持诚实的是同一道门。 + +### 为读者而写 + +book 文档按读者分流,不按产物类型(`book/notes/`): + +| 类型 | 写给谁 | 形态 | +|------|--------|------| +| `summary/` | 人类为主 | 报告:背景 → 做了什么 → 为什么 → 效果 | +| `learn/` | 人类 + agent | 可检索的知识条目,带 tags——包括症状词("timeout"、"drift") | +| `issue/` | 人类 + agent | 问题 + 复现 + 建议方向 | +| `task/` | 工作记忆 | 检查清单 | + +要读 diff 才能懂的 summary 不是 summary;标题不能回答问题的 learn 不会被下个会话检索到。`book/notes/README.md` 里的模板就是质量线。 + +### 索引契约 + +导航不了的知识库只是写进磁盘的单行道。BoCode 把可发现性做成构建检查: + +- 每篇 book 文档头部有 frontmatter `description`——一行说人话的内容摘要,写内容不写体裁 +- `code/tools/gen-book-index.mjs`(零依赖、纯 Node)重新生成 `book/README.md`——全库文档的总索引,按目录分组 +- 缺 description 的文档让构建**失败**(退出码 1)。零警告是唯一通过状态 + +`book/README.md` 同时是入口:agent 先读它拿全库地图;这个目录还可以直接用 [Obsidian](https://obsidian.md) 打开当 vault。 + +### 说人话 + +文档要被读很多年、却在几分钟内写完,所以风格规则短而严(`book/guidelines/writing-style.md`):像具体的人在当前场景下表达——专业可以,模板化不行。删开场套话和空总结;事实锁死——数字、命令、名称、责任主体一律不动。中文写作的完整规则在 [shuorenhua](https://github.com/MrGeDiao/shuorenhua) skill;guideline 文件是跨语言的默认兜底。 + +### 干净的 git 流 + +git 历史是 book 的一部分(`book/guidelines/git-workflow.md`)。每个非合并提交遵循 [Clean Commit](https://github.com/wgtechlabs/clean-commit) 格式——`📦 new (index): add book index generator`;分支遵循 [Clean Flow](https://github.com/wgtechlabs/clean-flow) 模型(`工作分支 → dev → main`)。两个规范本身不带工具,BoCode 把它们补齐了:零依赖校验器在本地(`.githooks/`)和 CI(`.github/workflows/git-policy.yml`)双重执行。实践中:`dev` 是单人开发的集成分支,验证过的小修复直接落;大功能切工作分支;`main` 只接收来自 `dev` 的 merge commit。 + +### 用自己建的,干干净净交付 + +BoCode 是自己的第一个用户:奠基走完了结构化需求、经确认的设计计划、分阶段施工与逐步验证,提交历史全程 Clean Commit——整个故事在 git log 里可读。你拿到的模板是干净的:没有带日期的记录、没有遗留的 plan,book 是空的、等着写你的。只留一个示范:[ADR-001](book/docs/decisions/ADR-001-adopt-bocode.md)——"采用这套工作流"的决策记录,这也是你的项目要重申的第一个决策。 + +--- + +## 快速开始 + +```bash +# 1. 用 GitHub "Use this template" 从本模板建仓库, +# 或者直接 clone: +git clone myproject && cd myproject + +# 2. 把模板变成你的项目(改名、填描述、清理记录): +bash scripts/init-project.sh myproject "一句话说明它是干什么的" + +# 3. 给你的 AI agent 装上三个 skill: +cp -r skills/bocode skills/feature-flow skills/book-writeback / +# (ZCode: ~/.zcode/skills/ · Claude Code: ~/.claude/skills/ —— 见 skills/README.md) + +# 4. 让你的 agent 指向 AGENTS.md——多数工具会自动读它。 +# 然后开发点什么。skill 会驱动整个流程。 +``` + +依赖:`bash` 和 `node`(两个脚本用)。没有包管理、没有 install 步骤、没有 lockfile——工具链刻意做得乏味。 + +## 仓库导览 + +| 路径 | 是什么 | +|------|--------| +| `AGENTS.md` | AI agent 的入口——结构、规则、硬约束 | +| `book/guidelines/` | 规则书:工作流、书写风格、git、review | +| `book/README.md` | 总索引(脚本生成——从这里开始) | +| `book/plans/` | 实现计划(施工图) | +| `book/notes/{summary,learn,task,issue}/` | 四类笔记 | +| `book/docs/{architecture,api,decisions}/` | 快照、契约、ADR | +| `skills/` | `bocode`、`feature-flow`、`book-writeback` | +| `code/tools/gen-book-index.mjs` | 索引生成器 | +| `scripts/init-project.sh` | 模板 → 你的项目 | +| `scripts/check-commit-message.mjs` | Clean Commit 校验器(含 `.githooks/`) | + +## 常见问题 + +**已有项目能用 BoCode 吗?** +能。把 `book/`、`skills/`、`scripts/`、`.githooks/`、`AGENTS.md`、`code/tools/` 拷进去,已有文档并进 book,跑一次索引生成。不需要迁移工具;`init-project.sh` 只服务新 clone。 + +**会绑定语言或技术栈吗?** +不会。book 是 Markdown;两个脚本是零依赖纯 Node。你的 `code/` 放什么都行——模板自己的 `code/` 只装工具。 + +**支持哪些 AI 工具?** +任何把 `AGENTS.md` 当指令入口、支持 `SKILL.md` 格式的工具(ZCode、Claude Code 及兼容 agent)。没有 skill 时流程优雅降级:guidelines 用文字承载同样的规则。 + +**不刷索引会怎样?** +运行时什么都不会坏——但索引一旦过期,整个系统赖以成立的可发现性就开始流失。所以检查让缺 description 的文档大声失败。 + +**为什么用 `YYYY-MM/` 归档而不是按功能建目录?** +月份是稳定、低维护的物理分组。功能靠索引、frontmatter 和链接找到——不靠把每个跨月功能切碎的目录嵌套。 + +## 致谢 + +BoCode 的 git 纪律构建在 WGTech Labs 的两个开放标准上——[Clean Commit](https://github.com/wgtechlabs/clean-commit)(提交格式)与 [Clean Flow](https://github.com/wgtechlabs/clean-flow)(分支模型)——并为两个"只有规范没有工具"的标准补上了执行工具链。说人话书写规范源自 MrGeDiao 的 [shuorenhua](https://github.com/MrGeDiao/shuorenhua)。 + +## 许可 + +[MIT](LICENSE) diff --git a/book/README.md b/book/README.md new file mode 100644 index 0000000..52434c3 --- /dev/null +++ b/book/README.md @@ -0,0 +1,72 @@ +--- +description: Master index of the book — the map of every document. Regenerate with `cd code && npm run book:index` after any book change +--- + +# book — bocode master index + +> Generated by a script — do not edit by hand. After any book change run: `cd code && npm run book:index`. +> Every new file must carry a frontmatter `description` (one plain-language line about the content, not the genre); the build warns and exits 1 otherwise. + +## How to use this book + +- **AI agents**: read this file first for the full map, then follow links to what you need. Before writing any book document, read `guidelines/writing-style.md`. +- **Humans**: browse by the directory table below. Rules live in `guidelines/`, blueprints in `plans/`, experience in `notes/learn/`, architecture in `docs/architecture/`, decisions in `docs/decisions/`. +- **By time**: `changelogs/` and `notes/{summary,learn,issue}/` archive under `YYYY-MM/`; the month is a physical grouping only — do not nest deeper by feature. +- **By feature**: search this index for a feature name, keyword, or frontmatter summary; `notes/learn/` entries are also searchable by their `tags`. +- **Obsidian**: open `book/` directly as a vault. Links are plain relative Markdown; if you move files, rerun the index. + +## Directory map + +| Directory | Purpose | +|------|------| +| `changelogs/` | Change log: what landed and when | +| `docs/` | Technical docs: architecture, API, decisions | +| `docs/api/` | API design and interface docs | +| `docs/architecture/` | Architecture snapshots: modules, data flow | +| `docs/decisions/` | Architecture decision records (ADR) | +| `guidelines/` | Development rules every contributor (including AI) must follow | +| `notes/` | Running records: learn / summary / task / issue | +| `plans/` | Implementation plans: the construction blueprint agents build from | + +## All files + +### changelogs/ + +- [README.md](changelogs/README.md) — Changelogs directory usage — dated change records archived by month, found via the index + +### docs/ + +- [README.md](docs/README.md) — Map of docs/ — architecture snapshots, API design, and architecture decision records + +### docs/api/ + +- [README.md](docs/api/README.md) — API design docs — where interface contracts are written before and while they are implemented + +### docs/architecture/ + +- [README.md](docs/architecture/README.md) — Architecture snapshots — dated documents describing the current state of modules and data flow + +### docs/decisions/ + +- [ADR-001-adopt-bocode.md](docs/decisions/ADR-001-adopt-bocode.md) — We run this repository on the BoCode workflow — book drives code, code writes back, six phases gate every feature +- [README.md](docs/decisions/README.md) — How to write an ADR here — sections, naming, numbering, and when a decision needs a record + +### guidelines/ + +- [README.md](guidelines/README.md) — Index of the five guidelines — workflow, writing style, git, review checklist, plus the architecture and coding templates +- [architecture.md](guidelines/architecture.md) — Template for your project's long-term architecture rules — boundary invariants, module map, tech baseline, with a worked example of boundary-style rules +- [coding-style.md](guidelines/coding-style.md) — Template for your project's coding baseline — the language-specific rules any contributor or agent must follow +- [git-workflow.md](guidelines/git-workflow.md) — Clean Commit message format and Clean Flow branch, PR, and merge rules for solo and team development +- [review-checklist.md](guidelines/review-checklist.md) — The eight code-review checks every change must pass — findings are recorded, never fixed in passing +- [workflow.md](guidelines/workflow.md) — Six-phase gate workflow with the seven code↔book interaction rules and the document routing table +- [writing-style.md](guidelines/writing-style.md) — Plain-language writing standard for every book document — fidelity contract first, then minimal style rules, intensity levels, and a read-back check + +### notes/ + +- [README.md](notes/README.md) — The four note types (learn, summary, task, issue), when each is written, the retrieval order, and the template for each + +### plans/ + +- [README.md](plans/README.md) — Plans directory usage — implementation plans land here after Phase 2 approval, with naming and the plan template + + diff --git a/book/changelogs/README.md b/book/changelogs/README.md new file mode 100644 index 0000000..42ed930 --- /dev/null +++ b/book/changelogs/README.md @@ -0,0 +1,17 @@ +--- +description: Changelogs directory usage — dated change records archived by month, found via the index +--- + +# Changelogs + +The project's timeline: what landed, when. Files archive under `YYYY-MM/` (e.g. `2026-09/`); the month is only for time navigation — no deeper feature subdirectories. + +## How to find things + +- **What happened recently**: open the newest month. +- **A specific feature**: search `book/README.md` for the feature name or a keyword. +- **Full context**: follow the same date into `notes/summary/`, `notes/learn/`, and `notes/issue/`. + +## Naming + +`YYYY-MM-DD-.md` diff --git a/book/docs/README.md b/book/docs/README.md new file mode 100644 index 0000000..9f2002f --- /dev/null +++ b/book/docs/README.md @@ -0,0 +1,15 @@ +--- +description: Map of docs/ — architecture snapshots, API design, and architecture decision records +--- + +# Docs + +Technical documentation: what the system looks like and why it looks that way. + +| Directory | Content | Difference from guidelines | +|-----------|---------|---------------------------| +| `architecture/` | Implementation snapshots — the current state of modules and data flow | `guidelines/architecture.md` holds long-term rules; snapshots hold dated, current truth | +| `api/` | API design and interface contracts | Guidelines say how to review; API docs say what the interfaces are | +| `decisions/` | Architecture decision records (ADR) — why choices were made | Decisions record one choice each; guidelines accumulate the standing rules | + +New documents need a frontmatter `description` (see `guidelines/writing-style.md`), and the index must be regenerated after adding them (`cd code && npm run book:index`). diff --git a/book/docs/api/README.md b/book/docs/api/README.md new file mode 100644 index 0000000..f00699b --- /dev/null +++ b/book/docs/api/README.md @@ -0,0 +1,13 @@ +--- +description: API design docs — where interface contracts are written before and while they are implemented +--- + +# API docs + +Interface contracts: endpoints, request/response shapes, error codes, and the invariants callers rely on. Write the contract here when designing an interface, keep it current while the interface lives. + +## Conventions + +- One document per API surface (or per version of it), not per endpoint +- Every field listed with type, meaning, and whether it's optional +- Error responses enumerated with their meanings — no "and various errors" diff --git a/book/docs/architecture/README.md b/book/docs/architecture/README.md new file mode 100644 index 0000000..3ab3701 --- /dev/null +++ b/book/docs/architecture/README.md @@ -0,0 +1,13 @@ +--- +description: Architecture snapshots — dated documents describing the current state of modules and data flow +--- + +# Architecture snapshots + +Each snapshot describes how the system actually looks at a point in time: processes, modules, data flow, deployment shape. The long-term rules live in `guidelines/architecture.md`; this directory holds what is true today. + +## Conventions + +- One document per process, module, or cross-cutting concern; for a dated view, name it `YYYY-MM-DD-.md` +- A snapshot superseded by a newer one gets a `superseded by ` line at the top — never delete history silently +- Every snapshot starts with a one-paragraph orientation: what runs where, and what talks to what diff --git a/book/docs/decisions/ADR-001-adopt-bocode.md b/book/docs/decisions/ADR-001-adopt-bocode.md new file mode 100644 index 0000000..c456e84 --- /dev/null +++ b/book/docs/decisions/ADR-001-adopt-bocode.md @@ -0,0 +1,35 @@ +--- +description: We run this repository on the BoCode workflow — book drives code, code writes back, six phases gate every feature +--- + +# ADR-001: Adopt the BoCode workflow + +## Status + +Accepted — the template ships with this decision made. Revisit only if the project outgrows it. + +## Context + +Most implementation in this project happens with AI coding agents. Agents are fast but stateless: every session starts from zero, and project knowledge either lives somewhere durable or it's gone. In projects that keep everything in chat history and memory, the same questions get re-answered, the same pitfalls get re-hit, and humans lose track of why the code looks the way it does. + +The alternatives considered: + +- **Convention elsewhere (ADR-only / README-only)**: too thin — it records decisions but not experience or plans +- **Issue-tracker-centric**: tasks live, but knowledge doesn't; the tracker is a queue, not a book +- **No system**: knowledge evaporates with each session + +## Decision + +This project keeps two top-level halves — `code/` and `book/` — in a bidirectional relationship: + +- `book/` drives `code/`: plans are the construction blueprint, guidelines are the baseline, learn entries are the experience base, issues are the improvement backlog +- `code/` writes back to `book/`: every feature ends with a summary, new learnings, new issues, a changelog entry, and a regenerated index +- Every feature moves through six gated phases (Step 0 brief → analysis → design approval → implementation → testing → review/wrap-up), with design requiring user approval and review/wrap-up recording rather than fixing +- Every book document carries a one-line frontmatter description; a zero-dependency script regenerates the master index and fails when one is missing + +## Consequences + +- Every feature leaves written traces; agents start each session from the book, not from zero +- Humans can follow the project without reading code: summaries report, decisions explain +- Wrap-up costs a few extra minutes per feature — accepted as the price of compounding +- The discipline only pays while the index stays green and the writing stays plain; both are enforced by tooling and style rules rather than willpower diff --git a/book/docs/decisions/README.md b/book/docs/decisions/README.md new file mode 100644 index 0000000..aeda428 --- /dev/null +++ b/book/docs/decisions/README.md @@ -0,0 +1,28 @@ +--- +description: How to write an ADR here — sections, naming, numbering, and when a decision needs a record +--- + +# Decisions (ADR) + +An architecture decision record answers one question: why this choice. Future readers — humans and agents — will ask "why is it like this"; the ADR is the answer they find. + +## When to write one + +- A choice that's expensive to reverse +- A choice a reasonable person could have made differently +- A boundary rule in `guidelines/architecture.md` being added or changed + +## Format + +| Section | Content | +|---------|---------| +| Status | Proposed / Accepted / Superseded by ADR-NNN | +| Context | The forces at play when the decision was made — constraints, alternatives considered | +| Decision | What was chosen, in one or two sentences | +| Consequences | What gets better, what gets harder, what we accepted | + +## Naming + +`ADR-NNN-.md`, numbering monotonically up, never reused. A decision that reverses an earlier ADR gets a new number and flips the old one to "Superseded by ADR-NNN". + +See [ADR-001](ADR-001-adopt-bocode.md) for a worked example. diff --git a/book/guidelines/README.md b/book/guidelines/README.md new file mode 100644 index 0000000..e1dfb0e --- /dev/null +++ b/book/guidelines/README.md @@ -0,0 +1,18 @@ +--- +description: Index of the five guidelines — workflow, writing style, git, review checklist, plus the architecture and coding templates +--- + +# Guidelines + +The project's development rules. Every contributor — including AI agents — follows them. + +| File | Content | +|------|---------| +| `workflow.md` | Six-phase gate workflow and the code↔book interaction rules | +| `writing-style.md` | Plain-language standard for every book document | +| `git-workflow.md` | Clean Commit format and Clean Flow branch/PR/merge rules | +| `review-checklist.md` | The eight code-review checks | +| `architecture.md` | Long-term architecture rules (template — replace per project) | +| `coding-style.md` | Language-specific coding baseline (template — replace per project) | + +Start with `workflow.md`; the others answer questions it raises. diff --git a/book/guidelines/architecture.md b/book/guidelines/architecture.md new file mode 100644 index 0000000..6f52d09 --- /dev/null +++ b/book/guidelines/architecture.md @@ -0,0 +1,31 @@ +--- +description: Template for your project's long-term architecture rules — boundary invariants, module map, tech baseline, with a worked example of boundary-style rules +--- + +# Architecture + +> **This file is a template — replace it in your project.** It holds the long-term architecture truth: boundary invariants, the module map, the technology baseline, and data ownership. What exists *today* belongs in `docs/architecture/` snapshots; what must stay true *forever* belongs here. + +## What to define here + +1. **Boundary invariants** — the "X ≠ Y" rules (see the worked example below). Two concerns that must never fuse, each with the reason it exists. +2. **Module map** — the top-level modules/processes, their responsibilities, and who talks to whom. One sentence per module is enough; details live in snapshots. +3. **Technology baseline** — languages, frameworks, storage, and the rule for swapping any of them (usually: via an adapter, never via a rewrite). +4. **Data ownership** — for each store or dataset, the single module allowed to write it. + +## Worked example: boundary invariants + +A boundary rule names two concerns and keeps them apart, with the reason a reviewer can check: + +| Rule | Why | +|------|-----| +| Provider ≠ Domain | An external provider's structure must not leak into domain logic; swapping providers then touches adapters only | +| Raw Data ≠ Derived View | Raw inputs and computed views have different lifecycles and different owners; fusing them couples ingestion to presentation | +| Primary DB ≠ Cache | A cache may speed things up but never own truth; everything in it must be rebuildable | + +Write rules you can enforce in review. If a rule can't be checked against a diff, it's a wish, not a boundary. + +## Maintenance + +- Boundary rules change only through an ADR in `docs/decisions/`. +- When reality drifts from this file, fix reality or fix the file — never let them disagree silently. diff --git a/book/guidelines/coding-style.md b/book/guidelines/coding-style.md new file mode 100644 index 0000000..2e05a15 --- /dev/null +++ b/book/guidelines/coding-style.md @@ -0,0 +1,20 @@ +--- +description: Template for your project's coding baseline — the language-specific rules any contributor or agent must follow +--- + +# Coding style + +> **This file is a template — replace it in your project.** It holds the coding baseline a reviewer can check against a diff. Anything that needs a tool to verify (formatting, lint) should be wired into a script or CI, and only referenced here. + +## Sections to fill + +- **Language & toolchain** — versions, runtime, package manager; what counts as "the standard way to run this project" +- **Naming** — files, types, functions, variables, constants; the project's one convention per kind +- **Formatting & lint** — the tool, the command, and that CI fails when it's dirty +- **Error handling** — how errors are raised, wrapped, and surfaced; what never gets swallowed +- **Testing conventions** — where tests live, how they're named, what must be covered before a change counts as done +- **Dependencies** — the policy for adding one (and the default answer: don't, unless it removes more code than it adds) + +## Rule of thumb + +One rule per line, each checkable in review. Prefer "we always X" over paragraphs of rationale — the *why* goes into `docs/decisions/` as an ADR when it's interesting, and stays out of the way when it's not. diff --git a/book/guidelines/git-workflow.md b/book/guidelines/git-workflow.md new file mode 100644 index 0000000..2115250 --- /dev/null +++ b/book/guidelines/git-workflow.md @@ -0,0 +1,129 @@ +--- +description: Clean Commit message format and Clean Flow branch, PR, and merge rules for solo and team development +--- + +# Git workflow + +This repository follows [Clean Commit](https://github.com/wgtechlabs/clean-commit) and [Clean Flow](https://github.com/wgtechlabs/clean-flow): commit history stays readable, and `main` only ever receives code that already integrated stably on `dev`. Both specs ship as documentation only — this repository enforces them with its own zero-dependency tooling (`scripts/check-commit-message.mjs`, `.githooks/`, and `.github/workflows/git-policy.yml`). + +## The whole flow in one picture + +```text +Big feature: feature/* work branch ── local acceptance ──> dev ── PR + merge commit ──> main +Small fix: direct commit ─────────────────────────────────────> dev +``` + +| Branch | Purpose | Allowed sources | +|--------|---------|-----------------| +| `main` | Stable, releasable code | Merge commits from `dev` only | +| `dev` | The solo-developer integration branch | Verified small fixes, docs, low-risk iterations commit directly; big features merge in when done | +| Work branches | Independent big features or cross-cutting changes | Cut from the latest `dev` | + +Never commit or push directly to `main`. Solo development optimizes for speed: small, focused, locally verified fixes and docs may land on `dev` directly. Every independent big feature still starts from a work branch, so unfinished capability never leaks into `dev`. + +PRs are for reviews that deserve their own record: multi-person collaboration, and every `dev → main` release. A solo big feature may squash-merge into `dev` after local acceptance without a PR; a high-risk change can still open one deliberately. + +## Branch naming + +Short, lowercase, hyphenated: + +```text +feature/user-profile +fix/login-timeout +docs/deployment-guide +chore/update-dependencies +test/upload-validation +refactor/api-client +``` + +## Clean Commit format + +Every non-merge commit subject uses one of these forms. The rule applies to new commits from the moment this standard lands; existing history is never rewritten. + +```text + : + (): + !: + ! (): +``` + +| Emoji | Type | Use for | +|:---:|---|---| +| 📦 | `new` | New features, files, or capabilities | +| 🔧 | `update` | Changes, fixes, refactors, improvements to existing code | +| 🗑️ | `remove` | Deleting code, files, features, or dependencies | +| 🔒 | `security` | Security fixes and vulnerability patches | +| ⚙️ | `setup` | Config, CI/CD, tooling, build system | +| ☕ | `chore` | Maintenance, dependency updates, cleanup | +| 🧪 | `test` | Adding, updating, or fixing tests | +| 📖 | `docs` | Documentation changes | +| 🚀 | `release` | Version releases and release preparation | + +Rules: type and scope are lowercase; scope is optional and short; the description is present tense, doesn't end with a period, and stays under 72 characters. The breaking marker `!` goes right after the type and only on `new`, `update`, `remove`, and `security`. + +```text +📦 new (auth): add login rate limiting +🔧 update (api): improve error handling +🧪 test: add upload validation coverage +📖 docs: describe deployment process +🚀 release: promote dev to main +``` + +The repo script validates format, type, scope, breaking markers, trailing periods, and length; present tense stays a judgment call at review. + +## Solo agile development + +### Small fixes and fast iterations + +Keep them single-purpose, quickly verifiable, free of migrations, irreversible data operations, or wide refactors. After local checks pass, commit straight to `dev`: + +```bash +git checkout dev +git pull --ff-only origin dev +# change, test +node scripts/check-commit-message.mjs "🔧 update (form): handle empty optional input" +git commit -am "🔧 update (form): handle empty optional input" +git push origin dev +``` + +### Independent big features + +Start from a work branch. Local acceptance is enough for a solo feature — squash-merge into `dev`, then push: + +```bash +# 1. from the latest dev +git checkout dev +git pull --ff-only origin dev + +# 2. cut a work branch +git checkout -b feature/user-profile + +# 3. validate a subject before committing +node scripts/check-commit-message.mjs "📦 new (auth): add login rate limiting" +git add +git commit -m "📦 new (auth): add login rate limiting" + +# 4. sync with dev before merging back +git fetch origin +git rebase origin/dev +git checkout dev +git merge --squash feature/user-profile +git commit -m "📦 new (auth): add login rate limiting" +git push origin dev +``` + +When several people build the same feature, open the PR from `feature/user-profile` into `dev` and **Squash and merge** after checks; the squash subject uses Clean Commit too. Delete the work branch after merging. + +When `dev` is stable, open the `dev → main` PR and choose **Create a merge commit** to preserve the integration boundary. The merge-commit subject is Clean Commit as well, e.g.: + +```text +🚀 release: promote dev to main +``` + +## Automation and platform settings + +- PRs into `dev`/`main` and pushes to them are checked by `.github/workflows/git-policy.yml` for branch direction and commit subjects; direct pushes to `dev` still pass Clean Commit validation. +- Run `git config core.hooksPath .githooks` once per clone to get the same `commit-msg` check locally. +- Protect `main` on GitHub: require a PR from `dev`, status checks, and merge commits. Keep direct pushes to `dev` allowed for solo speed; team PRs still use squash merges. + +On private repos whose plan lacks the branch-protection API, CI and the local hook already enforce the policy in-repo; enable the platform settings as soon as the repo is public or the plan supports them. diff --git a/book/guidelines/review-checklist.md b/book/guidelines/review-checklist.md new file mode 100644 index 0000000..e0ab439 --- /dev/null +++ b/book/guidelines/review-checklist.md @@ -0,0 +1,20 @@ +--- +description: The eight code-review checks every change must pass — findings are recorded, never fixed in passing +--- + +# Code review checklist + +## Required checks + +- [ ] Duplicated code +- [ ] Authorization / permission holes +- [ ] Race conditions +- [ ] Transaction boundaries +- [ ] Missed notifications (where the design calls for one) +- [ ] Missed boundaries (input ranges / empty values / extremes) +- [ ] Complexity added +- [ ] Changes outside the approved scope + +## Principle + +**Record, never fix.** Findings go on the list and wait for the next round or a separate task. Fixing in passing breaks the gate — the review no longer reviews what was built. diff --git a/book/guidelines/workflow.md b/book/guidelines/workflow.md new file mode 100644 index 0000000..aa05bc2 --- /dev/null +++ b/book/guidelines/workflow.md @@ -0,0 +1,74 @@ +--- +description: Six-phase gate workflow with the seven code↔book interaction rules and the document routing table +--- + +# Workflow + +## Development process — six phases, hard gates + +Every feature moves through these phases in order. **No skipping.** + +| Phase | Name | Output | Gate | +|------|------|--------|------| +| Step 0 | Structured requirements brief | Requirements brief | Every slot filled | +| Phase 1 | Analysis | Impact map + risk list | No code changed | +| Phase 2 | Design | Data flow, file list, interfaces | **User approval required before Phase 3** | +| Phase 3 | Implementation | Code | Strictly per design; nothing outside scope | +| Phase 4 | Testing | Test cases | All green; no weakened assertions | +| Phase 5 | Code review | Review findings | Record only — no fixes | +| Phase 6 | Wrap-up | Docs, learnings, issues | Record only — no fixes | + +Step 0 comes before any code. Fill the brief: background, scope (what it affects, what it explicitly does **not** affect, and the boundaries), and the requirement itself. An empty "does not affect" list is the number-one cause of out-of-scope changes in Phase 3 — it is a required slot, not an optional one. + +Phase 4 runs test-first: write a failing test, write the minimum implementation that passes it, refactor with the test staying green. Coverage must include the normal path, boundary inputs (ranges, empty, extremes), error paths, and a regression check that existing behavior didn't break. + +Phases 5 and 6 share one discipline: **record, never fix.** A problem found during review or wrap-up goes into `notes/issue/` — fixing it is a separate, later task. Fixing in passing feels efficient and destroys the gate: the review no longer reviews what was built. + +## code ↔ book — the two half-brains + +``` + book/ (knowledge base + driving force) + ┌─────────────────────────────────────┐ + │ plans/ → drives implementation │ + │ guidelines/ → provides the baseline │ + │ learn/ → provides experience │ + │ issue/ → provides direction │ + │ decisions/ → provides context │ + └──────────────┬──────────────────────┘ + │ drives + ▼ + code/ + │ produces + ▼ + ┌─────────────────────────────────────┐ + │ summary/ ← feature reports │ + │ learn/ ← new experience │ + │ issue/ ← new problems found │ + │ changelogs/ ← change records │ + │ plans/ ← completion status │ + └─────────────────────────────────────┘ +``` + +## Interaction rules + +1. **Before coding** — read `guidelines/` for the baseline; search `notes/learn/` for related experience. +2. **While coding** — something new learned or tripped over? Write it to `notes/learn/` immediately; future sessions (human or agent) benefit. +3. **After coding** — sync the book: plan status, summary, new issues, changelog, index. +4. **Plans drive code** — `book/plans/` is the input to implementation. The agent reads the plan, builds in `code/`, writes back to `book/`. +5. **Issues feed code** — `notes/issue/` records problems that become the direction of later iterations. +6. **The book compounds** — every feature should leave the book more complete than it found it. The book is both the agent's context and the human's reference manual. +7. **Refresh the index** — after any book change, run `cd code && npm run book:index` before wrapping up. New files must carry a frontmatter `description`; missing ones fail the build. + +## Document routing + +| Output | Location | Audience | Style | +|--------|----------|----------|-------| +| Feature report | `book/notes/summary/` | Humans first | Report: background → what → why → outcome | +| Learned experience | `book/notes/learn/` | Humans + agents | Knowledge entry: searchable, tagged, applicability stated | +| Potential problem | `book/notes/issue/` | Humans + agents | Structured: problem + reproduction + suggested direction | +| Task tracking | `book/notes/task/` | Humans + agents | Checklist | +| Architecture decision | `book/docs/decisions/` | Humans first | ADR format | +| Implementation plan | `book/plans/` | Agents first | Structured, directly executable | +| Change log | `book/changelogs/` | Humans first | Short, dated entries | + +Every book document follows the plain-language standard in `guidelines/writing-style.md`. diff --git a/book/guidelines/writing-style.md b/book/guidelines/writing-style.md new file mode 100644 index 0000000..3f5b3df --- /dev/null +++ b/book/guidelines/writing-style.md @@ -0,0 +1,69 @@ +--- +description: Plain-language writing standard for every book document — fidelity contract first, then minimal style rules, intensity levels, and a read-back check +--- + +# Writing style — speak human + +Everything under `book/` (summary, changelog, learn, issue, task, plans, guidelines, docs) is written the same way: like a specific person speaking in a specific situation — not like a model performing writing. Professional is fine; templated is not. + +The complete rule set lives in the shuorenhua skill (source: [MrGeDiao/shuorenhua](https://github.com/MrGeDiao/shuorenhua)). If it is installed in your environment, prefer it; this file is the project default and the fallback when it isn't. + +## Fidelity contract — above any style + +No rewrite may add facts, drop core facts, or change who is responsible. The following never move: + +- Numbers, versions, dates, commands, API names, parameter names, field names, config keys, logs, error messages +- Code blocks, table data, directory structures +- System-behavior subjects, domain terms, ADR conclusions, responsibility attribution (who did what, in what state) +- When a quantitative claim is ambiguous, keep the original relationship and flag it for confirmation — never add counts, years, or measurements the source doesn't have +- Predicate strength must not drift: "improved performance" must not soften into "touches performance"; "saves time" must not grow into "saves time and money" + +## Minimal rules + +Work by pattern, not word-for-word substitution. Rotating synonyms to dodge repetition is itself model-speak — repeat a keyword when it is the right word. + +- Cut filler openers and meta-commentary: "it's worth noting that", "let me explain", "hope this helps" +- Cut empty-summary closers: "in summary", "at the end of the day", "essentially" +- In "not X, but Y" skeletons, usually delete the first half and just say Y +- Unsourced citations ("studies show"): flag the missing source — don't delete the claim, don't invent a source +- Unpack jargon into plain actions: "empower", "leverage", "synergy", "closed loop" +- Un-nominalize: "performed an optimization" → what changed, how much faster. "perform / implement / complete + gerund" is the tell +- Shorten translationese: fewer long attributive chains, fewer passive piles, less "through X, by way of Y, to achieve Z" +- Don't call the same thing by three different names in adjacent sentences +- Filler intensifiers ("important", "key", "critical", "core"): trim only when density is clearly too high, or replace with concrete information + +## Intensity levels + +Book documents use the `docs` setting (priorities: searchable, reproducible, stable terminology): + +| Level | When | Action | +|------|------|--------| +| minimal (default) | Text is mostly natural | Remove empty summaries, tighten tone | +| standard | Visible model-speak but sound structure | Unify register, fix performative tone, merge sentences or switch subjects where needed | +| aggressive | Almost never | Docs never go up to this level | + +No structural delete-and-merge: authoritative documents (specs, architecture, ADRs) get sentence-level rewrites and empty-sentence removal only — paragraphs are never reordered. + +## Positive target + +The finished text should carry concrete information, a subject and an action, a consistent register, and honesty about uncertainty. "Ready to send" is the finish line — don't keep polishing toward "sounds human" until it distorts. + +## Read-back (before committing) + +1. **Fidelity read-back**: did protected spans drift, did information get lost, did terminology distort, does anything read broken after the cuts? +2. **Residual-slop read-back** (only if the first pass still smells): leftover openers, leftover summaries, narrator voice, vague judgments, over-even rhythm — light corrections only. + +## Frontmatter convention + +Every book document starts with: + +```markdown +--- +description: one plain-language line about the content +--- +``` + +Good: `Module overview: responsibilities and boundaries of web, api, and worker` +Bad: `This document describes the overall architecture of the system` (that's the genre, not the content) + +The master index `book/README.md` is generated from these descriptions; `cd code && npm run book:index` warns and exits 1 when one is missing. diff --git a/book/notes/README.md b/book/notes/README.md new file mode 100644 index 0000000..e4ecf70 --- /dev/null +++ b/book/notes/README.md @@ -0,0 +1,82 @@ +--- +description: The four note types (learn, summary, task, issue), when each is written, the retrieval order, and the template for each +--- + +# Notes + +All running records of the project. Each subfolder has one purpose, and everything here is **recorded, never auto-fixed** — a recorded problem becomes a task; fixing it is separate work. + +`summary/`, `learn/`, and `issue/` archive under `YYYY-MM/`. The month is a stable, low-maintenance physical grouping; feature relationships live in filenames, frontmatter, and links in the text — never in deeper directory nesting. + +| Folder | Use | Written when | +|--------|-----|--------------| +| `learn/` | Experience and lessons | During coding, and at Phase 6 wrap-up | +| `summary/` | Feature and version reports | After each feature completes | +| `task/` | Task tracking and breakdowns | When a requirement arrives | +| `issue/` | Potential problems (recorded, never fixed) | Any phase that finds one | + +## Retrieval order + +1. Read `book/README.md` first; locate documents by feature name, keyword, or summary. +2. Then read the specific type and month. +3. Before coding, search `learn` first; at wrap-up, write the feature's outcome, experience, and open problems to `summary`, `learn`, and `issue` respectively. + +Obsidian can open `book/` directly as a vault; existing links are plain relative Markdown. + +## Templates + +### summary — a report a human can read without opening the code + +```markdown +--- +description: +--- +# — summary + +- **Background**: why this feature exists +- **What was done**: the changes, in plain words +- **Why these choices**: the decisions and their reasons +- **Outcome**: what works now, measured where possible +- **Follow-ups**: what's deliberately left open, linking issues +``` + +### learn — a searchable knowledge entry, for humans and agents + +```markdown +--- +description: +tags: [, , ] +--- +# + +- **Scenario**: when this entry applies +- **Why**: the mechanism behind it +- **How to apply**: what to do differently next time +``` + +Tags drive retrieval — write the words you'd search for later, including symptom words ("timeout", "drift", "silent-fail"). + +### issue — a recorded problem, never fixed in passing + +```markdown +--- +description: +--- +# + +- **Observed**: what was seen, where, when +- **Reproduction**: the steps or conditions that bring it back +- **Suggested direction**: what a fix would probably touch — recorded only +``` + +### task — a checklist that tracks a piece of work + +```markdown +--- +description: +--- +# + +- [ ] +- [x] +``` diff --git a/book/plans/2026-09-13-bocode-foundation-design.md b/book/plans/2026-09-13-bocode-foundation-design.md deleted file mode 100644 index fc88d5a..0000000 --- a/book/plans/2026-09-13-bocode-foundation-design.md +++ /dev/null @@ -1,157 +0,0 @@ ---- -description: BoCode 基础设计:自举式 code+book 双向驱动工作流模板仓库的完整蓝图与已确认决策 ---- - -# BoCode 基础设计(Design Spec) - -> 状态:待用户审阅 · 2026-09-13 · 本文档是 BoCode 仓库的第一篇 plan,仓库从这一刻起自举。 - -## 1. 背景与目标 - -StarBell 项目验证了一套 code/book 双向驱动的工作方法:`code/` 与 `book/` 双半脑、六阶段关卡、四类 notes、frontmatter 索引契约、说人话书写规范。本设计把这套方法从 StarBell 抽象成**通用开源模板仓库 BoCode**(book + code),任何人 clone 即可给自己的项目装上这套工作流。 - -**成功标准:** - -1. 新用户通过 GitHub "Use this template" 或 clone,运行一条命令完成项目化重置,5 分钟内得到一个可用的 BoCode 项目 -2. AI agent(任何支持 SKILL.md / AGENTS.md 约定的工具)读入口文件后能正确遵守双向驱动纪律 -3. README(英文主 + 中文版)把设计哲学讲透,仓库本身就是工作流的活示范 -4. 零第三方运行时依赖:不需要 bun、不需要 npm install、node 直跑全部脚本 - -## 2. 已确认决策(用户拍板) - -| 决策点 | 结论 | -|--------|------| -| 消费形态 | 模板仓库(clone / Use this template 即用) | -| 仓库架构 | 方案 A 自举模板:仓库自身就是一个 BoCode 项目,自己的记录走自己的流程 | -| skills 来源 | 全部自研(superpowers 套件仅作参考,不收录不改编其文本) | -| shuorenhua | 只引用不内置:writing-style 保留规则文本作兜底,skill 本体给外部安装指引 | -| skill 数量 | 3 个:bocode(入口)、feature-flow(六阶段)、book-writeback(回写) | -| README 语言 | 英文主文档 + 中文版 README.zh-CN.md,内容对等 | -| guidelines 语言 | 模板表面(guidelines、AGENTS.md、skills)全英文;BoCode 自身活记录(summary/learn/changelog/plans)中文 | -| 索引工具 | gen-book-index 从 .ts/bun 改为 .mjs,node 与 bun 通吃,零依赖 | -| agent 入口 | AGENTS.md 承载内容,CLAUDE.md 只写一行指针 | -| 许可证 | MIT,版权人 Focus(2026) | - -## 3. 仓库结构 - -``` -BoCode/ -├── README.md # 英文主文档:设计哲学九章 + Quick Start + 目录导览 -├── README.zh-CN.md # 中文版,内容对等 -├── LICENSE # MIT -├── AGENTS.md # agent 入口:结构、双向驱动规则、文档约定、关键约束 -├── CLAUDE.md # 一行指针 → AGENTS.md -├── .gitignore # 忽略 .DS_Store、node_modules 等 -├── .github/ -│ └── workflows/git-policy.yml # CI:Clean Commit 校验 + 分支流向检查(dev→main 只允许 merge commit) -├── scripts/ -│ ├── check-commit-message.mjs # Clean Commit 标题校验,零依赖,node 直跑 -│ └── init-project.sh # 一键重置:改项目名、清空 BoCode 自身活记录、刷新索引 -├── skills/ -│ ├── README.md # 各平台安装指引(ZCode / Claude Code / 通用 SKILL.md 兼容工具) -│ ├── bocode/SKILL.md # 入口 skill:结构认知、双向驱动纪律、索引刷新时机 -│ ├── feature-flow/SKILL.md # Step 0 需求 Brief + 六阶段硬关卡(Phase 4 内嵌 TDD) -│ └── book-writeback/SKILL.md # summary/learn/issue 回写向导:模板 + 质量关卡 -├── code/ -│ ├── tools/gen-book-index.mjs # 扫描 book/ 生成总索引;缺 description 警告并退出 1 -│ └── package.json # 仅 book:index 一个脚本,零依赖 -└── book/ - ├── README.md # 总索引(脚本生成,勿手改) - ├── guidelines/ - │ ├── README.md # guidelines 地图 - │ ├── workflow.md # 六阶段关卡 + 双向驱动七条交互规则 + 文档分流表 - │ ├── writing-style.md # 说人话:保真合同 + 最小规则 + 档位 + 回读清单(含 shuorenhua 引用) - │ ├── git-workflow.md # Clean Commit + Clean Flow(通用版,去 StarBell 细节) - │ ├── review-checklist.md # Phase 5 结构化 review 清单 - │ ├── architecture.md # 模板:指导项目定义自己的长期边界(含示例写法) - │ └── coding-style.md # 模板:技术栈相关的编码基线占位 - ├── docs/ - │ ├── README.md - │ ├── architecture/README.md # 实现快照占位 - │ ├── api/README.md # API 文档占位 - │ └── decisions/ - │ ├── README.md # ADR 写法说明 - │ └── ADR-001-adopt-bocode.md # 示范 ADR:为什么本项目采用 BoCode - ├── notes/ - │ ├── README.md # 四类 notes 分工 + 写入时机 + 检索顺序 + 内嵌模板 - │ ├── learn/2026-09/ # 经验条目(BoCode 自身记录,init-project.sh 清理) - │ ├── summary/2026-09/ # 功能报告(同上) - │ ├── task/README.md - │ └── issue/2026-09/README.md # 只记不修(同上) - ├── plans/ # 本设计文档所在;README 说明 plan 格式 - └── changelogs/ - └── 2026-09/README.md # 变更日志格式说明 -``` - -## 4. 组件设计 - -### 4.1 README.md(英文)与 README.zh-CN.md - -九章哲学骨架(两部分已确认): - -1. **The problem** — agent 无状态、文档腐烂、人失去控制 -2. **Two half-brains** — code 回答"怎么运作",book 回答"为什么这样运作";可执行的真相 vs 可导航的真相 -3. **The flywheel** — book→code(plans/guidelines/learn/issue/decisions),code→book(summary/learn/issue/changelog/索引刷新);复利而非重启 -4. **Gates, not brakes** — Step 0 需求 Brief("不影响清单"必填);Phase 2 人类确认;Phase 5/6 只记录不修复 -5. **Write for the reader** — summary 报告体 vs learn 知识条目 -6. **The index contract** — 一行 description + 零依赖脚本 + 缺失即失败;Obsidian 兼容 -7. **Speak human** — 反模板腔、事实锁死(引用 shuorenhua) -8. **Clean git flow** — emoji 提交格式、dev 集成分支、main 只收 merge commit -9. **This repo runs on BoCode** — 自举示范,活记录在 book/ 里 - -之后:Quick Start(Use this template → `bash scripts/init-project.sh` → 装 skills → 指向 AGENTS.md)、目录导览、FAQ(含"我已经有一个项目怎么引入")、License。 - -### 4.2 AGENTS.md - -从 StarBell CLAUDE.md 通用化:项目概述占位、空间结构、双向驱动规则、文档分流表、code↔book 交互五条、关键约束(六阶段不跳步、Phase 2 确认、只记不修、索引必刷新)。去掉 StarBell 特有内容(六条架构边界、codegen 命令)。 - -### 4.3 skills 套件(全自研,纯 SKILL.md) - -| skill | 触发场景 | 核心内容 | 来源与改写 | -|-------|----------|----------|------------| -| `bocode` | 会话开始 / 用户提到 book、索引、文档去向 | 结构地图;编码前查 guidelines+learn、收尾必回写+刷索引;frontmatter description 纪律 | 新写 | -| `feature-flow` | 用户要实现/修改功能且请求稀疏 | Step 0 Brief(背景/作用域/需求,"不影响"必填 + 推荐清单);六阶段硬关卡;Phase 4 内嵌 TDD;Phase 6 回写指向 book-writeback | structured-feature-implementation 通用化:去 doc-sync-router/Mango 分支,回写目标固定为 book/ | -| `book-writeback` | 功能收尾 / 用户要写 summary/learn/issue | 三类文档模板与质量关卡(summary 报告体、learn 带 tags 可检索、issue 只记不修);写完刷索引 | 新写,吸收 StarBell notes 模板 | - -### 4.4 工具链 - -- **gen-book-index.mjs**:逻辑照搬 StarBell 版(walk + frontmatter description 解析 + 按目录分组 + 警告退出 1),ESM plain Node,标题里的项目名从 `code/package.json` 的 `name` 字段读,读不到用 "book" -- **check-commit-message.mjs**:StarBell 版即零依赖自研实现,直接通用化收编 -- **init-project.sh**:交互式问项目名 → 替换 AGENTS.md 与 `code/package.json` 的占位 → 删除 book/notes/{learn,summary,issue,task} 与 book/changelogs 下的全部 YYYY-MM 月度目录(BoCode 自身记录)→ 重跑 book:index → 打印 skills 安装提示 -- **git-policy.yml**:push/PR 校验提交标题格式与分支流向;文档写明 GitHub 分支保护建议(main:require PR + merge commit) - -### 4.5 book/ 模板内容 - -guidelines 五篇核心(workflow/writing-style/git-workflow/review-checklist)为**通用成品**(英文),architecture.md 与 coding-style.md 为**带示例写法的模板**。notes 四类目录的 README.md 内嵌该类文档的写作模板(不单独成篇,避免索引混入假文件),保证 `book:index` 首跑即零警告。 - -### 4.6 自举策略 - -- BoCode 自身的开发记录(本设计文档、后续 changelog、learn、summary)用中文写进 book/,作为活教材 -- init-project.sh 负责把这部分"作者的记录"从用户项目里清掉,同时保留模板示例 -- 仓库 git 历史从 main 上的首个 commit(本设计文档)开始,随后建 dev 分支,日常开发走 dev,遵循 BoCode 自己的 git-workflow - -## 5. 明确不做(YAGNI) - -- 不做 npm 脚手架 CLI -- 不做多语言 guidelines(英文模板 + 中文 README 即止) -- 不内置任何第三方 skill(shuorenhua、superpowers 均为外部引用) -- 不做文档站 / 不做 Obsidian 插件 -- v1 不做 CONTRIBUTING.md / SECURITY.md(开源后按需加) - -## 6. 风险与对策 - -| 风险 | 对策 | -|------|------| -| README 哲学写成抽象口号 | 每个哲学点必须落到一条可执行的规则或一个目录/脚本上;宁短勿空 | -| 模板示例与 BoCode 活记录混淆 | init-project.sh 明确清理范围;示例文件名统一 template 前缀或集中标注 | -| 英文文档表达打折 | 英文定稿前用说人话标准回读;术语表与中文版一一对应 | -| skills 与 guidelines 内容重复漂移 | 原则:guidelines 管"是什么/为什么"(人类读),skills 管"何时做/怎么做"(agent 执行);引用不复制 | - -## 7. 验收清单 - -- [ ] `bash scripts/init-project.sh` 在干净 clone 上跑通,产出项目无 BoCode 自身记录残留 -- [ ] `node code/tools/gen-book-index.mjs` 首跑零警告退出 0 -- [ ] `node scripts/check-commit-message.mjs ""` 对正反例行为正确 -- [ ] 3 个 SKILL.md 均带 frontmatter name/description,触发条件互斥清晰 -- [ ] README.md 与 README.zh-CN.md 章节一一对应 -- [ ] 仓库全部 commit 符合 Clean Commit 格式 diff --git a/book/plans/README.md b/book/plans/README.md new file mode 100644 index 0000000..00ecffe --- /dev/null +++ b/book/plans/README.md @@ -0,0 +1,40 @@ +--- +description: Plans directory usage — implementation plans land here after Phase 2 approval, with naming and the plan template +--- + +# Plans + +Implementation plans live here. Each feature's detailed plan lands in this folder once its Phase 2 design is approved — the plan is the construction blueprint the agent builds from. + +## Naming + +`YYYY-MM-DD-.md` + +## Template + +```markdown +--- +description: +status: draft | approved | in_progress | completed +--- + +# — plan + +## Requirements brief + + +## Impact range + + +## Design + + +## Build order +1. +2. ... + +## Test plan + +``` + +A plan is executable as written: each step small enough to verify on its own. When the build finishes, flip `status` to `completed` — the plan then doubles as the record of what was intended, next to the summary of what happened. diff --git a/code/package.json b/code/package.json new file mode 100644 index 0000000..5f8c191 --- /dev/null +++ b/code/package.json @@ -0,0 +1,10 @@ +{ + "name": "bocode", + "version": "0.1.0", + "private": true, + "type": "module", + "description": "Project source tree. The only script here is the book index generator — this file has zero dependencies by design.", + "scripts": { + "book:index": "node tools/gen-book-index.mjs" + } +} diff --git a/code/tools/gen-book-index.mjs b/code/tools/gen-book-index.mjs new file mode 100755 index 0000000..2d1dd4b --- /dev/null +++ b/code/tools/gen-book-index.mjs @@ -0,0 +1,141 @@ +#!/usr/bin/env node +/** + * Scans every Markdown file under book/ and regenerates book/README.md, + * the master index of the whole book. + * + * Usage: cd code && node tools/gen-book-index.mjs + * (or: npm run book:index) + * + * Convention: every document starts with frontmatter whose `description` + * is a one-line, plain-language summary of the content. Files missing it + * are listed on stderr and the script exits 1 — zero warnings is the + * only passing state. Zero dependencies; runs on plain Node (and bun). + */ +import { readdirSync, readFileSync, writeFileSync } from "node:fs"; +import { join, dirname, relative } from "node:path"; +import { fileURLToPath } from "node:url"; + +const TOOLS_DIR = dirname(fileURLToPath(import.meta.url)); +const CODE_ROOT = join(TOOLS_DIR, ".."); +const BOOK_ROOT = join(CODE_ROOT, "..", "book"); +const OUTPUT = join(BOOK_ROOT, "README.md"); + +function projectName() { + try { + const pkg = JSON.parse(readFileSync(join(CODE_ROOT, "package.json"), "utf8")); + if (pkg.name) return pkg.name; + } catch { + // no package.json or no name — fall through to the default + } + return "this project"; +} + +const NAME = projectName(); + +const DIR_PURPOSE = { + changelogs: "Change log: what landed and when", + docs: "Technical docs: architecture, API, decisions", + "docs/api": "API design and interface docs", + "docs/architecture": "Architecture snapshots: modules, data flow", + "docs/decisions": "Architecture decision records (ADR)", + guidelines: "Development rules every contributor (including AI) must follow", + notes: "Running records: learn / summary / task / issue", + "notes/learn": "Experience and lessons; read before coding", + "notes/summary": "Feature reports, written for humans", + "notes/task": "Task tracking and breakdowns", + "notes/issue": "Potential problems — recorded, never auto-fixed", + plans: "Implementation plans: the construction blueprint agents build from", +}; + +function purposeForDir(dir) { + if (DIR_PURPOSE[dir]) return DIR_PURPOSE[dir]; + const parent = Object.keys(DIR_PURPOSE) + .filter((key) => key && dir.startsWith(`${key}/`)) + .sort((a, b) => b.length - a.length)[0]; + return parent ? `Archived under ${parent}/, grouped by month` : ""; +} + +function walkMd(dir) { + const out = []; + for (const entry of readdirSync(dir, { withFileTypes: true })) { + if (entry.name.startsWith(".")) continue; + const full = join(dir, entry.name); + if (entry.isDirectory()) out.push(...walkMd(full)); + else if (entry.name.endsWith(".md")) out.push(full); + } + return out; +} + +function parseDescription(abs) { + const text = readFileSync(abs, "utf8"); + if (!text.startsWith("---")) return null; + const lines = text.split("\n"); + for (let i = 1; i < lines.length; i++) { + if (lines[i].trim() === "---") return null; // frontmatter ended, not found + const m = lines[i].match(/^description:\s*(.+)$/); + if (m) return m[1].trim(); + } + return null; +} + +function link(rel) { + return /[\s()]/.test(rel) ? `<${rel}>` : rel; +} + +const files = walkMd(BOOK_ROOT) + .filter((f) => f !== OUTPUT) + .sort(); + +const warnings = []; +const byDir = new Map(); + +for (const abs of files) { + const rel = relative(BOOK_ROOT, abs); + const dir = dirname(rel) === "." ? "" : dirname(rel); + const desc = parseDescription(abs); + if (!desc) warnings.push(rel); + if (!byDir.has(dir)) byDir.set(dir, []); + byDir.get(dir).push({ name: rel.split("/").pop(), rel, desc: desc ?? "(missing description)" }); +} + +const dirKeys = [...byDir.keys()].sort((a, b) => a.localeCompare(b, "en")); + +let out = ""; +out += "---\n"; +out += "description: Master index of the book — the map of every document. Regenerate with `cd code && npm run book:index` after any book change\n"; +out += "---\n\n"; +out += `# book — ${NAME} master index\n\n`; +out += "> Generated by a script — do not edit by hand. After any book change run: `cd code && npm run book:index`.\n"; +out += "> Every new file must carry a frontmatter `description` (one plain-language line about the content, not the genre); the build warns and exits 1 otherwise.\n\n"; +out += "## How to use this book\n\n"; +out += "- **AI agents**: read this file first for the full map, then follow links to what you need. Before writing any book document, read `guidelines/writing-style.md`.\n"; +out += "- **Humans**: browse by the directory table below. Rules live in `guidelines/`, blueprints in `plans/`, experience in `notes/learn/`, architecture in `docs/architecture/`, decisions in `docs/decisions/`.\n"; +out += "- **By time**: `changelogs/` and `notes/{summary,learn,issue}/` archive under `YYYY-MM/`; the month is a physical grouping only — do not nest deeper by feature.\n"; +out += "- **By feature**: search this index for a feature name, keyword, or frontmatter summary; `notes/learn/` entries are also searchable by their `tags`.\n"; +out += "- **Obsidian**: open `book/` directly as a vault. Links are plain relative Markdown; if you move files, rerun the index.\n\n"; +out += "## Directory map\n\n"; +out += "| Directory | Purpose |\n|------|------|\n"; +for (const key of dirKeys) { + const label = key === "" ? "(root)" : key + "/"; + out += `| \`${label}\` | ${purposeForDir(key)} |\n`; +} +out += "\n## All files\n\n"; +for (const key of dirKeys) { + const label = key === "" ? "root" : key + "/"; + out += `### ${label}\n\n`; + for (const f of byDir.get(key)) { + out += `- [${f.name}](${link(f.rel)}) — ${f.desc}\n`; + } + out += "\n"; +} +out += `\n`; + +writeFileSync(OUTPUT, out); + +if (warnings.length > 0) { + console.error(`Files missing frontmatter description (${warnings.length}):`); + for (const w of warnings) console.error(` - ${w}`); + console.error(`Index written to ${OUTPUT} (${files.length} documents), but the files above lack a summary. Fix them and rerun.`); + process.exit(1); +} +console.log(`Index written to ${OUTPUT} — ${files.length} documents, zero warnings.`); diff --git a/scripts/check-commit-message.mjs b/scripts/check-commit-message.mjs new file mode 100755 index 0000000..f9f9377 --- /dev/null +++ b/scripts/check-commit-message.mjs @@ -0,0 +1,80 @@ +#!/usr/bin/env node +/** + * Validates commit subjects against the Clean Commit format + * (spec: https://github.com/wgtechlabs/clean-commit — which ships as + * documentation only; this script is the enforcement). + * See book/guidelines/git-workflow.md for the full standard as applied here. + * + * Usage: + * node scripts/check-commit-message.mjs "" # one subject + * ... | node scripts/check-commit-message.mjs # subjects on stdin + * Exit 0 = all valid; exit 1 = any invalid. + */ +const allowedTypes = new Map([ + ["📦", "new"], + ["🔧", "update"], + ["🗑️", "remove"], + ["🔒", "security"], + ["⚙️", "setup"], + ["☕", "chore"], + ["🧪", "test"], + ["📖", "docs"], + ["🚀", "release"], +]); + +const breakingTypes = new Set(["new", "update", "remove", "security"]); +const subjectPattern = /^(?📦|🔧|🗑️|🔒|⚙️|☕|🧪|📖|🚀) (?[a-z]+)(?!)?(?: \((?[a-z0-9][a-z0-9-]*)\))?: (?.+)$/u; + +function validateSubject(subject) { + const match = subjectPattern.exec(subject); + if (!match?.groups) { + return "must match ' : ' (scope and ! are optional)"; + } + + const { emoji, type, breaking, description } = match.groups; + if (allowedTypes.get(emoji) !== type) { + return `must use the matching Clean Commit emoji for type '${type}'`; + } + if (breaking && !breakingTypes.has(type)) { + return `type '${type}' cannot use the breaking-change marker !`; + } + if (description.endsWith(".")) { + return "description must not end with a period"; + } + if (Array.from(description).length >= 72) { + return "description must be under 72 characters"; + } + + return null; +} + +const argumentSubjects = process.argv.slice(2); +const input = argumentSubjects.length > 0 + ? argumentSubjects.join("\n") + : await new Promise((resolve, reject) => { + let data = ""; + process.stdin.setEncoding("utf8"); + process.stdin.on("data", (chunk) => { data += chunk; }); + process.stdin.on("end", () => resolve(data)); + process.stdin.on("error", reject); + }); + +const subjects = input.split(/\r?\n/).filter(Boolean); +if (subjects.length === 0) { + console.error("No commit subject supplied."); + process.exit(1); +} + +const invalidSubjects = subjects + .map((subject) => ({ subject, error: validateSubject(subject) })) + .filter(({ error }) => error); + +if (invalidSubjects.length > 0) { + for (const { subject, error } of invalidSubjects) { + console.error(`Invalid commit subject: ${subject}\n ${error}`); + } + console.error("See book/guidelines/git-workflow.md for valid examples."); + process.exit(1); +} + +console.log(`Validated ${subjects.length} Clean Commit subject${subjects.length === 1 ? "" : "s"}.`); diff --git a/scripts/init-project.sh b/scripts/init-project.sh new file mode 100755 index 0000000..ca40b98 --- /dev/null +++ b/scripts/init-project.sh @@ -0,0 +1,122 @@ +#!/usr/bin/env bash +# +# init-project.sh — turn a fresh BoCode clone into YOUR project. +# +# bash scripts/init-project.sh "" +# +# What it does: +# 1. Sets the project name in code/package.json (the index title reads it) +# 2. Fills the project overview paragraph in AGENTS.md +# 3. Writes a fresh minimal README.md (the BoCode philosophy README is +# replaced — find it in the BoCode repository itself) +# 4. Clears any dated living records (defensive: the template ships clean; +# this covers clones that carry records, e.g. from the BoCode origin) +# 5. Regenerates the book index +# 6. Optionally resets git history for a clean start +# +# Requires: bash, node (any version from the last few years). + +set -euo pipefail + +NAME="${1:-}" +DESC="${2:-}" + +if [ -z "$NAME" ] || [ -z "$DESC" ]; then + if [ ! -t 0 ]; then + echo "Usage: bash scripts/init-project.sh \"\"" >&2 + exit 1 + fi + while [ -z "$NAME" ]; do + printf "Project name (lowercase, no spaces): " + read -r NAME + done + while [ -z "$DESC" ]; do + printf "One-line description: " + read -r DESC + done +fi + +echo "Initializing ${NAME}: ${DESC}" + +# 1. Project name in code/package.json +node -e ' + const fs = require("fs"); + const file = "code/package.json"; + const pkg = JSON.parse(fs.readFileSync(file, "utf8")); + pkg.name = process.argv[1]; + fs.writeFileSync(file, JSON.stringify(pkg, null, 2) + "\n"); +' "$NAME" + +# 2. Project overview in AGENTS.md +node -e ' + const fs = require("fs"); + const file = "AGENTS.md"; + let text = fs.readFileSync(file, "utf8"); + text = text.replace( + //, + process.argv[1] + " — " + process.argv[2] + ); + fs.writeFileSync(file, text); +' "$NAME" "$DESC" + +# 3. Fresh README.md +cat > README.md </" +echo " 2. Point your AI agent at AGENTS.md (most tools pick it up automatically)." +echo " 3. Fill in book/guidelines/architecture.md and coding-style.md for your project." +echo " 4. Set your remote:" +echo " git remote add origin " diff --git a/skills/README.md b/skills/README.md new file mode 100644 index 0000000..30d4e2d --- /dev/null +++ b/skills/README.md @@ -0,0 +1,25 @@ +# Skills + +Three self-contained skills implement the BoCode workflow for AI agents. Each is a single `SKILL.md` in the standard format (frontmatter with `name` and `description`, then the body) — no code, no dependencies. + +| Skill | Does | Triggers | +|-------|------|----------| +| `bocode` | The structure map and the session discipline — read before coding, write back after | Session start in a BoCode repo; questions about where documents go or how the index works | +| `feature-flow` | Step-0 requirements brief + six hard-gated phases for feature development | "Implement / add / support / change X" with a sparse request | +| `book-writeback` | Templates and quality gates for writing back to the book | Feature wrap-up; "write a summary / learn entry / issue" | + +Division of labor: **skills say when and how** (executable behavior for the agent); **`book/guidelines/` says what and why** (reference for humans). They reference each other and never duplicate rules. + +## Installation + +Copy the three skill directories into your agent's skills folder: + +- **ZCode**: `~/.zcode/skills/` (user-wide) or `/.zcode/skills/` (per project) +- **Claude Code**: `~/.claude/skills/` or `/.claude/skills/` +- **Other SKILL.md-compatible agents**: the skills directory your tool documents + +```bash +cp -r skills/bocode skills/feature-flow skills/book-writeback / +``` + +Optional, recommended for Chinese-writing teams: install [shuorenhua](https://github.com/MrGeDiao/shuorenhua) — the full plain-language ruleset that `book/guidelines/writing-style.md` distills and can act as a fallback for. diff --git a/skills/bocode/SKILL.md b/skills/bocode/SKILL.md new file mode 100644 index 0000000..f1be8a7 --- /dev/null +++ b/skills/bocode/SKILL.md @@ -0,0 +1,47 @@ +--- +name: bocode +description: Entry skill for repositories running the BoCode workflow (code/ + book/ layout). Use when a session starts in such a repo, or when deciding where a document goes, how the book index works, or what the code↔book rules require. Teaches the structure map and the discipline; feature development itself is handled by feature-flow. +--- + +# bocode + +This repository runs BoCode: `code/` is the source, `book/` is the documentation stream and knowledge base. They drive each other in both directions. Your job in every session: keep the flywheel spinning — read from the book before coding, write back to the book after. + +## The map + +``` +book/ +├── README.md master index (script-generated — read this first) +├── guidelines/ the rules: workflow, writing style, git, review +├── docs/ architecture snapshots, API contracts, ADRs +├── notes/ +│ ├── learn/ experience entries — search before coding +│ ├── summary/ feature reports, written for humans +│ ├── task/ task tracking +│ └── issue/ recorded problems — never fixed in passing +├── plans/ implementation blueprints — the input to coding +└── changelogs/ dated change records +``` + +## Session discipline + +**Starting work:** +1. Read `book/README.md` for the full map. +2. Read `AGENTS.md` for the repository's rules and hard constraints. +3. Before coding anything: check `book/guidelines/` for the baseline, and search `book/notes/learn/` for related experience. + +**While coding:** a new lesson or pitfall goes straight into the current month's `notes/learn/YYYY-MM/` — don't wait for wrap-up to remember it. + +**Finishing work:** sync the book — plan status, summary, new issues, changelog entry — then regenerate the index. Details of what to write where are in the **book-writeback** skill. + +## The two contracts + +1. **Index contract**: every new book document starts with frontmatter `description` — one plain-language line about the *content* (not the genre). After any book change, run `cd code && npm run book:index`; the build fails on a missing description, and that's the point. +2. **Record-only contract**: problems found during review or wrap-up are recorded to `notes/issue/`, never fixed in passing. A recorded problem becomes a task; fixing is separate work. + +## What not to do + +- Don't edit `book/README.md` by hand — it's generated. +- Don't archive by feature: `summary/`, `learn/`, `issue/`, `changelogs/` group by `YYYY-MM/` only; features are found through the index, frontmatter, and links. +- Don't write book documents in template-speak — follow `book/guidelines/writing-style.md` (plain language, facts locked). +- Don't treat a plan in `book/plans/` as a suggestion: it is the input to implementation, and deviations go back through design, not silently into code. diff --git a/skills/book-writeback/SKILL.md b/skills/book-writeback/SKILL.md new file mode 100644 index 0000000..fed035a --- /dev/null +++ b/skills/book-writeback/SKILL.md @@ -0,0 +1,91 @@ +--- +name: book-writeback +description: Guides writing back to the book after work completes — summary reports, learn entries, issue records, changelog entries — with templates and quality gates, then regenerating the index. Use at feature wrap-up, after small fixes that taught something, or when the user asks to write a summary, learn entry, issue, or changelog. +--- + +# book-writeback + +Development that doesn't write back to the book loses its experience. This skill covers what to write, where, and the quality bar — for the BoCode layout (`book/` with `notes/{summary,learn,issue}/`, `changelogs/`, `plans/`). + +## What to write, when + +| Situation | Write | +|-----------|-------| +| A feature completed | summary + learn + changelog, plan status → completed | +| Something was learned or tripped over (any phase) | learn — immediately, not at wrap-up | +| A problem was noticed but deliberately not fixed | issue | +| A small fix with nothing to teach | changelog only | + +## Templates and quality gates + +### summary → `book/notes/summary/YYYY-MM/YYYY-MM-DD-.md` + +A report a human reads without opening the code. + +```markdown +--- +description: +--- +# — summary + +- **Background**: why this feature exists +- **What was done**: the changes, in plain words +- **Why these choices**: the decisions and their reasons +- **Outcome**: what works now, measured where possible +- **Follow-ups**: what's deliberately left open, linking issues +``` + +**Gate:** a reader who has never seen the code understands what changed and why. Numbers over adjectives; state what wasn't done as plainly as what was. + +### learn → `book/notes/learn/YYYY-MM/YYYY-MM-DD-.md` + +A searchable knowledge entry for humans and agents. + +```markdown +--- +description: +tags: [, , ] +--- +# + +- **Scenario**: when this entry applies +- **Why**: the mechanism behind it +- **How to apply**: what to do differently next time +``` + +**Gate:** the title alone answers the question. Tags include the words you'd search for later — including symptom words ("timeout", "drift", "silent-fail"). + +### issue → `book/notes/issue/YYYY-MM/YYYY-MM-DD-.md` + +A recorded problem. **Never fix it as part of recording.** + +```markdown +--- +description: +--- +# + +- **Observed**: what was seen, where, when +- **Reproduction**: the steps or conditions that bring it back +- **Suggested direction**: what a fix would probably touch — recorded only +``` + +**Gate:** someone else could confirm the problem from the record alone. + +### changelog → `book/changelogs/YYYY-MM/YYYY-MM-DD-.md` + +Short, dated, factual: what landed. One entry per change; link the summary when one exists. + +### plan status → `book/plans/YYYY-MM-DD-.md` + +Flip `status:` to `completed` (or `in_progress`) so the blueprint doubles as the record of intent. + +## After every writeback + +1. Every new file carries frontmatter `description`. +2. Regenerate the index: `cd code && npm run book:index` — zero warnings or it didn't happen. +3. Writing follows `book/guidelines/writing-style.md`: plain language, fidelity contract above style (numbers, commands, names, and responsibility attribution never move). + +## Quality bar + +A writeback that fails the fidelity contract (invented facts, softened predicates, shifted blame) is worse than no writeback — future sessions build on it. If unsure of a number or a cause, write the uncertainty into the entry. diff --git a/skills/feature-flow/SKILL.md b/skills/feature-flow/SKILL.md new file mode 100644 index 0000000..cad160c --- /dev/null +++ b/skills/feature-flow/SKILL.md @@ -0,0 +1,93 @@ +--- +name: feature-flow +description: Splits a feature into a Step-0 structured requirements brief plus six hard-gated phases (analysis, design, implementation, testing, review, wrap-up). Use when the user asks to implement/add/support/change a feature and the request is sparse — missing background, scope, or detailed logic. Do not use for one-line fixes, typos, pure questions, or tasks whose scope the user has already fully specified. +--- + +# feature-flow + +## Goal + +Split a feature into **brief → six phases**, each phase a hard gate. Fill a structured requirements brief before touching code, and proactively raise the design axes the user didn't mention. Then move phase by phase — no skipping. + +**Core principle:** a request that says *what* but not *why / scope / boundaries* is not ready for code. Fill the gaps first; then surface the axes the user didn't know were missing. + +## Step 0: the requirements brief (REQUIRED — before any code) + +Render the brief below and fill every slot. For empty slots you have two duties: + +**A. Missing → ask.** Real gaps go to the user as questions. Don't guess background or scope — they change what gets built. Ask once, completely. + +**B. Sufficient → recommend.** Once enough is known to start, don't stop — raise the design axes the user didn't mention (permissions, notifications, idempotency, caching, transactions, boundaries, regression, generated-artifact sync…). Mark each as `[recommended — confirm or reject]`. This is the core increment of this skill: filling gaps the user didn't know were there. + +### Brief template + +``` +## Background + + +## Scope +- Affects: +- Does NOT affect: +- Boundaries: + +## Requirement + +``` + +> The **exclusions** slot is REQUIRED. An empty "does not affect" list is the number-one cause of out-of-scope changes in Phase 3. + +**Axes checklist (review every time, raise the relevant ones):** permissions/auth · notifications · idempotency · cache invalidation · transaction boundaries · concurrency/races · rate limits · data migration · regression impact · generated-artifact sync (codegen / schema / proto — refresh per the project's build scripts after changes). + +--- + +## The six phases (each a hard gate; an unfinished gate blocks the next) + +### Phase 1: Analysis + +Understand the requirement → find the relevant code → trace the call chain → map the impact → flag risks. **No code changes.** + +**Output:** impact map + risk list. + +### Phase 2: Design + +**Output:** data flow, sequence diagram (optional), file change list, new interfaces, permission design, notification design, test points. + +**Stop and wait for approval.** Do not enter Phase 3 until the user explicitly approves. (A kickoff message that clearly orders implementation and sets the technical context counts as approval — record that basis in the plan.) + +> **Permissions + notifications** are the two slots agents forget most. Even when the answer is "not needed this time", state it explicitly. + +**On approval:** write the plan into `book/plans/YYYY-MM-DD-.md` (template in that directory's README). The plan is the construction blueprint — this file, not memory, is what Phase 3 builds from. + +### Phase 3: Implementation + +Strictly per the approved design. **No changes outside scope, no refactors, no new abstractions.** Match the existing code's style. + +### Phase 4: Testing (test-first) + +Write a failing test → write the minimal implementation that passes → refactor with tests green. + +**Coverage (all required):** normal path · permission checks · boundaries (input ranges / empty / extremes) · error paths · regression (existing behavior intact). + +**Gate:** all relevant tests pass, and no assertion was weakened to make them pass. + +### Phase 5: Code review + +Structured review of the diff, checking: duplicated code · permission holes · races · transaction issues · missed notifications · missed boundaries · added complexity · out-of-scope changes. + +**Record, never fix.** Fixing in passing breaks the gate — findings go to the list and wait for a separate round. Follow the project's review checklist if one exists (`book/guidelines/review-checklist.md`). + +### Phase 6: Wrap-up + +Write back to the book: plan status, summary, learn entries, new issues, changelog — then regenerate the index. The **book-writeback** skill covers templates and quality gates. + +**Invariant:** problems found here are **recorded, never fixed**. + +--- + +## Constraints + +- Step 0 before any code, every brief slot filled +- No skipping phases; every REQUIRED gate met before the next +- Phase 2 design and Phase 3 scope boundaries advance only with explicit user approval +- Phase 5 records without fixing; Phase 6 records without fixing +- The writeback target is this project's `book/` — never bypass the project's own document conventions