feat: 基于 commit 水位线的 /llmdoc:update(多批变更检测)#30
Conversation
Replace date/working-tree change detection with a durable commit watermark (llmdoc/state/sync.md). /llmdoc:update and the Codex llmdoc-update skill now diff watermark..HEAD (net), support multi-batch --range/--commits/--since/--from, degrade gracefully (non-git, shallow, first-run, rebased, HEAD-behind), and advance the watermark on success. - New tracked watermark: llmdoc/state/sync.md (single load-bearing SHA) - Rewrote commands/update.md + skills/llmdoc-update/SKILL.md: resolution ladder (rev-parse existence check before merge-base; two-direction is-ancestor for HEAD-behind), batch flags, watermark-advance terminal - Agents (Claude .md + Codex .toml): recorder owns/advances the watermark with batch-tip content reads and single-writer; worker never edits index/state - Init seeds the watermark; README (EN/ZH) + plugin manifests -> 2.2.0 Note: this commit intentionally does NOT update the llmdoc/ knowledge docs, so the next /llmdoc:update dogfoods the new capability. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Dogfood of the new commit-watermark update capability: an independent cold agent ran /llmdoc:update following commands/update.md against range 7a8fe47..a9ad7bf, mapped the committed source change to the impacted llmdoc/ docs, updated them, and advanced the watermark. - architecture/update-orchestration.md: commit-watermark model, batch flags, batch-tip content rule, range x authorship x risk mode triggers, watermark / sole-writer / worker invariants - reference/repo-surfaces.md: register llmdoc/state/sync.md as state - index.md: mark state/ as non-knowledge, keep sync.md un-indexed - guides/updating-update-workflow.md: new touch-points + watermark checks - memory/doc-gaps.md: close resolved .codex tomls mirror gap, add a watermark-resolution-ladder test gap - llmdoc/state/sync.md: watermark advanced 7a8fe47 -> a9ad7bf Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A cold agent executing commands/update.md against a real commit range
surfaced five contract defects; fixed here in both the Claude command and
the Codex skill:
- non-git guard was a fall-through (`|| { echo; }` without exit), so a
non-git dir still ran later git commands and emitted fatal 128s. Now an
explicit early-out gates the whole ladder.
- "self-authored" (the hard floor that forces >= analysis) had no
operational test. Defined it: git author email vs git config user.email;
unknown identity => treat as non-self-authored (conservative).
- consolidated the "safe to advance the watermark" preconditions (HEAD
attached, no MERGE_HEAD/rebase/cherry-pick/revert in progress) into a
named gate at the advance step.
- pinned the watermark advance field values (watermark-subject via
git log -1 --format=%s, updated-at ISO-8601 UTC, updated-by /llmdoc:update).
- cautioned against reformatting the `- watermark-commit: ` anchor line.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Second /llmdoc:update cycle over range a9ad7bf..80752ea (2 commits: the C2 doc-only sync + the C3 contract hardening). Validations: - loop-breaker correctly classified the range as a REAL update, not a doc-only fast-forward (excluding llmdoc/ leaves commands/update.md + the skill). - recorder judged C3 to be contract-internal procedure already covered by the update-orchestration.md invariants, so no llmdoc doc change was warranted — the run is an advance-only cycle. - watermark advanced a9ad7bf -> 80752ea via the hardened step-9 gate (HEAD attached, no git op in progress). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Code Review
This pull request introduces commit-based change detection for the llmdoc workflow, anchoring updates on a durable, git-tracked watermark (llmdoc/state/sync.md). It updates various agent configurations, public documentation, commands, and Codex skills to enforce watermark ownership, net-diff inputs, and update mode selection based on range size, authorship, and risk. The review feedback highlights several critical improvements to the shell script logic and git command usage, including: fixing potential fatal errors in the watermark existence and reachability checks when the watermark commit is missing or empty; properly handling NUL-separated rename/copy records in git diff --name-status -z to prevent parser desynchronization; generalizing "40-hex SHA" references to support SHA-256 repositories; ensuring that checks for active git operations verify the actual existence of the resolved paths on disk; removing redundant git diff --name-only --cached calls; and adding defensive handling for empty boundaries when resolving --since dates.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
|
Related to #29 |
Applies all 13 inline review comments (7 issues x dual surface + template), each empirically verified against real git behavior: - existence check now gates reachability via explicit if/elif/else — a missing/empty watermark no longer falls through to `merge-base` (which fatals 128 on a missing object). Same fall-through class as the non-git fix. - `-z --name-status` parsing: rename/copy records are STATUS\0OLD\0NEW\0 (3 fields); read two path tokens for R/C or the parser desyncs. - `git rev-parse --git-path` always prints a path and exits 0 — the in-progress-op check must test the resolved path with [ -f ]/[ -d ]. - `--since <date>`: fall back to the empty tree when the boundary commit B is empty (no commit predates the date), else `..HEAD` is fatal. - drop the redundant `git diff --name-only --cached` (git diff HEAD already covers staged changes). - generalize "40-hex SHA" to "full commit SHA" (SHA-256 repos). - tighten the already-synced terminal to the valid-watermark == HEAD case so the forced-RANGE_BASE=HEAD degraded branches don't misfire it. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
背景
/llmdoc:update(及 Codex 的llmdoc-updateskill)此前从工作树 + assistant 的新鲜记忆 + 日期戳产物来检测变更。这只在"刚改完"时可靠:一旦提交、工作树变干净,
就无法可靠回答"自上次同步以来改了什么",也无法在一次 update 里吞掉多批 commit。
本 PR 用基于 commit 的变更检测替换它,锚定在一个被 git 跟踪的持久水位线
(
llmdoc/state/sync.md)上。改动内容
llmdoc/state/sync.md—— 单一承载字段(
watermark-commit),记录llmdoc/已反映到的最后一个 source commit。机器管理,绝不作为知识索引。
commands/update.md+ Codexskills/llmdoc-update/SKILL.md),引入解析阶梯:
git rev-parse --verify --quiet)再
merge-base(缺失对象会让merge-base --is-ancestorfatal-128 而非退 1)→双向
is-ancestor捕获 HEAD 落后场景(反向区间会把未来文件当删除、抹掉文档)→net diff
git diff --name-status -M -C -z。--range A..B(可重复)、--commits SHA,…、--since REF、--from SHA、--working-tree-only。不相邻批次在批次 tip读取内容(
git show <tip>:<path>),避免卷入未请求的改动。恢复/首次运行的 baseline 强制 ≥
analysis;大回填强制full+ 用户确认)。降级运行绝不伪造水位线推进。
.md+ Codex.toml)、init落种子、README(中英)、插件清单(2.1.0 → 2.2.0)。
验证 —— 用这个特性把它自己发布出来
通过 dogfood 验证:一个独立的冷启动 agent 运行新的
/llmdoc:update(只读已提交的契约、跑真实 git 命令),从已提交的源变更重新生成
llmdoc/文档并推进水位线。端到端跑通(范围、模式、变更→文档映射、水位线推进全部正确)—— 并抓出 5 个契约缺陷,均在本 PR 修复:
作者 email vs
git config user.email。3–5. 推进安全前置检查收敛为具名门;水位线字段格式钉死;锚点行加防重排警告。
第二轮 dogfood 跨一个混合范围(一个 doc-only 提交 + 上述契约修复),确认 doc-only
loop-breaker 正确判定为"真更新",且契约内部、无需改文档的变更会走"仅推进水位线"路径。
git 边界语义(rebase/squash 恢复、HEAD 落后拒绝、shallow、非 git、root/merge 提交、
doc-only 快进)另用一个一次性脚本验证(21/21 全绿;不入库)。
提交
featdocsfixchore后续项
llmdoc/memory/doc-gaps.md。当前保障来自"文档化 + 已实测的 git 命令"以及那个一次性脚本。