Skill: lint
WHAT
Purpose và context
- Purpose: Periodic wiki health check — orphans, missing links, contradictions, stale (wiki→wiki VÀ code→wiki drift), index gaps; mở đầu bằng cổng no-op tất định (wiki-sync, 0 token).
- Trigger (when to invoke): After every 10 ingests, or when wiki stale/inconsistent, hoặc session_start báo
[wiki-sync] code đã đổi N commit
.
- Non-goals: không chọn phe khi hai trang mâu thuẫn (flag cho người); không tự đoán trigger nâng cấp cho marker ; không tự dời draft (đó là , có gate người duyệt); không sửa lấy có khi wiki đã current.
Mental model
wiki-sync --check (0 current · 3 drift · 2 chưa neo) → [hồ sơ cờ ⚑: events → scratch-log → provenance-log] → [docs-impact-plan + phân loại drift 4 nhánh] → quét nội-wiki (orphan · link · contradiction · stale · index · empty · Origin) → pulse báo-cáo-không-chặn (shortcut · unknown · skill-health · usage · tidy · claim-receipts · decision-liveness) → log → chốt neo
.
Input và output contract
| Field | Required? | Ý nghĩa |
|---|
| In | + neo wiki-sync | có | neo mất → exit 2, làm trọn rồi chốt neo |
| In | (hoặc bản global ~/.claude/harness/harness/scripts/
) | có | downstream không có harness/ trong repo dùng bản global |
| In | | không | chỉ repo framework; downstream bỏ qua bước đó |
| Out | sửa tại chỗ: missing links, index gaps; trang stale sửa surgical | theo kết quả | truy về một thay-đổi-code cụ thể |
| Out | danh sách flag (contradiction, orphan, empty, Origin thiếu, pulse) | có | chờ người quyết |
| Out | dòng trong + neo mới | có | kể cả khi no-op |
| Out | draft output report | có (trừ khi 0 artifact) | mục Delivery |
Rules và capabilities
- RULE-01 (MUST): Fix automatically: missing links (step 2), index gaps (step 5).
- RULE-02 (MUST): Flag, not resolve: contradictions, orphans, empty pages — need human decision.
- RULE-03 (MUST): Surgical update (distill openwiki 060726): sửa trang stale = thay đúng câu sai, KHÔNG viết lại trang còn đúng; ưu tiên sửa 1 câu hơn thêm 1 đoạn.
- RULE-04 (MUST): Soft diff budget: <5 file code đổi → sửa tối đa 1–2 trang wiki; thấy cần sửa >3 trang → dừng lại tự vấn vì sao trước khi sửa rộng.
- RULE-05 (MUST): Cấm formatting-only edit: không reformat bảng, không chuẩn hoá dòng trống/wording khi nội dung xung quanh không sai — diff nhiễu là nợ cho reviewer.
- RULE-06 (MUST): Canonical home: mỗi concept một trang chính chủ; trang khác chỉ nhắc ngắn + , không nhân bản giải thích.
- RULE-07 (MUST): No-op hợp lệ: "wiki đã current, không sửa gì" là một kết quả lint thành công — ghi log rồi dừng, đừng sửa lấy có.
- Capabilities: đọc wiki + metrics cục bộ; chạy script tất định 0-token; ghi trang wiki (surgical), index, log, neo sync.
Failure boundaries
- Exit 0 và mục đích là "wiki có khớp code không" → dừng sớm, succeeded (no-op hợp lệ).
- Trang nghi stale không truy được về thay đổi code nào → KHÔNG đụng.
- Cần sửa >3 trang cho <5 file code đổi → dừng lại tự vấn trước khi sửa rộng (clarify).
- Contradiction → flag cho người, không tự chọn winner.
- Hồ sơ why rỗng → ghi "hồ sơ mỏng, cần mở diff" thay vì im.
HOW
Main workflow
| Step | Type | Inputs | Action | Outputs/exit | Failure/next |
|---|
| W01 | deterministic | neo wiki-sync | Bước 0: | exit 0 / 3 / 2 | 0 + mục đích khớp-code → dừng; 3 → B01; 2 → B02 |
| W02 | deterministic | file code "⇐" | Bước 0b + 8f: hồ sơ cờ ⚑ (events, scratch-log, provenance-log) | | why rỗng → ghi "hồ sơ mỏng" |
| W03 | deterministic | wiki | Bước 1–7: orphans, missing links, contradictions, stale, index, empty, Origin | sửa 2 và 5, flag phần còn lại | — |
| W04 | deterministic | repo | Bước 8–8f: pulse báo cáo không chặn | danh sách flag | script/đường dẫn không có → bỏ qua bước đó |
| W05 | effect | kết quả | Bước 9: append log | dòng log | — |
| W06 | effect | wiki đã rà | Bước 10: wiki-sync.py --mark-synced
| neo mới | nội dung không đổi → không ghi |
| W07 | effect | kết quả | Output report draft (mục Delivery) | draft + index + log | 0 artifact → skip |
Chi tiết từng bước (nguồn chân lý cho W01–W07):
- Code-drift gate (0 token) —
RUN: python3 harness/scripts/wiki-sync.py --check
(downstream không có harness/ trong repo thì dùng bản global: python3 ~/.claude/harness/harness/scripts/wiki-sync.py --check --root .
).
0b. Hồ sơ cho từng cờ ⚑ (0 token — JOIN bộ nhớ thứ cấp 2 bước, wired 2026-07-18): với MỖI file code mà bước 0 báo "⇐" (nguyên nhân trang nghi stale):
- Bước 1 — PHIÊN NÀO chạm (kho dày, file-level):
RUN: grep "<tên-file>" harness/metrics/events.jsonl | tail -3
→ lấy + .
- Bước 2 — VÌ SAO (why của phiên đó):
RUN: grep "<session-id-8-ký-tự>" harness/metrics/scratch-log.jsonl | tail -2
.
Đính vào cờ khi báo user — cờ-có-hồ-sơ phán trong vài giây (đọc why đủ biết thay đổi có vô hiệu claim không), cờ-trần phải mò diff. Why rỗng/auto-đúc-từ-commit → ghi chú "hồ sơ mỏng, cần mở diff" thay vì im. (Giới hạn thật: scratch-log 1 why/phiên; events dày nhưng chỉ có path — độ giàu why phụ thuộc phiên có ghi tay không.)
- Exit 0 (): code không đổi kể từ neo → nếu mục đích lượt lint này là "wiki có khớp code không" thì dừng tại đây, trả lời "wiki đã current" — no-op là kết quả tốt, đừng bịa việc. Vẫn muốn quét sức khoẻ nội-wiki (orphan/index/origin) thì đi tiếp bước 1.
- Exit 3 (): các trang nghi stale đã được cờ trong kèm file code gây ra. Lập docs-impact-plan TRƯỚC khi sửa: mỗi trang định sửa phải truy về một thay-đổi-code cụ thể (
code đổi → trang → sửa gì → vì sao
); trang không truy được về thay đổi nào thì KHÔNG đụng.
- Phân loại drift trước khi sửa (rubric 4 nhánh, mượn ý temporal-invalidation từ RedPlanetHQ/core, github.com/RedPlanetHQ/core ): claim cũ và thực tế mới quan hệ với nhau kiểu gì?
- contradiction — hai claim không thể cùng đúng (vd "API dùng key X" khi key đã đổi tên) → claim cũ SAI, sửa đè bình thường.
- superseding — claim cũ TỪNG đúng, nay hết hiệu lực vì đổi kiến trúc (vd đổi engine/refactor) → đừng sửa đè câm lặng: thêm 2 trường vào frontmatter của trang — +
invalidated_by: <commit-sha hoặc file gây invalidate>
— rồi mới cập nhật nội dung. Trang vẫn giữ 1 dòng ngắn nói claim cũ từng đúng tới khi nào (đừng xoá lịch sử, chỉ đóng dấu).
- progression — cả hai đều đúng, khác giai đoạn (vd "đang thiết kế X" → "đã ship X") → giữ cả hai, KHÔNG invalidate, chỉ nối thêm claim mới.
- equivalence — cùng nghĩa khác lời (do ingest 2 lần) → coi là trùng lặp, gộp về 1 câu, không phải drift thật.
- Field / là optional, R9 (okf_frontmatter) không chặn khoá lạ — an toàn thêm mà không cần sửa validator.
- Exit 2 (chưa có neo / neo mất hiệu lực): làm trọn lint rồi chốt neo ở bước 10.
-
Orphans —
RUN: grep -rL "wiki/" --include="*.md" llmwiki/wiki/concepts/ llmwiki/wiki/entities/
→ files not referenced anywhere. Flag each.
-
Missing links — scan pages for entity/concept names that exist as wiki files but not written as
. Fix in place.
-
Contradictions — compare claims about same entity across ≤2 pages at a time. Flag pairs (file:line vs file:line). Do NOT pick winner — flag for human review.
-
Stale claims —
RUN: grep -rl "raw/" --include="*.md" llmwiki/wiki/
→ pages referencing raw/. Flag each.
-
Index gaps —
RUN: comm -23 <(find llmwiki/wiki -name "*.md" | sort) <(grep -o "llmwiki/wiki/[^)]*" llmwiki/wiki/index.md | sort)
→ files missing from index. Add rows.
-
Empty pages —
RUN: for f in llmwiki/wiki/**/*.md; do [ $(wc -l < "$f") -lt 5 ] && echo "$f"; done
→ flag for deletion or content.
-
Missing Origin —
RUN: grep -rL "## Origin" llmwiki/wiki/concepts/ llmwiki/wiki/entities/
→ flag each as incomplete.
-
Marker nợ thiếu trigger —
RUN: grep -rn "shortcut:" --include="*.py" --include="*.js" --include="*.ts" --include="*.sh" . | grep -v ",";
→ mỗi marker
cố ý phải có định dạng
<trần hiện tại>, <trigger nâng cấp>
(dấu phẩy tách 2 vế). Dòng lọt qua grep này = marker thiếu trigger nâng cấp (nợ không hạn → dễ thành "never"). Flag từng dòng cho người viết bổ sung trigger; KHÔNG tự đoán trigger.
8c.
Nợ unknown (fill-first, chờ verify — tất định, 0 token) —
RUN: python3 harness/scripts/unknown-ledger.py --list
→ in số unknown mở + cái cũ nhất + SPEC nào nhiều nợ nhất. Đây là các default model điền "để việc chạy tiếp, tính sau" (
(default, find-out-later)
).
BÁO CÁO, KHÔNG CHẶN — fill-first cố ý không chặn; chặn ở đây là phản bội cơ chế. Mục đích: nợ hiện ra để không chìm, người duyệt tự quyết khi nào trả (xem
[[150726-unknown-ledger]]
).
8b.
Skill-health (hình dạng skill, tất định — 0 token) —
RUN: python3 harness/scripts/skill-health.py
(repo có
) → in tổng context load model-invoked + skill nào có cờ:
(description quá dài) ·
(SKILL.md quá dài mà không progressive disclosure) ·
(tỉ lệ câu cấm cao — nên chuyển sang câu khẳng định) ·
(khối
thiếu điều kiện kiểm được ở cuối) · cặp description chớm-trùng. Tiêu chí gốc ở
.
Báo cáo, KHÔNG chặn — chất lượng, không phải an toàn. Flag để người viết cân nhắc, đừng tự sửa hàng loạt.
8b.
Skill-usage pulse (0 token, chỉ repo framework) —
RUN: python3 fdk/tools/skill-usage.py --weekly --no-html
→ bảng tần suất tuần + skill chết (idle ≥4 tuần). Đây là dây nuôi máy đo "skill nào đáng giữ" (wired 2026-07-18, vòng grower): usage tụt/chết là DỮ KIỆN cho quyết định cắt-giữ, không phải cảm tính. Downstream không có
→ bỏ qua bước này.
8c.
Docs-sprawl pulse (0 token) —
RUN: python3 harness/scripts/tidy.py check
→ exit 3 khi draft tầng gốc > 10 → báo user gợi ý chạy
(apply dời vào
+ reindex — có gate người duyệt, tool không tự dời khi lint). Draft/html là RENDER ephemeral; để phình là chôn bản chất dưới rác — vòng đời phải có người quét theo nhịp (wired 2026-07-18).
8d.
Claim-receipts trên draft ACTIVE (0 token) — với mỗi draft KEEP/TREO (không rà đồ sắp archive):
RUN: python3 harness/scripts/claim-receipts.py --check <draft>
→ trích mọi file/path văn bản TRÍCH DẪN, verify còn resolve trên đĩa. Unresolved = bằng chứng tất định
nội-dung-outdated (trỏ tới thứ đã chết/đổi tên) — flag kèm danh sách ref chết, người quyết sửa-hay-archive. Advisory (adapter
claim-receipts.config.yaml
verified:false) — không chặn, chỉ soi (wired 2026-07-18, ca unwired thứ 7).
8e.
Decision-anchoring liveness (0 token, tất định) —
RUN: python3 harness/scripts/decision-liveness.py check
(downstream không có
trong repo thì dùng bản global:
python3 ~/.claude/harness/harness/scripts/decision-liveness.py check
; repo không có
→ bỏ qua bước này). In mọi mục có
/
kèm nhãn
/
/
/
— người duyệt phân biệt ORPHAN (cần sửa neo hoặc xoá quyết định qua
, KHÔNG xoá vật lý) với STALE (cần đọc lại, có thể vẫn đúng) chỉ bằng nhãn, không phải đọc lại toàn bộ nội dung (SC-005).
BÁO CÁO, KHÔNG CHẶN — khớp khuôn không-chặn của draft-age/unknown-ledger (bước 8c).
8f.
Provenance-log lookup (0 token, tất định) — với mỗi file/quyết định bước 0b đang xét "vì sao đổi":
RUN: grep "<tên-file-hoặc-id>" harness/metrics/provenance-log.jsonl | tail -5
(downstream dùng bản global tương tự bước 0). Mỗi dòng khớp mang
/
/
(UTC tường minh)/
— nguồn "vì sao" THỨ HAI cạnh
/
ở bước 0b, khác biệt quan trọng:
git-tracked, đi theo được khi clone sang máy khác (2 nguồn kia hoặc gitignored-local hoặc không tự động toàn diện — xem
). Dùng làm CLUE bổ sung, không thay thế bước 0b.
BÁO CÁO, KHÔNG CHẶN.
-
Append to
:
with issues found/fixed vs flagged.
-
Chốt neo —
RUN: python3 harness/scripts/wiki-sync.py --mark-synced
(hoặc bản global như bước 0). Chỉ ghi khi nội dung wiki thực sự đổi (content-hash); tự xoá cờ
đã rà. Vòng phản hồi phải khép: không chốt neo = lần check sau báo drift giả.
Branches
| ID | Kind | Guard | Hành vi | Skip / failure | Rejoin |
|---|
| B01 | conditional_required | bước 0 exit 3 () | docs-impact-plan + phân loại contradiction / superseding / progression / equivalence trước khi sửa | trang không truy được → không đụng | W03 |
| B02 | conditional_required | bước 0 exit 2 (chưa có neo / neo mất hiệu lực) | làm trọn lint rồi chốt neo ở bước 10 | — | W03 |
| B03 | user_optional | bước 0 exit 0 nhưng vẫn muốn quét sức khoẻ nội-wiki | đi tiếp bước 1 | không muốn → dừng "wiki đã current" | W03 |
| B04 | capability_optional | downstream không có hoặc trong repo | dùng bản global ; không có hoặc → bỏ qua bước đó | — | W04 |
Validation và stopping
Exit code wiki-sync quyết điểm vào (tất định); các pulse 8–8f chỉ báo cáo. Sau lint chốt neo để lần check sau không báo drift giả. Dừng sớm hợp lệ khi exit 0.
Examples
- Positive: session_start báo
[wiki-sync] code đã đổi 3 commit
→ bước 0 exit 3, cờ 1 trang ⇐ → hồ sơ why cho thấy đổi ngưỡng draft → phân loại superseding → thêm + , sửa 1 câu → log + .
- Boundary/failure: bước 0 exit 0 và user chỉ hỏi "wiki có khớp code không" → dừng, trả lời "wiki đã current", ghi log, không sửa trang nào.
Delivery — Output Report
After all main skill tasks complete, write a propose draft to the wiki.
Steps
1. Build the filename:
- Format:
- = today (e.g., for 2 June 2026)
- = 2–4 kebab-case words summarising what was done (e.g., , , )
2. Write llmwiki/wiki/sources/draft/DDMMYY-<ten>.md
:
---
type: draft
title: "DDMMYY-<ten>"
status: proposed
tags: [<skill-name>, output-report]
timestamp: YYYY-MM-DD
---
# DDMMYY-<ten>
**Type:** draft
**Status:** proposed
**Tags:** <skill-name>, output-report
**Proposed:** YYYY-MM-DD
## What
<One sentence — what this skill invocation produced or decided>
## Output
<Key artefacts, files created/modified, or decisions made>
## Files
| File | Action |
|------|--------|
| `path/to/file` | created / modified |
## Notes
- Invoked via: `/<skill-name>` skill
## Origin
- **Draft:** `wiki/sources/draft/DDMMYY-<ten>.md`
- **Commit:** _(filled by verify-before-commit)_
- **Date promoted:** _(filled by verify-before-commit)_
3. Update wiki index & log:
- — append one row:
| [DDMMYY-<ten>](sources/draft/DDMMYY-<ten>.md) | draft | YYYY-MM-DD |
- — append:
## YYYY-MM-DD — <skill-name> — <ten>
Skip only when the skill produces zero artefacts and zero decisions (e.g., a pure display mode like
).