project-knowledge-harness¶
A lightweight, file-based memory harness that gives any software project three sharply-separated surfaces:
| Surface | Time direction | Question it answers | Access pattern |
|---|---|---|---|
TODO.md |
Future | "What might we do later?" | Read top to bottom (priority lanes) |
backlog/<slug>.md |
Future | "What was the analysis behind this idea?" | Indexed from TODO.md |
pitfalls/<slug>.md |
Past | "I see error X — has this happened before?" | Grep symptom keywords |
The skill exists to stop two common failure modes: valuable investigation
evaporating from chat history, and the graveyard of IDEAS.md /
ROADMAP.md / WISHLIST.md / LESSONS.md files that nobody maintains.
When the skill triggers¶
Future-direction signals: "where should ideas go?", "maybe later", "nice to have", "工程量太大需要再評估", "先記下來".
Past-direction signals: "save this troubleshooting", "踩過的坑", scattered
"Common issues" sections across docs/.
Either: "is there a place for X?" where X is metadata about decisions or history rather than current features.
Structure of the skill itself¶
skills/local/project-knowledge-harness/
├── SKILL.md # ~170-line entry point; loads on activation
├── assets/ # Copied into target projects
│ ├── TODO.md.template
│ ├── backlog-README.md.template
│ ├── backlog-doc.md.template
│ ├── pitfalls-README.md.template
│ ├── pitfall-doc.md.template
│ ├── agent-guidance.md.template # Snippet for AGENTS.md / CLAUDE.md
│ ├── readme-roadmap.md.template # Snippet for README.md
│ └── td-routing.md.template # td ↔ TODO.md routing snippet (when td is present)
├── scripts/ # Executed during setup or by the agent
│ ├── init.sh # One-shot setup of all of the above
│ ├── todo-kanban.sh # Validator + Markdown / JSON board renderer
│ ├── promote-todo.sh # Atomic active → ## Done move + re-validate
│ ├── start-todo.sh # Optional td bridge: start an item as a td issue
│ └── _lib/ # Shared TODO parser + td bridge (sourced)
└── references/ # Loaded on demand from SKILL.md links
├── tag-schema.md # Priority × effort schema and exact syntax
├── when-to-add-docs.md # Backlog vs pitfall vs invariant decision rules
├── anti-patterns.md # Mistakes to avoid
├── deployment-exclusion.md # Per-mechanism ignore-rule cheatsheet
└── integrating-trackers.md # td / GitHub Issues / Linear layering
SKILL.md is intentionally short and points to references/*.md so the
agent only loads decision detail when it needs it
(progressive disclosure).
How to apply the skill in a fresh repo¶
The default workflow is one command:
skills/local/project-knowledge-harness/scripts/init.sh \
--target /path/to/project \
--project-name "My Project" \
--deployment chezmoi # or npm | pip | docker | none
This is idempotent — re-running it skips files that already exist and
snippets whose sentinel marker is already present. Pass --force to
overwrite the three template files; snippets are still appended only once.
init.sh performs:
- Render
TODO.md,backlog/README.md,pitfalls/README.mdfromassets/*.template, substituting<PROJECT NAME>,<DEPLOYMENT MECHANISM>,<IGNORE FILE>. - Append the agent guidance snippet to
AGENTS.md/CLAUDE.md(auto-detected; override with--agent-contract). - Append the "Roadmap & lessons learned" snippet to
README.md(skip with--readme ""). - Run
todo-kanban.sh --validate-only TODO.mdto confirm the file is machine-readable. - Print the deployment-specific lines you should add to your ignore file.
init.sh deliberately does not edit .gitignore /
.chezmoiignore.tmpl / .dockerignore — the blast radius is too high
for an automated tool. Use the printed cheatsheet as your TODO.
Bundled scripts in detail¶
scripts/todo-kanban.sh¶
Validates the format and renders a kanban-style board.
scripts/todo-kanban.sh # default: TODO.md, Markdown board
scripts/todo-kanban.sh path/to/TODO.md # explicit file
scripts/todo-kanban.sh --validate-only # exit code only
scripts/todo-kanban.sh --json # machine-readable lane summary
Validation rules:
- First non-empty heading must be
# TODO. - Sections must appear in order:
## P1,## P2,## P3,## P?,## Done. Additional headings after## Doneare allowed (e.g., a## Notesor prune log section). - Top-level list items are validated:
P1/P2/P3:- [ ] **[Effort] Title** — descriptionP?:- [ ] **[?/Effort] Title** — descriptionDone:- ✅ [YYYY-MM-DD] [P#/Effort] Title — summaryEffort is one ofS,M,L,XL. Active items may end with→ [research](backlog/<slug>.md).- Anything that is not a top-level
- [ ]/- ✅item — prose, blockquotes, HTML comments,---rules, indented sub-bullets — is ignored and does not count toward lane totals. This lets you write inline guidance under each section without breaking the validator. - Compatible with macOS system Bash 3.2 (no associative arrays,
no
readarray).
scripts/promote-todo.sh¶
Move an active item from P1 / P2 / P3 / P? into ## Done with
the dated Done syntax, then re-validate.
scripts/promote-todo.sh \
--title "<substring of the item's title>" \
--summary "<one-line shipped summary>"
Behaviour:
- Substring match against the title field (case-sensitive). Refuses to run if zero or multiple active items match — refine the substring.
- Inserts the new
Doneentry immediately after the## Doneheading, usingdate -u +%Y-%m-%d(override with--date YYYY-MM-DD). - Looks up the validator next to itself; if validation fails after the edit, the original file is restored.
- Use
--dry-runto preview the rewritten file without mutating.
scripts/start-todo.sh (optional td bridge)¶
For projects that also use td for in-flight
agent work. Git stays the source of truth, and the link runs one way: a td
issue labelled pkh with the item's exact title points at the TODO.md
item. TODO.md never stores td ids, because they are machine-local unless
td-sync is set up.
PKH_TD=auto|on|off(defaultauto): the bridge is active only when td resolves a project from the current directory, including worktrees. Without td every script behaves as before.promote-todo.shprints a harvest-then-review hint for the open issue and never closes it.todo-kanban.shmarks in-flight items with🔧 td-xxxxand lists orphanedpkhissues.--validate-onlynever queries td.init.sh --td auto|on|offappends the routing snippet to the agent contract.
scripts/init.sh¶
See the workflow above. Notable flags:
--agent-contract FILE— override the auto-detectedAGENTS.md/CLAUDE.md/.opencode/AGENTS.md/.cursorruleschoice.--readme ""— skip the README snippet (useful for repos with their own conventions).--no-validate— skip the finaltodo-kanban.sh --validate-onlypass (for scripted bootstraps where validation is checked separately).--td auto|on|off— append the td ↔TODO.mdrouting snippet when td is detected (auto), always (on), or never (off).
Reference docs the skill loads on demand¶
references/tag-schema.md(also surfaced as a human-readable page: Tag schema)references/when-to-add-docs.mdreferences/anti-patterns.mdreferences/deployment-exclusion.mdreferences/integrating-trackers.md
How this repo uses the skill on itself¶
The repo's own TODO.md,
backlog/ (when populated),
pitfalls/ (when populated),
and scripts/ todo-kanban.sh /
promote-todo.sh are a live example of the harness applied to a real
project. The make kanban
target wraps the validator/renderer.