Files
Leo 10f25e53e3 feat: tasks.md ⇄ GitHub Project 單向投影 optional 模組(issue #16)+ bump 1.13.0
裝了 SDD 的專案可把 docs/3-specs/*/tasks.md 待辦單向投影成唯讀 GitHub Project。
md 唯一真相源、Project 永遠唯讀,無反向同步、不會兩個真相源打架。預設不逼:
沒裝 Arcrun/答不要的用戶完全 no-op,純 md 不受影響。

- 投影 workflow template/system-dev/workflows/tasks-project-sync.yaml(Arcrun
  workflow):foreach 增量 → switch 動作 → http_request 打 GitHub API:新 task→
  issue create / [ ]→[x]→close / 文字改→edit / 行刪→archive(not_planned),並用
  GraphQL addProjectV2ItemById 投影進 Projects v2。auth 走 {{creds.github_token}}。
- 本地觸發端 tasks-project-sync.local.sh:因 Arcrun workflow 跑遠端 CF Workers、
  沒本地 fs/git,「讀 tasks.md / git diff / 回寫 <!-- gh:id -->」由本地端做完再
  acr run 餵增量。本地一半 + 遠端一半,職責邊界清楚。薄殼不自刻 parser。
- 防複發核實:每個 component 經 acr parts 核實存在(registry 無 github 零件,全用
  http_request 打 REST/GraphQL)。acr validate --offline 通過(7 三元組、config 完整)。
- 啟用判準=對話 + 能力,不掃檔(Arcrun workflow 存遠端 KV、零本地檔也能用 →
  掃檔 false negative)。install/init 問一句 → 查環境有 Arcrun 就 acr push 啟用、
  沒有就一次性溫和廣告。帶檔 ≠ 啟用。install/update 隨 SDD 模組帶 workflow(add_if_missing)。
- 守 flag 紅線:push 後本機觸發單次,禁定期輪詢、禁 GitHub Actions fan-out。

⚠️ 端到端(acr push 真部署 + acr run 真投影)待 leo21c 驗,本版為 code-done 骨架。
SDD(內部,gitignore 不推):docs/3-specs/tasks-project-projection/。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28 16:24:33 +08:00

251 lines
15 KiB
Markdown

# system-dev-template
[繁體中文](README.md) | **English**
> Turn Claude Code from a "sprinting engineer" into a "disciplined engineer."
CC is an excellent engineer, but not a good project manager. It sprints to get work done — great for small projects, but on large ones it tends to:
- **Fix one thing, break another**: no global view, no SDD constraints
- **Let docs rot**: its built-in memory is unreliable, knowledge vanishes with the conversation, and it loves writing docs it never reads back — scattering them everywhere
This template solves both problems with two systems:
| System | What it solves | Core mechanism |
|--------|----------------|----------------|
| **SDD system** | Global view, think before doing | No code change without a `design.md` + `tasks.md` first |
| **LLM Wiki** | Memory that compounds, ordered docs | Two spaces: raw source (human-written) + `system-dev/wiki/` (AI-curated) |
> **Not just code projects, not just Claude Code.** LLM Wiki now also recognizes **Logseq / Obsidian vaults** —
> at install time it auto-detects which kind of folder you're in, writes the matching "raw source" into `CLAUDE.md`,
> reads only from there when curating the wiki, and **never moves your vault structure**
> (see "Not just code — Logseq / Obsidian vaults too" below).
> The curator isn't limited to Claude Code either — **claude.ai's Cowork** can use the same rules to scan and
> curate every wiki on your machine (see "Cowork can curate wikis too" below).
- SDD: already popular. The most thorough implementation is probably Amazon Kiro, but it's hard to pay for in Taiwan. This approach beats any flashier method — it forces CC not to do whatever it pleases.
- LLM Wiki: the latest RAG idea from the legendary Karpathy. It's a *pre-compile* approach — better and less fiddly than the embedding-and-chunk-into-vectors method your company bought, and far easier to run.
---
## Two ways to use it
### Option 1: New project
```bash
git clone https://github.com/uncle6me-web/system-dev-template
cp -r system-dev-template/template/. your-new-project/
cd your-new-project
```
Then in a CC conversation:
```
/wiki-init
```
### Option 2: Existing project (retrofit)
```bash
cd your-existing-project
curl -sSL https://raw.githubusercontent.com/uncle6me-web/system-dev-template/main/scripts/install.sh | bash
```
The script only creates what's missing — **it never touches files you already have**.
**Just one piece?** The two systems install separately (sometimes you only need the wiki, not SDD):
```bash
# Download, then run with a flag
curl -sSL .../install.sh -o install.sh && bash install.sh --wiki # LLM Wiki only
bash install.sh --sdd # SDD only
bash install.sh --all # both (default)
```
When run directly in a terminal (with a tty), running it without a flag **asks interactively** which piece to install — friendliest for non-engineers. With no tty, `curl | bash` safely defaults to `--all`. The hooks in `settings.json` are assembled automatically based on the modules you choose.
After installing, in a CC conversation:
```
/wiki-init
```
CC will scan your existing docs, build the wiki, and tidy up the docs structure.
> CC loves writing docs and scattering them everywhere; the bigger and older a project gets, the messier its folders — yet it's afraid to move anything. With the folder conventions written down, it can file everything for you in one pass.
> LLM Wiki won't touch your original files, but it builds a separate wiki and fixes your entry point — which is `CLAUDE.md`. So even though things get reorganized, your documents won't disappear.
---
## 🔄 Already on an older version? Update with one line
Heard there are new features and want the latest? Just run this:
```bash
cd your-project
curl -sSL https://raw.githubusercontent.com/uncle6me-web/system-dev-template/main/scripts/update.sh | bash
```
It first compares your version with the latest, tells you **which new features you'd gain**, and then:
| Action | Target |
|--------|--------|
| 🆕 **Add** new features (hooks / commands / templates the old version lacked) | Template files |
| ⬆️ **Update** template logic (hooks, commands, `TEMPLATE-*` swapped for new versions) | Template files |
| 🔒 **Never touch** your content and settings | `wiki/status.md`, `mistakes.md`, `decisions-summary.md`, `.wikiignore`, `settings.json`, `CLAUDE.md` |
> **Why use curl the first time?** Old installs don't have `update.sh` locally yet, so the first run has to fetch it from the remote.
> After running, it installs itself to `system-dev/scripts/update.sh`, so **next time just run** `bash system-dev/scripts/update.sh` — no more curl.
Updates only touch "installed modules" (wiki installed → wiki updated; SDD installed → SDD updated), detected automatically.
If `settings.json` is missing a hook that only the new version has, it won't change your settings for you — but it will **list them at the end** as a reminder to add them manually (it never edits your settings without asking).
📜 Want to know what changed each time and which version you're on? See the **[CHANGELOG](CHANGELOG.md)**.
---
## Not just code — Logseq / Obsidian vaults too
LLM Wiki originally assumed "raw source lives in `docs/`", but note vaults like Logseq and Obsidian have their own directory conventions.
Now `install.sh` **auto-detects the folder type** before creating `CLAUDE.md`, and writes the matching "raw source" into `CLAUDE.md`:
| Detected | Type | Raw source |
|----------|------|------------|
| `logseq/` folder | Logseq | `pages/`, `journals/` |
| `.obsidian/` folder | Obsidian | all `.md` under the root |
| Neither | Regular project | `docs/` (original behavior) |
The declaration written into `CLAUDE.md` is **an instruction for the AI** — it tells the curator "here's where the raw source is, read only from there when curating the wiki",
and for vaults it **explicitly forbids moving, renaming, or re-classifying `.md` files**; curation output always goes only into `system-dev/wiki/`.
This way, even with a note vault, the original structure stays intact and your notes never become unreadable.
> **Already have a `CLAUDE.md`?** It's never overwritten (the "don't touch what exists" principle). Instead, the declaration you should add is **listed at the end** of the install for you to paste manually.
---
## Mirror tasks to GitHub (optional, needs Arcrun)
If you installed SDD, you can **one-way project** the tasks in `system-dev/docs/3-specs/*/tasks.md` into a read-only GitHub Project (handy for boards/dashboards).
- **One-way, md is the source of truth**: the only write point is `tasks.md` — CC edits md when it finishes a task, you ask the AI to edit md when you want changes, **nobody touches the Project directly**. The Project is always read-only, so there's no two-sources-of-truth conflict.
- **Needs Arcrun** (a free AI-friendly workflow toolkit). No Arcrun → plain md, full no-op, unaffected.
- **How to turn it on**: after install, CC asks you once "do you want tasks mirrored to GitHub?" Answer "yes" and if Arcrun is present, CC `acr push`es the projection workflow to enable it; if Arcrun isn't installed, CC tells you "ask Claude to install it; you can also enable sync later." Answer "no" and nothing happens — no nagging.
- **Plays by the rules**: triggered once locally after a push (no periodic polling, no GitHub Actions), staying within the anti-flag red line.
> The workflow lives at `system-dev/workflows/tasks-project-sync.yaml` (+ local trigger `.local.sh`). **Shipped ≠ enabled** — enabling means you said yes and `acr push`ed.
> ⚠️ End-to-end flow is still being verified (issue #16).
---
## Cowork can curate wikis too
The wiki curator is no longer limited to Claude Code in the terminal — **claude.ai's Cowork** can do it too.
`system-dev/docs/SKILL.md` provides a skill for Cowork (`wiki-cowork-scan`) that **shares the same rules** as CC's `/wiki-init` and `/wiki-capture`:
- Scans every folder under `~/Documents` that has system-dev-template installed (i.e. has a `system-dev/wiki/`)
- Uses the **same detection logic as `install.sh`** to decide whether each folder is a regular project / Logseq / Obsidian
- Reads only the raw source and only appends to `system-dev/wiki/` (no overwrite, no delete); **never touches** raw source, `CLAUDE.md`, `logseq/`, `.obsidian/`, `assets/`
**CC and Cowork share an identical output format**, so whatever one curates, the other sees and skips or supplements — no duplication, no overwriting.
Great for a scheduled Cowork run that keeps every wiki on your machine up to date automatically.
> To use it: give `system-dev/docs/SKILL.md` to your Cowork as a skill reference, then tell it "curate the wiki".
---
## Directory guide
```
system-dev-template/
├── template/ ← skeleton copied into new projects
│ ├── CLAUDE.md ← fill-in-the-blanks navigation sign
│ ├── docs/ ← docs structure (six-layer taxonomy)
│ └── .claude/
│ ├── wiki/ ← CC's memory space (incl. .wikiignore for sensitive exclusions)
│ ├── commands/ ← slash commands
│ ├── hooks/ ← hard interceptors (recall + SDD protocol + wiki secret scan)
│ └── settings.json ← wires up hooks (install.sh assembles by module)
├── skills/
│ └── llm-wiki/ ← copy into Legacy-Workspace/.claude/skills/
├── scripts/
│ ├── install.sh ← retrofit script for existing projects
│ └── update.sh ← one-line update for old versions (swaps templates only, never your data)
└── docs/ ← this repo's own documentation
├── why.md ← design philosophy
├── wishlist.md ← pending features and completed records
└── SKILL.md ← wiki-curation skill for claude.ai Cowork (wiki-cowork-scan)
```
---
## Slash Commands
Available in any CC conversation after install:
| Command | What it does |
|---------|--------------|
| `/wiki-init` | Initialize the wiki (new project or retrofit) |
| `/wiki-recall` | At session start, manually resume (fallback when the hook doesn't fire) |
| `/wiki-capture` | Save this conversation's conclusions into the wiki |
| `/wiki-update` | At session end, update `status.md` |
| `/sdd-check` | Check whether the current task has a matching SDD |
| `/issue-handle` | Handle GitHub issues (read back from your own repo / cross-repo posting asks first / no auto-polling) |
The naming loop: init (create) → update (save, end of session) ↔ recall (resume, start of session) → capture (save conclusions anytime).
---
## Hooks (soft norms → hard interception)
Norms are no longer just soft reminders in `CLAUDE.md`; there's a backstop:
| Hook | Role |
|------|------|
| `session-start-recall.sh` | Auto-injects the key points of `status` at session start — doesn't rely on CC remembering |
| `sdd-guard.sh` | Touching a code file with no SDD → block (exit 2); the automated version of `/sdd-check` |
| `wiki-secret-scan.sh` | A sensitive value about to be written into `system-dev/wiki/` → block (exit 2); a mechanical backstop for passwords/keys/PII |
| `pre-write-guard.sh` | Skeleton for project-specific bans (disabled by default; takes effect once you fill in a pattern) |
---
## Wiki secret protection (content you don't want indexed)
Like `.gitignore`, it keeps content you don't want in the wiki (passwords, keys, PII) from being indexed. Three layers:
| Layer | Mechanism | What it blocks | Nature |
|-------|-----------|----------------|--------|
| **L1** | `system-dev/wiki/.wikiignore` (glob) | An entire sensitive file is not indexed | Protocol (CC complies) |
| **L2** | Inline markers `<!-- wiki:ignore -->``<!-- wiki:end -->` | A section within a file is not indexed | Protocol (CC complies) |
| **L3** | `wiki-secret-scan.sh` hook | A sensitive value actually being written into the wiki → exit 2 blocks it | **Hard interception (mechanical detection)** |
L1/L2 are markers you set proactively; L3 is the automatic backstop — if CC misses the first two, the moment a secret is written into the wiki it's caught by regex (password assignments, PEM private keys, AWS/GitHub/Slack keys, JWTs, connection-string credentials, national IDs, credit-card numbers).
> Honest limits: L1/L2 rely on CC's self-discipline; L3 relies on pattern matching (with false positives/negatives).
> This is a mechanism to reduce **accidental** leaks, not a vault — real secrets shouldn't be in version control in the first place.
> On a false positive: add `wiki-secret-ok` at the end of the line to allow it; for a whole sensitive file, add it to `.wikiignore`.
> Honest limits: the hook blocks syntactically obvious violations (writing directly to a file); it can't catch detours hidden in helpers / bash.
> Its value is "trying to skip it gets caught + leaves an auditable trace", not technical tamper-proofing — the docs (mindset) and the hook (backstop) are both indispensable.
---
## Design principles
- **Additive, not destructive**: when retrofitting an existing project, your existing norms stay; the wiki system layers on top
- **Structure is protocol**: CC and you share the same taxonomy, no need to re-explain every time
- **`CLAUDE.md` doesn't grow**: past 100 lines is an architecture problem, not a reason to add more content
- **Capture conclusions on the spot**: after a discussion, use `/wiki-capture` so knowledge stops vanishing
---
## Acknowledgments
This template stands on the shoulders of giants:
- **[Andrej Karpathy](https://gist.github.com/karpathy)** — originator of the LLM Wiki concept. This template's two-space memory system comes directly from his April 2026 idea: using an LLM to "pre-compile" knowledge into interlinked markdown, rather than re-running embedding retrieval on every query. One line of his captures the spirit: *"Obsidian is the IDE, the LLM is the programmer, the wiki is the codebase."*
- Further reading: [The Andrej Karpathy LLM Wiki Idea](https://reliabilitywhisperer.substack.com/p/the-andrej-karpathy-llm-wiki-idea), [Beyond RAG (Level Up Coding)](https://levelup.gitconnected.com/beyond-rag-how-andrej-karpathys-llm-wiki-pattern-builds-knowledge-that-actually-compounds-31a08528665e)
- **[Amazon Kiro](https://aws.amazon.com/documentation-overview/kiro/)** — this template's SDD (Spec-Driven Development) approach is learned from Kiro. It takes "have a structured spec before you start" to the furthest extreme; paying for it is inconvenient in Taiwan, but its methodology deserves respect and borrowing.
- **Claude (Claude Code / Anthropic)** — this template's hooks, secret protection, modular install, and this very README were all pair-developed with Claude. The template itself exists to turn Claude Code "from a sprinting engineer into a disciplined engineer" — it's both the tool and a co-author.