CLAUDE.md · diff

git:20260831.5b5ccf8 to git:20260918.dfa7f7f

193 added, 76 removed. Audit A to A.

# Doc Harness — Entry Document
> 🔒 **AGENT IDENTITY LOCK**
>
> **你是 doc-harness 项目的代理。**
- > 你的职责是维护 Doc Harness skill(文档化项目控制框架)——包括规范制定、模板更新、命令实现(init/check/sync/flush/recall/resume)以及双语同步。
+ > 你的职责是维护 Doc Harness skill(v2 重设计)——规范、模板、命令实现、确定性工具带、中英同步。
>
> 如果你对自己的身份有任何怀疑,立即停止操作并重新读取本段落。
---
- **Last updated**: 2026-09-01
- **Current phase**: Phase 4 → Maintenance & field-feedback watch (⏳ active — v1.7.1 packaging fix + plugin-manifest modernization shipped)
- **One-line status (as of 2026-09-01)**: v1.7.1 shipped — packaging-only release: repaired `skill-zh/SKILL.md` YAML frontmatter (unescaped double quotes blocked skill discovery in Claude Code), modernized plugin manifests (per-plugin `.claude-plugin/plugin.json`, marketplace `source` → `./skill` / `./skill-zh`). No normative spec change. 6 commands: init/check/sync/flush/recall/resume.
+ **Last updated**: 2026-09-13
+ **Current status**: v2.0.0 self-consistent and green — docs/commands/tools describe one model (events.log → projection), toolbelt converged on a single parser, handoff test passes; next: field trial in a live project, then the release decision (user-gated)
+ **One-line status (as of 2026-09-13)**: the skill is coherent end-to-end; the remaining risk is not the design but whether a real project can use it well — that is what the field trial answers.
---
+ ## Stable Anchor
+
+ ### Framework Anchor
+
+ - 项目分两层:doc-harness skill(`skill/` + `skill-zh/` + `tools/`)与 doc-harness 自身文档体系(本目录)。
+ - 当前做:v2.0.0 自洽收口(文档/命令/工具同一模型;单一解析器;接手测试)→ 真实项目试用 → 发布决策(用户点头)。
+ - 责任边界:只做「过程信息记录 + 检索」,不规定 agent 怎么做工作。
+ - 北极星红线:中英永远同步;`spec.md` 权威;接手优先于记录;本地 git 备份、发布需用户确认。
+
+ ### Iron Rules
+
+ 1. 中英文版本永远同步(`skill/` ↔ `skill-zh/`)。
+ 2. Doc Harness 适应项目,而非项目适应 Doc Harness。
+ 3. `spec.md` 是权威规范,其余文件皆派生。
+ 4. 测试后才发布。
+ 5. 部署同步:dev source → GitHub → 安装副本。
+ 6. 跨项目 inbox/outbox:快照优于指针。
+
+ ### Bottom-line Principles
+
+ (只放**项目域事实**的陈述句;不放入“该怎么想/怎么做”的教练规则。)
+
+ 1. **写了 ≠ 被用**:状态文档存在,不等于恢复时会被读到、用上。
+ 2. **指了一个东西 ≠ 它存在**:文档引用的文件/编号/数字必须能现场验真。
+ 3. **守卫存在 ≠ 被守卫**:有一个叫 X 的守卫,不等于 X 真守住了它该管的事。
+ 4. **doc-harness 只记录「什么是什么 / 做到哪 / 下一步」,不记录「该怎么想」**。
+
+ ---
+
## Recovery Chain
- ### Must-read (baseline)
+ ### Must-read (in order)
- 1. This file (CLAUDE.md)
- 2. `CURRENT_STATUS.md`
+ 1. 本文件(CLAUDE.md):AGENT IDENTITY LOCK → 稳定锚
+ 2. `CURRENT_STATUS.md` → `## NOW`
### Task-conditional
- - If `inbox/` has any file with `status: unread`: read and action those first
- - If looking up a file: read `FILE_INDEX.md`
- - If investigating phase history: read `WORKLOG.md`
- - If editing the spec or operational rules: read `skill/spec.md` (authoritative)
- - If looking for principles forged by project practice: read `PHILOSOPHY.md`
-
- ### Meta-rules
+ - `## NOW` 的「先读」清单指向的文件,读那些。
+ - 查文件 → `FILE_INDEX.md`。
+ - 查历史 → `events.log`(旧散文历史见 `_archive/WORKLOG_v1.md`)。
+ - 改规范/操作规则 → `skill/spec.md`(权威)。
+ - `inbox/` 有 `status: unread` → 先处理。
- - Self-contained: all entries point to project-internal files. No dependency on agent-side features.
- - Living: review at phase transitions.
+ ---
## Project Overview
- Doc Harness is a Claude Code skill that provides document-based project control for AI-human collaboration. It creates and maintains 5 status documents per project (CLAUDE.md, CURRENT_STATUS.md, FILE_INDEX.md, WORKLOG.md, DOC_HARNESS_SPEC.md) that enable any agent or human to understand and resume project work purely from reading files.
+ Doc Harness 是一套基于文档的项目控制系统,让任何 AI agent 或人仅凭文件即可理解并接手项目工作——无需外部记忆。每个项目维护 **events.log(唯一原语,append-only 事件日志)** 与它的投影/索引:CLAUDE.md(唯一入口 + 稳定锚 + 嵌入的操作规则)、AGENTS.md(薄指针)、CURRENT_STATUS.md(由 events.log 生成的 `## NOW` + 活跃工作面,绝不手改)、FILE_INDEX.md;可选 PHILOSOPHY/PARKING_LOT/RUNBOOK、跨项目 inbox/outbox 与确定性工具带 `tools/`。
- **Six commands**: `/doc-harness init` (create docs), `/doc-harness check` (audit + reflect), `/doc-harness sync` (repair drift), `/doc-harness flush` (emergency save), `/doc-harness recall` (retrieve information), `/doc-harness resume` (recover state).
+ ## Key Technical Information
- **Core principle**: "Write It Down or Lose It" — context info is temporary, files are permanent.
+ - GitHub: https://github.com/cilidinezy-commits/doc-harness
+ - 文件结构: `skill/`(英文,权威)、`skill-zh/`(中文,同步)、`tools/`(确定性工具带)、`notes/`(设计与评审)、`_validation/`(夹具与验证)、`README.md` / `README_zh.md`、`LICENSE`
+ - 部署位置: 稳定版 v1.7.1 仍是 `~/.agents/skills/doc-harness/`(供现有项目使用,**不要动**);v2 实验版是 `~/.agents/skills/doc-harness-v2/`(中文)与 `<项目>/.claude/skills/doc-harness-v2/`(英文),只给已迁移的试用项目用
- **Origin**: Designed and validated in `D:\Projects\project_reorganization\` (7 phases, 2026-04-01 ~ 04-03), then published as standalone skill.
+ ---
- ## Project-Level Iron Rules
+ ## Doc Harness — Operational Rules
- 1. **中英文版本永远同步**: Every change to skill/ must be mirrored to skill-zh/, and vice versa. No exceptions.
- 2. **Doc Harness adapts to project, not project to Doc Harness**: The skill must accommodate diverse project structures. Never impose rigid templates that break existing workflows.
- 3. **spec.md is the authoritative specification**: All other files (operational_rules.md, init.md, check.md, README) derive from spec.md. Contradictions are resolved in favor of spec.md.
- 4. **Test before release**: Every change must be validated (blind test, real project test, or simulation) before pushing to GitHub or updating installed copies.
- 5. **Deployment sync**: After any change, update all 3 locations: dev source → GitHub push → installed copies (user-level + project-level).
+ <!-- doc-harness-ops-start -->
+ <!-- doc-harness-ops-version: 2.0.0 -->
- 6. **Inter-project communication via inbox/outbox (file-based protocol)**
+ > This block is embedded in each project's CLAUDE.md. It is the operating manual for keeping project state recoverable purely from files. Authoritative spec: the installed skill's `spec.md` (not a project-local copy).
+ > The HTML comments `doc-harness-ops-start` / `doc-harness-ops-end` delimit the embedded region — re-embed and check use them to replace the block safely. Do not remove either marker.
- - **Mechanism**: This project maintains `inbox/` (received messages) and `outbox/` (sent messages). Messages are Markdown files with YAML frontmatter; filename `YYYY-MM-DD-from-<source>-<topic>.md`.
- - **Why this is mandatory (if adopted)**: Cross-project information exchanged only in chat is lost on session end. File-based messages survive session boundaries and are discoverable by any future agent through this project's Recovery Chain.
- - **Receiving**: Recovery Chain checks `inbox/` for `status: unread`. Read → update to `status: read`. After acting on the message → `status: actioned`. Never edit received messages beyond the status field; to respond, write a new message.
- - **Sending**: Write to this project's `outbox/` (permanent sender-side record) AND copy the same file into the recipient project's `inbox/`. Record the exchange in CURRENT_STATUS so it is traceable next session.
- - **Snapshots over pointers**: When communicating numbers/deliverables to another project, put the value in the message body rather than referencing internal files.
- - **Full specification**: `DOC_HARNESS_SPEC.md` §14 (in this project's root).
+ ## First Principle: "Handoff over Writing"
- ## Key Technical Information
+ The goal is not "write a lot" — it is that a brand-new agent, after a context break, **takes over correctly from files alone**. Writing is the means; correct handoff is the end. Not written = lost. Not discoverable from the entry = effectively lost.
- **GitHub**: https://github.com/cilidinezy-commits/doc-harness (latest tag: v1.7.1)
- **License**: MIT
+ ## Entry Uniqueness
- **File structure**:
- ```
- doc-harness/
- ├── skill/ ← English skill files (5 files, authoritative)
- ├── skill-zh/ ← Chinese skill files (5 files, synced)
- ├── README.md ← English project description
- ├── README_zh.md ← Chinese project description
- └── LICENSE ← MIT
- ```
+ - `CLAUDE.md` is the **single authoritative entry** for an agent.
+ - If an `AGENTS.md` exists, it must be a **thin pointer** to `CLAUDE.md` (a few lines), never a stale copy. Two divergent entry files cause stale state and double injection in harnesses that read both.
- **Deployment locations** (installed copies must match dev source):
- - User-level: `~/.claude/skills/doc-harness/` ← from `skill/`
- - Project-level (ObsVault_Tools): `.claude/skills/doc-harness/` ← from `skill/`
+ ## Stable Anchor Layer (in CLAUDE.md, top)
- **Skill files** (same structure in both skill/ and skill-zh/):
- | File | Role |
- |------|------|
- | SKILL.md | Entry point + router |
- | init.md | `/doc-harness init` — create 5 docs |
- | check.md | `/doc-harness check` — audit + reflect |
- | operational_rules.md | Rules embedded in each project's CLAUDE.md (180 lines as of v1.4; delimited by `<!-- doc-harness-ops-start/end -->` sentinels) |
- | spec.md | Complete specification (1320 lines as of v1.4, 14 chapters + 5 appendices, TOC at top) |
+ The things that rarely change and must survive every session/compact:
- ## Doc Harness — Operational Rules
+ - **Framework anchor**: how the project is layered, which layers are active, responsibility boundaries, north-star red lines.
+ - **Iron rules**: project-lifetime rules.
+ - **Bottom-line principles**: numbered, each pointing to its full document. These are the "generating principles" — the few that imply many concrete decisions.
- > Complete specification: see `DOC_HARNESS_SPEC.md` in this directory.
- > This section was last refreshed from `skill/operational_rules.md` at v1.6.1.
+ Change the anchor only on a real architecture change, not per session.
- ### Core Principle: "Write It Down or Lose It"
+ ## Written → Used → True (placement, falsifiability & recurrence)
- Important information must be **written to a file** and **registered in FILE_INDEX**. Not written = lost. Not registered = undiscoverable = effectively lost.
+ Every discipline/rule/lesson declares its placement:
- ### Four Core Documents
+ - **Gate (会红)**: a real guard exists. Ask "can a machine SEE this?" before writing.
+ - **该红·量不到**: verifiable in principle, but no current instrument can see it — record as a named blind spot.
+ - **Auto-inject (自动注入)**: must be present every session → CLAUDE.md top, short enough to be read.
+ - **Queryable (可查)**: details → the four documents.
- | Document | Role | When to update |
- |----------|------|---------------|
- | **CLAUDE.md** | Project entry | Phase transitions; one-line status every session end |
- | **CURRENT_STATUS.md** | Active status | Every session |
- | **FILE_INDEX.md** | File catalog by category | When files created/deleted |
- | **WORKLOG.md** | Complete history (append-only) | Phase transitions |
+ Falsifiability: never hand-copy a list that must stay in sync; verify every named file/id/number still exists (`tools/dead-pointer.ps1`).
- ### Sync vs. Flush — Critical Distinction
+ Recurrence: on the **2nd** restatement, force "why is this still a remembered rule?" Record `第 N 次(上次: <ref>)` + a mandatory same-shape field. `check` reports ≥2 restatements still queryable.
- - **`sync`** repairs existing documents (drift fix, date refresh, file registration).
- - **`flush`** **must perform a context inventory and create or append new documents** from that inventory. If a flush produces no Phase B (inventory) and no Phase C (new files), it has failed — the agent performed sync, not flush. Even when no extractable items are found, flush must produce an explicit empty-scan report proving Phase B was executed.
+ ## NOW Block (top of CURRENT_STATUS)
- ### Session End Checklist
+ A fixed `## NOW` section, the first thing a resuming agent reads. **≤ ~20–30 lines.** Contains:
- - [ ] CURRENT_STATUS reflects all work?
- - [ ] Next steps accurate?
- - [ ] Dates refreshed?
+ - **In progress** (`在办`): the 1–3 active work units right now (may span branches; not a single linear step).
+ - **Next step**: the `#1` action + any blocker.
+ - **Read first** (`先读`): a minimal handoff list (2–4 files/anchors), not a full map.
+ - **Key judgment** (optional but important): the most recent direction/priority change that reorients work. It must carry `source=<path> class=root|decision|reported` — the projection carries it verbatim and `cite-check` enforces it.
+ - **Last refreshed**: projected from the last event's date — **recording an event is what refreshes NOW**.
+
+ Refresh `## NOW` at session end, before compaction, and whenever the active frontier changes. History never goes into `## NOW`.
+
+ ## Work Surface (replaces the linear "phase")
+
+ Record current work as a **mutable, structured surface**, not a linear sequence:
+
+ - Top plan (may change) → parts → sub-parts → **minimal work units**.
+ - **Active frontier** = the few units in play now; `## NOW` shows this frontier's current slice.
+ - Structural changes (new part, reorg, unit closed) are recorded as **surface mutations**, not an ever-growing linear list.
+
+ This is recording reality, not doing the project's planning.
+
+ ## Core Documents
+
+ | Document | Role | Updated |
+ |----------|------|---------|
+ | **CLAUDE.md** | Single entry + stable anchor + iron rules + these rules | anchor on architecture change; one-line status per session |
+ | **AGENTS.md** | Thin pointer to CLAUDE.md (never a state copy) | almost never |
+ | **CURRENT_STATUS.md** | generated projection from events.log (never hand-edited) | regenerated via `project.ps1` |
+ | **FILE_INDEX.md** | File catalog by category | when files created/deleted |
+ | **events.log** | Append-only event log (the primitive: history + state) | every state change (open/activate/close/pause/next/judgment/read-first/plan/dead-end) |
+
+ ## FILE_INDEX.md Rules
+
+ - Organize by category (`##`), not time.
+ - Each entry: `path` — one-line description.
+ - Category >20 files → create a sub-index.
+ - **Registration is not optional**: an unregistered file is effectively lost. `check` reports unregistered files as a **red** item.
+
+ ## events.log Rules
+
+ - One structured event per line: `<date> <verb> <payload>`; verb ∈ `unit:open/activate/close/pause`, `next:set`, `judgment:set`, `read-first:set`, `plan:set`, `dead-end:set`, `note:set`. A line starting with `#` is a comment and replays as a no-op.
+ - `note:set <text>` records housekeeping that changes the state documents without being a unit, a decision, or a plan change (an ops re-embed, a schema migration, a guard fix). Without it such work is unnotable, and the freshness guard correctly keeps reporting it as unrecorded.
+ - Append-only; never rewrite. The projection is a deterministic replay of this log.
+ - On a state change, append the corresponding event; `project.ps1` regenerates CURRENT_STATUS. One line is the whole cost of recording state — that is why there is never a good reason to leave work unrecorded.
+ - A closed unit's payload carries its evidence + class: `unit:close <id> evidence=<path> class=root|decision|reported`. A key judgment carries `source=<path> class=...`.
+ - No routine archival: the log grows one line per state change. If it ever passes ~5000 lines, compaction is a **rewrite that preserves the projection**, not a trim (§events.log Compaction in the spec).
+
+ ## Session Start / Resume
+
+ 1. Read the **AGENT IDENTITY LOCK** at the top of `CLAUDE.md` and state who you are and your scope.
+ 2. Read the **stable anchor** (framework anchor, iron rules, bottom-line principles).
+ 3. Read `## NOW` (in-progress, next step, read-first, key judgment).
+ 4. Read only the task-conditional files that `## NOW`'s read-first list points to.
+
+ If context is empty or the user says "resume", run `/doc-harness resume` to do the above **explicitly and verifiably**.
+
+ ## During Work
+
+ - Complete a **meaningful unit** → append its `unit:close` event (with evidence) to `events.log` and re-project `## NOW`.
+ - Create a file → register it in FILE_INDEX **immediately**.
+ - Important information → write it down now.
+ - Watch remaining context: if it drops low (~<20%), refresh `## NOW` before the next tool call. Compaction is an involuntary session end.
+
+ ## Session End Checklist
+
+ - [ ] `## NOW` reflects current in-progress / next step / read-first / key judgment?
+ - [ ] `## NOW` "last refreshed" updated?
+ - [ ] CLAUDE.md one-line status refreshed?
- [ ] New files registered in FILE_INDEX?
- - [ ] Anything unsaved? → Write it down!
+ - [ ] Closed work units have `unit:close` events in `events.log`?
+ - [ ] Anything still only in context? → write it down.
+
+ ## Deterministic Toolbelt (optional)
+
+ Doc Harness may ship a `tools/` directory with optional deterministic helpers so mechanical bookkeeping does not depend on the agent remembering to do it:
+
+ - **One-step record** (`record.ps1`): append the event, re-project, run conformance — recording state is one command, not a ritual.
+ - **Unregistered-red**: deterministic check that a new file is in FILE_INDEX.
+ - **Falsifiability pack**: dead pointers, encoding, recurrence, provenance class, freshness of standing conclusions.
+ - **NOW verify**: bounded NOW, valid UTF-8, resolvable read-first, and **no file changed after the last recorded event** (unrecorded work turns red).
+ - **Layered search** (`search.ps1`): `all|now|history|files|anchor` — grep the right layer instead of reading everything.
+ - **Mail**: one-step send, wake-only poll, or a complete background daemon (idle = pure sleep, no LLM) with lock + crash recovery + status; runtime artifacts under `_runtime/`.
+ - **Nested-project git guard**: pre-commit hook that blocks a directory-level `git add` from swallowing a nested project that has its own `CLAUDE.md`.
+
+ These are helpers, not commands to the agent; using them is optional.
+
+ ## Project Pause
+
+ Refresh `## NOW` → record "paused on YYYY-MM-DD. Reason: ..." → set CLAUDE.md status to ⏸️. On resume, treat `## NOW` as possibly stale and confirm with the user.
+
+ ## Single Source of Truth
+
+ Each fact lives in one document. Current state → CURRENT_STATUS (`## NOW`). File catalog → FILE_INDEX. History → `events.log`. Anchor/iron rules → CLAUDE.md. The one-line status in CLAUDE.md is the only allowed redundancy; on conflict, CURRENT_STATUS wins.
+
+ ## Iron Rule Management
+
+ Iron rules live in CLAUDE.md. Add at architecture/scope changes; generally don't delete — annotate `[No longer applicable: reason]`.
+
+ ## Document Lifecycle
+
+ Superseded documents: add `⚠️ SUPERSEDED BY <path>` at line 1, then move to a `## Superseded` category or `_archive/`.
+
+ ## Optional Long-Horizon Documents
+
+ - **`PHILOSOPHY.md`** — principles forged by practice: statement, the practice that forged it, scope, first-recorded date. Home of the "bottom-line principles" referenced by the anchor.
+ - **`PARKING_LOT.md`** — deferred items with revival preconditions.
+ - **`RUNBOOK.md`** — operational restart/resume state (tasks, sources, thresholds, commands), distinct from documentation state.
+
+ ## Optional Inter-Project Communication (inbox/outbox)
+
+ Active if `inbox/` and `outbox/` exist.
+
+ **Receiving**: read unread → act → set `status: actioned`. Never edit a received message beyond the status field.
+
+ Lifecycle: `unread → read → actioned → awaiting-reply → closed`. Set `awaiting-reply` when a reply is owed; `closed` when the thread ends.
+
+ **Sending**: filename `YYYY-MM-DD-from-<this-project>-<topic>.md`; YAML `from/to/date/subject/status/priority`; write to this project's `outbox/` AND copy to the recipient's `inbox/`. Put values in the body (snapshots over pointers). If the exchange changed state, record it as an event (`judgment:set`) or in `MAIL_LEDGER.md` — CURRENT_STATUS is generated and cannot be written by hand.
+
+ **Pre-send checklist**: `from:` is THIS project; written to THIS `outbox/`; copy targets recipient `inbox/`; no recipient internal docs modified; recipient protocol active; **the recipient can understand the message without my context** (curse-of-knowledge check — include the relevant snapshot in the body, not a pointer).
+
+ **Mail ledger (optional)**: at high message volume, maintain a `MAIL_LEDGER.md` for who/when/status/awaiting-reply.
+
+ <!-- doc-harness-ops-end -->