lint
Periodic wiki health check — orphans, missing links, contradictions, stale (wiki→wiki VÀ code→wiki drift), index gaps. Bước 0 là cổng no-op tất định (wiki-sync, 0 token) — code không đổi kể từ neo thì kết luận "wiki current" và dừng sớm hợp lệ.
How do I install this agent skill?
npx skills add https://github.com/rheinmir/setup --skill lintIs this agent skill safe to install?
- Gen Agent Trust Hubpass
The skill automates wiki and codebase maintenance by executing local shell commands and Python scripts. It audits file consistency, links, and health metrics, but its broad file access and use of interpolated command execution present a minor surface for indirect injection.
- Socketpass
No alerts
- Snykpass
Risk: LOW · No issues
What does this agent skill do?
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
shortcut:; không tự dời draft (đó là/tidy, 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 | llmwiki/wiki/ + neo wiki-sync | có | neo mất → exit 2, làm trọn rồi chốt neo |
| In | harness/scripts/* (hoặc bản global ~/.claude/harness/harness/scripts/) | có | downstream không có harness/ trong repo dùng bản global |
| In | fdk/tools/skill-usage.py | 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 ## YYYY-MM-DD — lint trong llmwiki/wiki/log.md + 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 +
[[wikilink]], 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: wiki-sync.py --check | 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) | phiên · ts · why | 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ấysession+ts. - Bước 2 — VÌ SAO (why của phiên đó):
RUN: grep "<session-id-8-ký-tự>" harness/metrics/scratch-log.jsonl | tail -2. Đínhphiên · ts · whyvà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 (
current): 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 (
drift): các trang nghi stale đã được cờcode-drifttrongstale.jsonkè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
prompts/statements.ts): 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 —
invalid_at: YYYY-MM-DD+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
invalid_at/invalidated_bylà optional, R9 (okf_frontmatter) không chặn khoá lạ — an toàn thêm mà không cần sửa validator.
- 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
- 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
[[wikilinks]]. 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 markershortcut: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ó skills/) → in tổng context load model-invoked + skill nào có cờ: desc (description quá dài) · sprawl (SKILL.md quá dài mà không progressive disclosure) · negation (tỉ lệ câu cấm cao — nên chuyển sang câu khẳng định) · weak-criterion (khối ### Task thiếu điều kiện kiểm được ở cuối) · cặp description chớm-trùng. Tiêu chí gốc ở [[skill-craft]]. 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ó fdk/tools → 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 /tidy (apply dời vào archive/ + 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ó harness/ trong repo thì dùng bản global: python3 ~/.claude/harness/harness/scripts/decision-liveness.py check; repo không có harness/mechanisms.yaml → bỏ qua bước này). In mọi mục có anchor_symbol/live_probe kèm nhãn LIVE/STALE/ORPHAN/UNAVAILABLE — người duyệt phân biệt ORPHAN (cần sửa neo hoặc xoá quyết định qua status: retired, 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 writer_id/topic/ts_utc (UTC tường minh)/git_sha — nguồn "vì sao" THỨ HAI cạnh events.jsonl/scratch-log.jsonl ở 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 [[log-model]]). Dùng làm CLUE bổ sung, không thay thế bước 0b. BÁO CÁO, KHÔNG CHẶN.
-
Append to
llmwiki/wiki/log.md:## YYYY-MM-DD — lintwith 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ờcode-driftđã 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 (drift) | 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ó harness/ hoặc fdk/tools trong repo | dùng bản global ~/.claude/harness/...; không có fdk/tools hoặc harness/mechanisms.yaml → 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 ⇐harness/scripts/tidy.py→ hồ sơ why cho thấy đổi ngưỡng draft → phân loại superseding → thêminvalid_at+invalidated_by, sửa 1 câu → log +--mark-synced. - 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:
DDMMYY-<ten>.md DDMMYY= today (e.g.,020626for 2 June 2026)<ten>= 2–4 kebab-case words summarising what was done (e.g.,landing-page-coteccons,brand-kit-fintech,ingest-auth-spec)
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:
llmwiki/wiki/index.md— append one row:| [DDMMYY-<ten>](sources/draft/DDMMYY-<ten>.md) | draft | YYYY-MM-DD |llmwiki/wiki/log.md— 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
/caveman-stats).
How can the creator link this skill?
Add the canonical catalog link to the repository README so users can inspect current installs and available audits. The publishing guide covers the complete discovery path.
<a href="https://skillzs.dev/skills/rheinmir/setup/lint">View lint on skillZs</a>