feat: US-004 — /wiki-lint skill (health checks + atomic README regen)
Wave 3 of /delegate execution. /wiki-lint (.claude/skills/wiki-lint/SKILL.md, 525 lines): - Argument interface: [--dry-run]; argument-hint set - Default regenerates wiki/README.md atomically (tmp file + validate non-empty + grep for exact header + atomic rename; on failure exits non-zero and leaves original intact) - --dry-run prints proposed changes without writing - Five distinct check types (NEVER conflated): 1. Stale-90d (updated > 90 days) 2. Deprecated (confidence: deprecated) — REPORTS only, never SETS 3. Orphan (zero inbound [[slug]] refs, two-pass) 4. Broken outbound link (separate from orphans) 5. Contradiction detection (stub — descoped to follow-up) - Uses the canonical frontmatter extraction command from context/rules/wiki.md § 6, byte-identical to /wiki-query (US-003) - Daily log entry per Memory Improvement Protocol Refs #350. Wave 4 (US-005 — AGENTS.md registration) is the final dependency-unblocked story. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
92c879749d
commit
1e6ab78b81
2 files changed
+526
No files matched your search
@@ -0,0 +1,525 @@
|
||||
---
|
||||
name: wiki-lint
|
||||
description: |
|
||||
Manual health-check skill for the wiki corpus. Surfaces five finding types:
|
||||
stale entries (updated > 90 days ago), deprecated entries (confidence:
|
||||
deprecated), orphaned entries (zero inbound [[slug]] references), broken
|
||||
outbound links ([[slug]] references with no matching entry), and a stub for
|
||||
contradiction detection (not yet implemented). Default invocation atomically
|
||||
regenerates wiki/README.md; --dry-run prints proposed changes without writing.
|
||||
Always logs to memory/<today>/log.md per the Memory Improvement Protocol.
|
||||
TRIGGER when: asked to health-check the wiki, "lint the wiki", "regenerate
|
||||
wiki/README.md", "find stale or orphaned wiki entries", or before a release
|
||||
that includes wiki changes.
|
||||
argument-hint: "[--dry-run]"
|
||||
---
|
||||
|
||||
# Wiki Lint
|
||||
|
||||
Health-check the `wiki/` corpus and regenerate `wiki/README.md`. This is
|
||||
Karpathy's "Lint + Maintain" operation adapted for Open Harness: surface
|
||||
stale, deprecated, orphaned, and broken-link entries; regenerate the index
|
||||
atomically.
|
||||
|
||||
The canonical schema, frontmatter extraction command, cross-link convention,
|
||||
and confidence lifecycle all live in `context/rules/wiki.md`. This skill
|
||||
defers to those rules — it does not redefine them.
|
||||
|
||||
## When to Use
|
||||
|
||||
- `/wiki-lint` to regenerate `wiki/README.md` and surface any health findings.
|
||||
- `/wiki-lint --dry-run` to preview what would change without writing.
|
||||
- Periodically (manual cadence — no heartbeat cron in v1) to keep the corpus
|
||||
healthy as entries accumulate.
|
||||
|
||||
## When NOT to Use
|
||||
|
||||
- **`/wiki-ingest`** — to add or update an entry. `/wiki-lint` is read-only
|
||||
except for `wiki/README.md` regeneration.
|
||||
- **`/wiki-query`** — to search for a topic and read entries into context.
|
||||
- **Direct `Edit` tool on `wiki/README.md`** — `/wiki-lint` owns this file;
|
||||
hand-edits will be overwritten on the next run.
|
||||
|
||||
## Argument Interface (locked)
|
||||
|
||||
```
|
||||
/wiki-lint [--dry-run]
|
||||
```
|
||||
|
||||
The argument interface is locked. Do not add flags or positional arguments
|
||||
without editing this SKILL.md.
|
||||
|
||||
- **No arguments**: run all checks, atomically regenerate `wiki/README.md`.
|
||||
- **`--dry-run`**: run all checks, print the proposed `wiki/README.md` content
|
||||
and any findings, but do NOT write `wiki/README.md` or any other file.
|
||||
|
||||
## Instructions
|
||||
|
||||
### 1. Parse arguments
|
||||
|
||||
```bash
|
||||
ARGUMENTS="${ARGUMENTS:-}"
|
||||
DRY_RUN=false
|
||||
if echo "$ARGUMENTS" | grep -q -- '--dry-run'; then
|
||||
DRY_RUN=true
|
||||
fi
|
||||
```
|
||||
|
||||
All subsequent write operations (including the atomic `wiki/README.md`
|
||||
regeneration) are gated on `DRY_RUN=false`. In dry-run mode, print what
|
||||
would be written; never write it.
|
||||
|
||||
### 2. Collect all wiki entry paths
|
||||
|
||||
```bash
|
||||
HARNESS=/home/sandbox/harness
|
||||
WIKI_ENTRIES=()
|
||||
for f in "$HARNESS"/wiki/*.md; do
|
||||
[ -f "$f" ] && WIKI_ENTRIES+=("$f")
|
||||
done
|
||||
ENTRIES_COUNT=${#WIKI_ENTRIES[@]}
|
||||
```
|
||||
|
||||
This enumerates `wiki/*.md` directly — NOT via `wiki/README.md` (the README is
|
||||
the output of this skill, not its input). Sub-article files at
|
||||
`wiki/<parent>/<child>.md` are not matched by this glob; they are scoped for
|
||||
a future iteration.
|
||||
|
||||
If `$ENTRIES_COUNT = 0`, skip all check steps and proceed directly to
|
||||
§ 7 (README regeneration with empty corpus) and § 8 (Memory Protocol).
|
||||
|
||||
### 3. Extract frontmatter for each entry
|
||||
|
||||
For every entry path, extract its YAML frontmatter using the canonical command
|
||||
locked in `context/rules/wiki.md` § 6:
|
||||
|
||||
```bash
|
||||
awk '/^---$/{f=!f; next} f{print}' wiki/<slug>.md
|
||||
```
|
||||
|
||||
Build a lookup table of slug → frontmatter fields:
|
||||
|
||||
```bash
|
||||
declare -A ENTRY_SLUGS # slug → file path
|
||||
declare -A ENTRY_TITLES # slug → title
|
||||
declare -A ENTRY_TAGS # slug → tags string
|
||||
declare -A ENTRY_UPDATED # slug → updated date
|
||||
declare -A ENTRY_CONFIDENCE # slug → confidence value
|
||||
declare -A ENTRY_PATH # slug → full path
|
||||
|
||||
for entry in "${WIKI_ENTRIES[@]}"; do
|
||||
frontmatter=$(awk '/^---$/{f=!f; next} f{print}' "$entry")
|
||||
slug=$(echo "$frontmatter" | grep '^slug:' | awk '{print $2}')
|
||||
title=$(echo "$frontmatter" | grep '^title:' | sed 's/^title: *//' | tr -d '"')
|
||||
tags=$(echo "$frontmatter" | grep '^tags:' | sed 's/^tags: *//')
|
||||
updated=$(echo "$frontmatter" | grep '^updated:' | awk '{print $2}')
|
||||
confidence=$(echo "$frontmatter" | grep '^confidence:' | awk '{print $2}')
|
||||
|
||||
[ -z "$slug" ] && continue # skip malformed entries (no slug)
|
||||
|
||||
ENTRY_SLUGS["$slug"]="$entry"
|
||||
ENTRY_TITLES["$slug"]="$title"
|
||||
ENTRY_TAGS["$slug"]="$tags"
|
||||
ENTRY_UPDATED["$slug"]="$updated"
|
||||
ENTRY_CONFIDENCE["$slug"]="$confidence"
|
||||
ENTRY_PATH["$slug"]="$entry"
|
||||
done
|
||||
```
|
||||
|
||||
This extraction MUST use the exact `awk '/^---$/{f=!f; next} f{print}'` command.
|
||||
Deviation from the § 6 canonical command is forbidden — both `/wiki-query` and
|
||||
`/wiki-lint` must use identical extraction to prevent silent divergence (a match
|
||||
that works in one skill must work in the other).
|
||||
|
||||
### 4. Stale-90d check
|
||||
|
||||
Enumerate entries where frontmatter `updated:` is more than 90 days older than
|
||||
today's UTC date. These are reported as a separate finding type with the
|
||||
recommendation "consider review".
|
||||
|
||||
```bash
|
||||
TODAY=$(date -u +%Y-%m-%d)
|
||||
STALE_90D=()
|
||||
|
||||
for slug in "${!ENTRY_UPDATED[@]}"; do
|
||||
updated="${ENTRY_UPDATED[$slug]}"
|
||||
[ -z "$updated" ] && continue
|
||||
|
||||
# Compute age in days (compatible with GNU date)
|
||||
today_epoch=$(date -u -d "$TODAY" +%s 2>/dev/null \
|
||||
|| date -u -j -f "%Y-%m-%d" "$TODAY" +%s)
|
||||
updated_epoch=$(date -u -d "$updated" +%s 2>/dev/null \
|
||||
|| date -u -j -f "%Y-%m-%d" "$updated" +%s)
|
||||
age_days=$(( (today_epoch - updated_epoch) / 86400 ))
|
||||
|
||||
if [ "$age_days" -gt 90 ]; then
|
||||
STALE_90D+=("$slug (updated: $updated, age: ${age_days}d)")
|
||||
fi
|
||||
done
|
||||
```
|
||||
|
||||
Print findings:
|
||||
|
||||
```
|
||||
=== Stale-90d findings (${#STALE_90D[@]}) — consider review ===
|
||||
```
|
||||
|
||||
For each entry in `STALE_90D`, print one line: ` - <slug> (updated: <date>, age: <N>d)`.
|
||||
|
||||
If `${#STALE_90D[@]} = 0`, print ` (none)`.
|
||||
|
||||
**Important**: this check only REPORTS. `/wiki-lint` does NOT modify the
|
||||
`updated:` field or any other frontmatter field on any entry.
|
||||
|
||||
### 5. Deprecated check
|
||||
|
||||
Enumerate entries where frontmatter `confidence: deprecated`. These are reported
|
||||
as a separate finding type with the recommendation "consider archive or delete".
|
||||
|
||||
```bash
|
||||
DEPRECATED=()
|
||||
|
||||
for slug in "${!ENTRY_CONFIDENCE[@]}"; do
|
||||
if [ "${ENTRY_CONFIDENCE[$slug]}" = "deprecated" ]; then
|
||||
DEPRECATED+=("$slug")
|
||||
fi
|
||||
done
|
||||
```
|
||||
|
||||
Print findings:
|
||||
|
||||
```
|
||||
=== Deprecated findings (${#DEPRECATED[@]}) — consider archive or delete ===
|
||||
```
|
||||
|
||||
For each entry in `DEPRECATED`, print one line: ` - <slug>`.
|
||||
|
||||
If `${#DEPRECATED[@]} = 0`, print ` (none)`.
|
||||
|
||||
**Critical constraint**: `/wiki-lint` ONLY REPORTS deprecated entries — it NEVER
|
||||
autonomously SETS `confidence: deprecated`. The `deprecated` value is set
|
||||
MANUALLY by the orchestrator only, per the lifecycle defined in
|
||||
`context/rules/wiki.md` § 5. This constraint is non-negotiable.
|
||||
|
||||
Stale-90d (§ 4) and Deprecated (§ 5) are always reported separately. They are
|
||||
distinct finding types and MUST NOT be conflated — an entry can be stale-90d
|
||||
and NOT deprecated, or deprecated and NOT stale-90d.
|
||||
|
||||
### 6. Orphan check (two-pass)
|
||||
|
||||
An orphaned entry has zero inbound `[[slug]]` references from any other entry
|
||||
body. A single-entry corpus is always an orphan — this is a **true positive**,
|
||||
not a false positive. The orphan check does not distinguish corpus size.
|
||||
|
||||
#### Pass 1: enumerate all known slugs
|
||||
|
||||
```bash
|
||||
ALL_SLUGS=("${!ENTRY_SLUGS[@]}")
|
||||
```
|
||||
|
||||
This is already populated from § 3.
|
||||
|
||||
#### Pass 2: count inbound references per slug
|
||||
|
||||
```bash
|
||||
declare -A INBOUND_COUNT
|
||||
for slug in "${ALL_SLUGS[@]}"; do
|
||||
INBOUND_COUNT["$slug"]=0
|
||||
done
|
||||
|
||||
for entry in "${WIKI_ENTRIES[@]}"; do
|
||||
entry_slug=$(basename "$entry" .md)
|
||||
|
||||
# Extract body (everything after the closing frontmatter ---)
|
||||
body=$(awk '/^---$/{n++; if(n==2){p=1; next}} p{print}' "$entry")
|
||||
|
||||
# Find all [[slug]] references in this entry's body
|
||||
while IFS= read -r link_slug; do
|
||||
[ -z "$link_slug" ] && continue
|
||||
# Count this as an inbound reference for link_slug (from entry_slug)
|
||||
# Only count if link_slug is different from the entry itself
|
||||
if [ "$link_slug" != "$entry_slug" ] && [ -n "${INBOUND_COUNT[$link_slug]+_}" ]; then
|
||||
INBOUND_COUNT["$link_slug"]=$(( INBOUND_COUNT["$link_slug"] + 1 ))
|
||||
fi
|
||||
done < <(echo "$body" | grep -oE '\[\[[a-z0-9-]+\]\]' | sed 's/\[\[\(.*\)\]\]/\1/')
|
||||
done
|
||||
```
|
||||
|
||||
Build the orphan list (zero inbound references):
|
||||
|
||||
```bash
|
||||
ORPHANS=()
|
||||
for slug in "${ALL_SLUGS[@]}"; do
|
||||
if [ "${INBOUND_COUNT[$slug]}" -eq 0 ]; then
|
||||
ORPHANS+=("$slug")
|
||||
fi
|
||||
done
|
||||
```
|
||||
|
||||
Print findings:
|
||||
|
||||
```
|
||||
=== Orphan findings (${#ORPHANS[@]}) — entries with zero inbound [[links]] ===
|
||||
```
|
||||
|
||||
For each entry in `ORPHANS`, print one line: ` - <slug>`.
|
||||
|
||||
If `${#ORPHANS[@]} = 0`, print ` (none)`.
|
||||
|
||||
**Single-entry corpus note**: a corpus with exactly one entry always produces
|
||||
one orphan (the only entry cannot link to itself). This is a true positive.
|
||||
Document it in the log `Observation` field when it occurs.
|
||||
|
||||
### 7. Broken outbound link check
|
||||
|
||||
A broken outbound link is a `[[slug]]` reference in any entry's body where
|
||||
`slug` does NOT match any existing entry's frontmatter `slug` field. This
|
||||
finding type is separate from orphans — orphans have no INBOUND links; broken
|
||||
outbound links reference slugs that DO NOT EXIST.
|
||||
|
||||
```bash
|
||||
BROKEN_LINKS=()
|
||||
|
||||
for entry in "${WIKI_ENTRIES[@]}"; do
|
||||
entry_slug=$(basename "$entry" .md)
|
||||
body=$(awk '/^---$/{n++; if(n==2){p=1; next}} p{print}' "$entry")
|
||||
|
||||
while IFS= read -r link_slug; do
|
||||
[ -z "$link_slug" ] && continue
|
||||
# Check if link_slug matches any known entry slug
|
||||
if [ -z "${ENTRY_SLUGS[$link_slug]+_}" ]; then
|
||||
BROKEN_LINKS+=("$entry_slug → [[$link_slug]] (no such entry)")
|
||||
fi
|
||||
done < <(echo "$body" | grep -oE '\[\[[a-z0-9-]+\]\]' | sed 's/\[\[\(.*\)\]\]/\1/')
|
||||
done
|
||||
```
|
||||
|
||||
Print findings:
|
||||
|
||||
```
|
||||
=== Broken outbound link findings (${#BROKEN_LINKS[@]}) ===
|
||||
```
|
||||
|
||||
For each finding in `BROKEN_LINKS`, print one line: ` - <source-slug> → [[<missing-slug>]] (no such entry)`.
|
||||
|
||||
If `${#BROKEN_LINKS[@]} = 0`, print ` (none)`.
|
||||
|
||||
See `context/rules/wiki.md` § 4 for the cross-link convention and grep
|
||||
patterns that govern outbound link syntax (`\[\[[a-z0-9-]+\]\]`).
|
||||
|
||||
### 8. Contradiction detection (stub)
|
||||
|
||||
Contradiction detection is explicitly **descoped** for v1. The function prints
|
||||
the following exact text and returns:
|
||||
|
||||
```
|
||||
contradiction detection: not yet implemented — see wiki-lint follow-up tracking
|
||||
```
|
||||
|
||||
A follow-up tracking issue may be filed post-merge but is not a pre-merge
|
||||
blocker. Do not attempt any heuristic approximation of contradiction detection;
|
||||
the stub text above is the complete implementation for v1.
|
||||
|
||||
### 9. README regeneration
|
||||
|
||||
Build the `wiki/README.md` entries table. Sort all entries by `updated:`
|
||||
descending (most recently updated first).
|
||||
|
||||
#### 9a. Sort entries by updated date descending
|
||||
|
||||
```bash
|
||||
SORTED_SLUGS=()
|
||||
RANK_LINES=()
|
||||
for slug in "${!ENTRY_UPDATED[@]}"; do
|
||||
updated="${ENTRY_UPDATED[$slug]:-0000-00-00}"
|
||||
RANK_LINES+=("$updated $slug")
|
||||
done
|
||||
|
||||
while IFS= read -r line; do
|
||||
SORTED_SLUGS+=("${line#* }")
|
||||
done < <(printf '%s\n' "${RANK_LINES[@]}" | sort -r)
|
||||
```
|
||||
|
||||
#### 9b. Build the README content
|
||||
|
||||
The README file is owned and regenerated by `/wiki-lint`. The table header is
|
||||
literal — the exact byte sequence matters for validation.
|
||||
|
||||
```bash
|
||||
# Preserve the static preamble of wiki/README.md (lines before the Index table)
|
||||
# The Index section starts at "## Index"
|
||||
PREAMBLE=$(awk '/^## Index$/{exit} {print}' "$HARNESS/wiki/README.md")
|
||||
|
||||
NEW_README="$PREAMBLE"$'\n'
|
||||
NEW_README+="## Index"$'\n\n'
|
||||
NEW_README+="| Slug | Title | Tags | Updated |"$'\n'
|
||||
NEW_README+="| --- | --- | --- | --- |"$'\n'
|
||||
|
||||
for slug in "${SORTED_SLUGS[@]}"; do
|
||||
title="${ENTRY_TITLES[$slug]:-}"
|
||||
tags="${ENTRY_TAGS[$slug]:-}"
|
||||
updated="${ENTRY_UPDATED[$slug]:-}"
|
||||
NEW_README+="| $slug | $title | $tags | $updated |"$'\n'
|
||||
done
|
||||
```
|
||||
|
||||
**Empty corpus**: if `$ENTRIES_COUNT = 0`, the table contains only the two
|
||||
header lines and no data rows. This is NOT an error condition.
|
||||
|
||||
#### 9c. Atomic write or dry-run
|
||||
|
||||
In `--dry-run` mode, print the proposed content:
|
||||
|
||||
```
|
||||
--- Proposed wiki/README.md (dry-run, not written) ---
|
||||
<content>
|
||||
--- end proposed wiki/README.md ---
|
||||
```
|
||||
|
||||
In default (non-dry-run) mode, perform the **atomic write**:
|
||||
|
||||
```bash
|
||||
TMP="$HARNESS/wiki/README.md.tmp"
|
||||
FINAL="$HARNESS/wiki/README.md"
|
||||
|
||||
# Write to tmp
|
||||
printf '%s' "$NEW_README" > "$TMP"
|
||||
|
||||
# Validate: non-empty AND contains the exact header line
|
||||
if [ ! -s "$TMP" ]; then
|
||||
echo "ERROR: wiki/README.md.tmp is empty — aborting regeneration"
|
||||
rm -f "$TMP"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! grep -qF '| Slug | Title | Tags | Updated |' "$TMP"; then
|
||||
echo "ERROR: wiki/README.md.tmp is missing the required header line — aborting regeneration"
|
||||
rm -f "$TMP"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Atomic rename on validation success
|
||||
mv "$TMP" "$FINAL"
|
||||
echo "wiki/README.md regenerated (${ENTRIES_COUNT} entries)"
|
||||
```
|
||||
|
||||
**Atomic write protocol** (Critic-B mitigation):
|
||||
|
||||
1. Write to `wiki/README.md.tmp` first.
|
||||
2. Validate the tmp file: it must be non-empty AND contain the exact header line
|
||||
`| Slug | Title | Tags | Updated |`.
|
||||
3. On validation success: atomically rename `wiki/README.md.tmp` → `wiki/README.md`.
|
||||
4. On validation failure: exit non-zero, leave the original `wiki/README.md`
|
||||
intact, print the failure reason, and remove the tmp file.
|
||||
|
||||
This protocol ensures that a partial write or generation failure never leaves
|
||||
`wiki/README.md` in a corrupt or empty state.
|
||||
|
||||
### 10. Memory Improvement Protocol
|
||||
|
||||
Always run this step regardless of outcome, dry-run or not. Get the current
|
||||
UTC time first:
|
||||
|
||||
```bash
|
||||
date -u +%H:%M
|
||||
TODAY=$(date -u +%Y-%m-%d)
|
||||
mkdir -p "$HARNESS/memory/$TODAY"
|
||||
```
|
||||
|
||||
Append to `memory/<UTC-date>/log.md`:
|
||||
|
||||
```markdown
|
||||
## /wiki-lint -- HH:MM UTC
|
||||
- **Result**: OP | DRY-RUN | FAIL
|
||||
- **Entries-Scanned**: <count>
|
||||
- **Stale-90d**: <count>
|
||||
- **Deprecated**: <count>
|
||||
- **Orphaned**: <count>
|
||||
- **Broken-Links**: <count>
|
||||
- **Mode**: op | dry-run
|
||||
- **Observation**: <one sentence — key finding or "no findings on a fresh corpus">
|
||||
```
|
||||
|
||||
Field definitions:
|
||||
|
||||
| Field | Content |
|
||||
|-------|---------|
|
||||
| `Entries-Scanned` | Total number of `wiki/*.md` files processed |
|
||||
| `Stale-90d` | Count of entries with `updated:` > 90 days older than today |
|
||||
| `Deprecated` | Count of entries with `confidence: deprecated` |
|
||||
| `Orphaned` | Count of entries with zero inbound `[[links]]` |
|
||||
| `Broken-Links` | Count of `[[slug]]` references with no matching entry |
|
||||
| `Mode` | `op` for a normal run (README regenerated); `dry-run` if `--dry-run` was passed |
|
||||
| `Result` | `OP` on success (including dry-run); `FAIL` if the skill errored out |
|
||||
| `Observation` | One sentence — e.g., "1 orphan (single-entry corpus, true positive); no other findings" |
|
||||
|
||||
Then apply the qualify/improve loop per `context/rules/memory.md` § Write:
|
||||
|
||||
- Did any finding reveal a gap in the wiki schema or cross-link conventions?
|
||||
- Did the atomic write step surface an edge case worth capturing?
|
||||
- If yes, propose a `memory/MEMORY.md` addition.
|
||||
|
||||
See `context/rules/memory.md` for the canonical Memory Improvement Protocol.
|
||||
|
||||
## Extraction Command Reference
|
||||
|
||||
The canonical frontmatter extraction command, per `context/rules/wiki.md` § 6:
|
||||
|
||||
```bash
|
||||
awk '/^---$/{f=!f; next} f{print}' wiki/<slug>.md
|
||||
```
|
||||
|
||||
This MUST be the extraction method used in this skill. Deviation from the § 6
|
||||
command is forbidden — both `/wiki-query` and `/wiki-lint` must use identical
|
||||
extraction to prevent silent divergence (a match that works in one skill must
|
||||
work in the other). Any future change to this extraction method requires
|
||||
updating both skills atomically.
|
||||
|
||||
## Five Check Types — Summary
|
||||
|
||||
| # | Type | Finding trigger | Recommendation | Autonomously sets flag? |
|
||||
|---|------|-----------------|---------------|------------------------|
|
||||
| 1 | Stale-90d | `updated:` > 90 days older than today UTC | consider review | No |
|
||||
| 2 | Deprecated | `confidence: deprecated` | consider archive or delete | No — report only |
|
||||
| 3 | Orphan | zero inbound `[[slug]]` references | (informational; true positive even for single-entry corpus) | No |
|
||||
| 4 | Broken outbound | `[[slug]]` in body where `slug` has no matching entry | (informational; fix by adding the entry or correcting the link) | No |
|
||||
| 5 | Contradiction | descoped | n/a — stub only | n/a |
|
||||
|
||||
These five types are always reported separately. Types 1 and 2 (both related to
|
||||
"staleness" in a loose sense) MUST NOT be conflated — they have distinct triggers
|
||||
and distinct recommendations.
|
||||
|
||||
## Anti-Patterns
|
||||
|
||||
- **Conflating stale-90d with deprecated** — stale-90d triggers on age of `updated:`;
|
||||
deprecated triggers on the value of `confidence:`. An entry may be one, both, or
|
||||
neither. Always report them under separate headings.
|
||||
- **Setting `confidence: deprecated` autonomously** — `/wiki-lint` is a reporter,
|
||||
not a writer. The `deprecated` flag is set MANUALLY by the orchestrator per
|
||||
`context/rules/wiki.md` § 5. If `/wiki-lint` sets this flag, it violates the
|
||||
confidence lifecycle.
|
||||
- **Treating a single-entry orphan as a false positive** — a corpus with one entry
|
||||
always produces one orphan finding. This is correct behavior. Document it in the
|
||||
log Observation.
|
||||
- **Conflating orphans with broken outbound links** — orphans have no INBOUND links
|
||||
(other entries don't reference them); broken outbound links reference slugs that
|
||||
DO NOT EXIST. They are separate checks with different remediation paths.
|
||||
- **Non-atomic README write** — writing directly to `wiki/README.md` without the
|
||||
tmp → validate → rename protocol risks corruption. Always use the three-step
|
||||
atomic write in § 9c.
|
||||
- **Grepping `wiki/README.md` for entries** — the README is the output of this
|
||||
skill, not its input. Always enumerate `wiki/*.md` directly.
|
||||
- **Skipping the log** — every invocation (OP, DRY-RUN, FAIL) appends a log entry.
|
||||
No exceptions.
|
||||
- **Hardcoding today's date** — always compute UTC date at runtime with
|
||||
`date -u +%Y-%m-%d`.
|
||||
|
||||
## See Also
|
||||
|
||||
- `context/rules/wiki.md` — the locked schema, § 4 (cross-link / orphan / broken-link
|
||||
definitions), § 5 (confidence lifecycle: who SETS vs REPORTS), § 6 (frontmatter
|
||||
extraction canonical command)
|
||||
- `/wiki-ingest` — add or update an entry; the only authorized write path to `wiki/`
|
||||
- `/wiki-query` — search the wiki by topic; shares the § 6 extraction command
|
||||
- `context/rules/memory.md` — Memory Improvement Protocol (MIP) governing the log step
|
||||
- `/context-audit` — reference for `--dry-run` flag pattern and atomic-write convention
|
||||
@@ -12,6 +12,7 @@ Update policy and release automation live in [`.claude/rules/git.md`](.claude/ru
|
||||
- `wiki/` directory + `context/rules/wiki.md` schema for Karpathy LLM Wiki pattern ([#351](https://github.com/ryaneggz/open-harness/pull/351)).
|
||||
- `/wiki-ingest` skill (`.claude/skills/wiki-ingest/SKILL.md`) — captures `WebFetch` snapshots and authors/updates wiki entries; supports URL/path ingest + `--from-draft` promotion; orchestrator-only writes; body-merge per `context/rules/wiki.md` § 7 ([#351](https://github.com/ryaneggz/open-harness/pull/351)).
|
||||
- `/wiki-query` skill (`.claude/skills/wiki-query/SKILL.md`) — frontmatter-only grep against `wiki/*.md` (title, slug, tags) using the canonical extraction from `context/rules/wiki.md` § 6; multi-word OR semantics; sub-cap reads all when < 3, top 3 by `updated:` descending otherwise ([#351](https://github.com/ryaneggz/open-harness/pull/351)).
|
||||
- `/wiki-lint` skill (`.claude/skills/wiki-lint/SKILL.md`) — manual health check for the wiki corpus: five finding types (stale-90d, deprecated, orphan, broken outbound link, contradiction-stub-descoped); atomic `wiki/README.md` regeneration with tmp-then-rename + validation; `--dry-run` flag for read-only audits; reports `confidence: deprecated` entries but never autonomously sets the flag (per `context/rules/wiki.md` § 5 lifecycle) ([#351](https://github.com/ryaneggz/open-harness/pull/351)).
|
||||
- `/reflect` skill (`.claude/skills/reflect/SKILL.md`) — deliberate whole-session "Improve" pass that operationalizes the Memory Improvement Protocol (`context/rules/memory.md`): scans the current conversation for durable behavioral patterns, applies the qualify filter, classifies survivors by tier, and proposes `memory/MEMORY.md` / `context/IDENTITY.md` additions for explicit confirmation before writing (log-tier entry always appended). Manual-trigger, current-session scope, propose-then-confirm. Authored via the skill-builder agent for `github:mifunedev/skills` ([#337](https://github.com/ryaneggz/open-harness/issues/337)).
|
||||
- `/caveman` token-compression skill + subcommands (`.claude/skills/caveman{,-commit,-review,-compress,-stats}/`) — output-style mode that compresses agent prose ~65–75% via telegraphic phrasing while preserving code, API names, error strings, security warnings, and irreversible-action confirmations verbatim. Levels: `lite`/`full`/`ultra`/`wenyan`. Vendored adaptation of [JuliusBrussee/caveman](https://github.com/JuliusBrussee/caveman) (MIT, commit `655b7d9`) authored natively to harness skill conventions; upstream `curl | bash` installer intentionally not run. Pinned in `.mifune/skills.lock` as manual/vendored entries ([#335](https://github.com/ryaneggz/open-harness/issues/335)).
|
||||
- `/context-audit` skill (`.claude/skills/context-audit/`) — data-backed, repeatable eval for the default-loaded context budget. Tier-1 scores each file on 4 dimensions (footprint, load-bearing, integrity, redundancy) and emits KEEP/TRIM/DEMOTE/CUT verdicts. Tier-2 ablation harness (`runner.sh` + 7 probe files) removes a target file, runs a fixed task suite via `claude -p`, and measures behavior degradation — the only provably safe gate for cutting load-bearing content ([#333](https://github.com/ryaneggz/open-harness/issues/333)).
|
||||
|
||||
Reference in new issue
Block a user