agentleFS
anthonymaleyanthonymaley/Kerd/skills/tend/SKILL.md

tend

Skill3 starsChanged 53 days agoMITView on GitHub

Use when the user says 'tend', 'check structure', 'fix drift', 'structural health check', 'set up this project', 'initialize kerd', 'scaffold', or needs to audit or converge repo structure to current Kerd conventions. Works on new repos (full setup) and existing repos (detect drift, fix gaps).

5 other projects use a version of this.

Adopted by

Most recently taken up by

  • Other versions5 projects use a version of this.

    Word for word · 0

    None found.

    Edited · 0

    None found.

    Wrote their own version · 5

    1. juxt/allium★ 506same name
    2. Michaelliv/napkin★ 428same name
    3. jahala/umbel★ 7same name
    4. scottlivingston/claude-skills★ 1same name
    5. rmichaelthomas/tend★ 0same name

    How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.

  • In this repository8 other files it gives its agents.

The file

Show its rules and text

We split this skill into the rules it gives an agent

23 rules. 0 are common, 12 are distinctive, and 11 are very specific to this project.

  • 0

    Common

    Most of the 4 edited versions we read keep these.

  • 12

    Distinctive

    This author's own choices. Worth a look.

  • 11

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Run it on a new repo to set up everything.

    line 16
  2. Very specific:

    Check kivna/vault.json → name field

    line 37
  3. Very specific:

    Check README.md → first # heading

    line 38
  4. Distinctive:

    Only ask for project name and one-line description if this is a brand new repo (no README.md, no CLAUDE.md, no docs/).

    line 41
  5. Distinctive:

    Run each category below. Collect results into three buckets:

    line 45
  6. Distinctive:

    Check required dirs exist:

    line 52
  7. Distinctive:

    Check these files exist:

    line 59
  8. Very specific:

    No banned files: check for files that don't belong in the vault: CLAUDE.md, README.md, TODO.md, Context.md, [Name] Context.md, [Name] …

    line 154
  9. Distinctive:

    Self-identifying filenames: every file in the vault folder (except the MOC) should start with the project or company name.

    line 155
  10. Very specific:

    MOC links resolve: every [[wikilink]] in the MOC should point to a file that exists in the vault folder.

    line 156
  11. Very specific:

    If kivna/vault.json does not exist, the vault is simply not opted in — this is not a finding.

    line 159
  12. Very specific:

    If vault needs full setup, the fix is to run the /kerd:kivna scaffold mechanic (not to reimplement it here.

    line 165
  13. Very specific:

    Check .claude/settings.local.json for hook command strings that reference the Kerd plugin cache (cache/kerd-marketplace/.../hooks/) or a …

    line 217
  14. Distinctive:

    If stale entries are found:

    line 219
  15. Distinctive:

    After the report, outside its code block, put the decision as the question form sets it: the report is the Problem and Facts.

    line 306
  16. Distinctive:

    Create missing directories and files

    line 318
  17. Very specific:

    Run /kerd:kivna scaffold if vault needs setup

    line 319
  18. Distinctive:

    Remove deprecated files (after confirmation for deletions)

    line 320
  19. Very specific:

    Add missing .gitignore entries

    line 321
  20. Distinctive:

    Delete or move stray files as proposed

    line 322
  21. Distinctive:

    "skip" / "no": Do nothing. The report is the value.

    line 327
  22. Distinctive:

    After fixes are applied, print what was changed.

    line 331
  23. Very specific:

    If this is a brand new repo and all structure was just created, suggest: "Structure ready.

    line 333

“Common” is measured: kept by at least 6 in 10 of the 4 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Tend (Structural Health & Convergence)

Asking the person: every question is one speech-bubble line, the last prose line of the message, > 💬 **The question?**, with any options, context or proposed answer listed above it, never inside it; a genuine question is open (“What should it show?”), never “X, or Y?”; a check the person runs, its expected result already written above, asks whether that result happened (“Did the import finish and say how many were saved?”), never an open recall question (“What does the finished line say?”); when options are in hand (open work, known routes, candidates), list them above the question with one recommendation; a question that chooses among them (which work, which route) asks about that recommendation (“Start with the export fix?”), never an open question that ignores the list, while a missing fact, a pick-several choice and Switch In’s fixed arrival question keep their own question; ask with no list only when none are in hand; where the host offers one, a native picker may follow the bubble carrying those same options and always leaving a free-form answer open, never replacing or preceding it — see the question form.

Putting a decision to the person: a consequential question — its answer commits to work, spends real effort, releases or deletes something, or reverses a ruling — comes after a decision block: Problem, Facts (with how we know the problem is real and how strong that evidence is), Known options (or “needs study”), Recommendation, Why, Cost, What we lose, Input (who else checked it, or nobody yet). Its bubble is the Recommendation sentence ending “— approve?”, every operation included, or one genuine question the recommendation depends on; never a smaller or softer question than the real decision, and never without the block. A factual question or a small, easily undone step stays one line — see the question form.

Showing the person: when they ask to see something, and whenever a proposal carries two or more connected parts, a branch, an ownership boundary or a before → after change, the answer carries a saved, rendered view drawn with diagram-design or Archify — never hand-rolled ASCII in a code fence, never an offer question, no quota; only a single action or a factual answer stays text, and being easy to describe in words does not make it one — see showing the work.

Audits repo infrastructure against current Kerd conventions. Shows a visual report of current vs expected state. Fixes with approval.

Run it on a new repo to set up everything. Run it on an existing repo to catch drift. Run it after a Kerd version bump to pick up new conventions. Safe to run anytime. It converges, never destroys.

Usage

/kerd:tend: run in the root of a git repo

Boundary with Slainte

  • tend: structure and plumbing (dirs, vault, config files, naming, stray files, deprecated patterns).
  • slainte: content (doc accuracy, staleness, consistency, CLAUDE.md sections).

The Process

1. Verify git

Confirm .git exists. If not, stop: "No git repo found. Initialize a repo and set up a remote first, then run /kerd:tend again."

2. Infer project identity

Resolve the project name without asking questions:

  1. Check kivna/vault.json → name field
  2. Check README.md → first # heading
  3. Fall back to the directory name, title-cased

Only ask for project name and one-line description if this is a brand new repo (no README.md, no CLAUDE.md, no docs/).

3. Run all checks

Run each category below. Collect results into three buckets:

  • ✓ passing: no action needed
  • ✗ failing: needs creation or structural fix
  • ⚠ warning: needs cleanup or migration

Category 1: Directory structure

Check required dirs exist:

  • kivna/
  • kivna/sessions/
  • docs/

Category 2: Required files

Check these files exist:

  • README.md
  • CLAUDE.md
  • CONTEXT.md
  • TODO.md
  • docs/playbook.md

TODO shape check (drift detection): TODO.md must be lean — ## Now + ## Backlog only. Flag ⚠ if it contains a ## Current Session block, a ### Context section, or any ## Previous/Older Session blocks (pre-split shape, v0.60.0). No automatic healer exists as of v0.107.0 — Switch Out self-migrated these shapes until Switch was replaced. Tend still detects them; the migration is now yours to make. Same for a missing CONTEXT.md when TODO.md exists — flag as pre-split, don't create it here.

For brand new repos (user provided project name), create missing files using these templates:

README.md:

# [Project Name]

[One-line description]

TODO.md:

# TODO

## Now

## Backlog

CONTEXT.md:

# Context

## What This Is
[One paragraph: the project in brief]

## Where We Are
[Current working state]

CLAUDE.md:

# [Project Name]

## Session Workflow

When wrapping up a session (`/kerd:switch out`):
1. Update `TODO.md`: check off completed items, add new ones.
2. Update `docs/playbook.md`: if any new steps, tools, or config were added during the session, add them to the playbook. Always update the "Current Status" section.

## Doc Impact Table

| Doc | Update When |
|-----|-------------|
| README.md | Project description, setup steps, or structure changes |
| docs/playbook.md | New setup steps, integrations, gotchas, tech stack changes, or status changes |
| TODO.md | Every session close-out |

docs/playbook.md:

# Playbook: [Project Name]

How to rebuild this project from scratch.

## Tech Stack
[What tools/frameworks and why they were chosen]

## Setup
[Steps to get the project running locally]

## Architecture
[Key structural decisions and why]

## Integrations
[External services, APIs, config needed]

## Deployment
[How to deploy, environment variables needed]

## Gotchas
[Things that broke, non-obvious behavior, workarounds]

## Current Status
[What's working, what's in progress, what's next]

For existing repos, only report missing files. Don't create them with templates. The user may have a reason for their absence, or may want to create them with project-specific content.

Category 3: Vault integration

Check:

  • kivna/vault.json exists and is valid JSON with vault, folder, name fields
  • The vault folder at the resolved path exists on disk
  • Spine complete: the spine is [Name].md (MOC) + [Name] Status.md + [Name] Weekly.md. Flag any missing spine file. The fix for a missing spine file is /kerd:kivna scaffold (which is idempotent — it fills gaps without clobbering existing files); kivna owns vault writes, tend only detects. (Spine convention: docs/vault-spec.md.)
  • No vault-side session history: flag a sessions/, sessions-of-record/, or similar dated-log folder inside the vault folder. Session history lives in the repo (kivna/sessions/), never in the vault. The fix is to remove it from the vault (the repo is the system of record).
  • No symlinks: scan the vault folder for symlinks pointing to the repo. Each symlink is a violation.
  • No banned files: check for files that don't belong in the vault: CLAUDE.md, README.md, TODO.md, Context.md, [Name] Context.md, [Name] Log.md, Log.md, session export files, any file whose name doesn't start with the project/company name (generic names like Decisions.md, Notes.md)
  • Self-identifying filenames: every file in the vault folder (except the MOC) should start with the project or company name. Flag files that would collide across vaults in Obsidian's quick switcher.
  • MOC links resolve: every [[wikilink]] in the MOC should point to a file that exists in the vault folder.
  • No append-only patterns: flag files with multiple dated ## YYYY-MM-DD section headers (remnants of old pattern). Exempt [Name] Weekly.md — it is the one sanctioned append-style spine file, and its ## Week of YYYY-MM-DD sections are by design.

If kivna/vault.json does not exist, the vault is simply not opted in — this is not a finding. Report one info line, never a ⚠ or ✗ state, and count the category as passing:

ℹ Vault integration: no vault configured — opt-in via /kerd:kivna scaffold when this project wants a knowledge base

If vault needs full setup, the fix is to run the /kerd:kivna scaffold mechanic (not to reimplement it here; kivna owns vault operations).

Category 4: Deprecated patterns

Detect files/dirs from older Kerd versions:

  • kivna/context.md: replaced by vault Status.md in v0.10.0 (was vault Context.md in v0.7.0)
  • kivna/checkpoints/: replaced by vault Status.md in v0.10.0 (was vault Context.md in v0.7.0)
  • kivna/memories/: replaced by vault in v0.7.0
  • commands/: removed in v0.7.0, plugin system loads skills directly
  • .sotu: renamed to .slainte in v0.11.0 (both since removed)
  • .slainte: removed in v0.85.0 — targets derive from the repo; offer deletion
  • skills/shakh/: renamed back to skills/switch/ in v0.14.0
  • skills/seach/: intermediate name, renamed to skills/switch/ in v0.14.0

Category 5: Naming consistency

Scan committed files (not gitignored) for:

  • Mixed case patterns in the same directory (e.g., Setup.md alongside config.md)
  • Inconsistent separators within a directory (kebab-case mixed with snake_case mixed with spaces)
  • Detect the project's dominant naming convention per directory and flag outliers

Skip skills/ (SKILL.md is a Kerd convention), docs/plans/ (dated prefixes are intentional), and vault-native files.

Category 6: Stray & stale files

Scan for:

  • Screenshots (*.png, *.jpg, *.jpeg, *.gif, *.webp) in repo root or committed dirs
  • Temp files (*.tmp, *.log, *.bak, *.swp, *~)
  • .DS_Store anywhere in the repo
  • Files with no git commits touching them in 60+ days that aren't documentation (.md), config (.json, .yaml, .toml), or gitignore. Use git log -1 --format=%at -- <file> to check the most recent commit touching the file.
  • Orphaned files not referenced by any other file in the repo (check with grep for the filename across all files). Only check for files in the repo root (subdirectory files are more likely intentional).

Category 7: .gitignore hygiene

Check:

  • .gitignore exists
  • Contains entries for: kivna/input/, kivna/output/, .DS_Store
  • Untracked files (from git status) that suggest a missing ignore rule: group by pattern and suggest rules

Category 8: Skill hygiene

Scan all skills/*/SKILL.md files and key docs (CLAUDE.md, README.md, docs/playbook.md) for:

  • Missing kerd: prefix: any bare /<skill> slash-command reference that should be its /kerd:<skill> form (/kerd:conductor, /kerd:switch, /kerd:skriv, …). Check inside backtick-quoted commands and prose references. Skip README.md (allowed to use shorthand per CLAUDE.md convention).
  • Stale skill names: references to deprecated skill names (sotu, seach, shakh) in active/instructional context (not CHANGELOG, session logs, or deprecated patterns lists). Each hit is a rename that was missed.
  • Frontmatter drift: the name field in SKILL.md should match its parent directory name. The description field should not reference deprecated skill names.

Category 9: Hook hygiene

Kerd hooks auto-load from the plugin (v0.96.0+). They live in the plugin's own hooks/hooks.json and the harness registers them whenever the Kerd plugin is enabled — the plugin-root variable (CLAUDE_PLUGIN_ROOT) expands correctly there. No per-repo wiring is needed, and none should be added. The session-start and skill-complete hooks are silent unless the repo carries Kerd state (kivna/.active-modes, a kivna/ dir), so they no-op cleanly everywhere else; the context-reading hook (v0.153.0) runs in every project by design, telling the session its token count. This is the standard plugin-hook mechanism; it never version-rots, because there is no cached version path to go stale.

The only job left for tend is migration: find and remove stale manual hook entries left in .claude/settings.local.json by the old (pre-0.96.0) wiring mechanism. Those entries either point at a garbage-collected cache version (dead — Claude Code prunes old versions, see the playbook GC gotcha) or duplicate a hook the plugin now auto-loads (double-fire). Both are fixed by deletion.

Check .claude/settings.local.json for hook command strings that reference the Kerd plugin cache (cache/kerd-marketplace/.../hooks/) or a /hooks/ path that starts with the plugin-root variable written out unexpanded ($ followed by {CLAUDE_PLUGIN_ROOT}; that form never expands in settings and was always inert). Any such entry is stale.

If stale entries are found:

⚠ Hook hygiene — stale manual hook wiring found
  ┌──────────────────┬──────────────────────────────┬──────────┐
  │ Hook             │ Wired path                   │ Proposed │
  ├──────────────────┼──────────────────────────────┼──────────┤
  │ SessionStart     │ .../kerd/0.65.0/hooks/...    │ remove   │
  │ PostToolUse      │ .../kerd/0.65.0/hooks/...    │ remove   │
  │ UserPromptSubmit │ .../kerd/0.65.0/hooks/...    │ remove   │
  └──────────────────┴──────────────────────────────┴──────────┘
  Why: Kerd hooks now auto-load from the plugin (hooks/hooks.json).
       These manual entries are dead (pruned cache version) or
       duplicate the auto-loaded hooks. Removing them restores the
       standard behaviour and prevents double-firing.
  Fix: remove the Kerd hook entries from .claude/settings.local.json
       (leave any non-Kerd hooks and other settings untouched).
  Verify: after removal, the hooks still fire (auto-loaded) — a new
       session in this repo prints the last-session line from
       session-start.sh.

When fixing, read .claude/settings.local.json, remove only the Kerd hook entries (matched by the cache path, a /hooks/ path starting with the unexpanded plugin-root variable ($ followed by {CLAUDE_PLUGIN_ROOT}), or — in the Kerd source repo — a local .../Kerd/hooks/ path), and preserve every non-Kerd hook, permission, and other setting. Do not add replacement entries — the plugin provides them.

Auto-load covers the Kerd source repo too, so it needs no local hook wiring either: a repo that kept local entries and got the plugin's auto-loaded hooks would fire each hook twice. Hook changes under development are validated by tests/hooks_test.sh (which runs the local scripts directly), not by live session behaviour, so nothing is lost by letting live sessions use the cached version.

4. Display report

Format the report as a visual table. Show passing categories as one-liners. Show failing/warning categories with current vs proposed tables and a "Why" explanation.

Evidence tracking for failing/warning findings: the "Why" cell must reference the source of the finding — which check detected it (e.g. "Category 3 vault.json check: missing field name" / "Category 6 staleness scan: file not touched in 60+ days per git log -1 --format=%at -- <path>" / "Category 9: hook path resolves to nonexistent file at <path>"). When proposing fixes in the Proposed column, include the verification step the user can run after the fix lands (e.g. "verify with: cat kivna/vault.json shows the name field; git log -1 -- <path> shows recent activity"). Findings without a source-of-detection are unverifiable; the proposed fix becomes "trust me" rather than reproducible.

┌─────────────────────────────────────────────────┐
│  /kerd:tend: [project-name]                      │
└─────────────────────────────────────────────────┘

✓ Directory structure
  kivna/  kivna/sessions/  docs/

✓ Required files
  README.md  CLAUDE.md  CONTEXT.md  TODO.md  docs/playbook.md

✗ Vault integration
  ┌──────────────────┬───────────────┬─────────────────────────────┐
  │ Item             │ Current       │ Proposed                    │
  ├──────────────────┼───────────────┼─────────────────────────────┤
  │ symlinks         │ 8 found       │ remove all (vault spec      │
  │                  │               │ prohibits repo symlinks)    │
  │ Context.md       │ exists        │ remove (replaced by         │
  │                  │               │ Status.md)                  │
  │ Log.md           │ exists        │ remove (no replacement,     │
  │                  │               │ git log is authoritative)   │
  │ Decisions.md     │ generic name  │ rename to [Project]         │
  │                  │               │ Architecture Decisions.md   │
  └──────────────────┴───────────────┴─────────────────────────────┘
  Why: vault spec requires self-identifying filenames, no symlinks,
       no append-only files. See docs/vault-spec.md.

⚠ Deprecated patterns
  ┌──────────────────┬───────────────┬─────────────────────────────┐
  │ Item             │ Current       │ Proposed                    │
  ├──────────────────┼───────────────┼─────────────────────────────┤
  │ kivna/context.md │ exists        │ remove (replaced by vault   │
  │                  │               │ Status.md)                  │
  │ kivna/checkpoints│ 3 files       │ remove (replaced by vault   │
  │                  │               │ Status.md)                  │
  └──────────────────┴───────────────┴─────────────────────────────┘

⚠ Stray & stale files
  ┌──────────────────┬───────────────┬─────────────────────────────┐
  │ Item             │ Current       │ Proposed                    │
  ├──────────────────┼───────────────┼─────────────────────────────┤
  │ Screenshot*.png  │ 2 files in    │ delete or move to           │
  │                  │ repo root     │ kivna/input/                │
  │ .DS_Store        │ 3 locations   │ add to .gitignore, remove   │
  └──────────────────┴───────────────┴─────────────────────────────┘

✓ Naming consistency
✓ .gitignore hygiene
✓ Skill hygiene

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 4 passing  ·  2 warnings  ·  1 failing
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

After the report, outside its code block, put the decision as the question form sets it: the report is the Problem and Facts; Known options are fix all, pick individually or skip; give the Recommendation (usually fix all) with its Why, the Cost (files touched), What we lose (any local variation the fix overwrites) and Input, then ask, naming the count:

💬 Fix all three findings — approve?

5. Fix flow

"yes" / "fix all": Apply all proposed fixes:

  • Create missing directories and files
  • Run /kerd:kivna scaffold if vault needs setup
  • Remove deprecated files (after confirmation for deletions)
  • Add missing .gitignore entries
  • Delete or move stray files as proposed
  • Stage all changes

"pick" / "pick individually": Show each ✗/⚠ item one at a time. Ask yes/no for each. Apply only approved fixes.

"skip" / "no": Do nothing. The report is the value.

6. Summary

After fixes are applied, print what was changed. Do NOT commit — structural fixes are the user's to review before they land.

If this is a brand new repo and all structure was just created, suggest: "Structure ready. Run /kerd:conductor to start your first session, or /kerd:switch out to commit and push."

No Commit

Tend does NOT commit or push. It makes structural changes and stops. Unlike conductor's work commits — which land behind a verification gate that proves the task did what it claimed — tend's changes are structural convergence with no such gate, so they stay in the working tree for the user to review. The user commits via /kerd:switch out or manually.

Notes

  • Tend is idempotent. Running it twice produces the same result.
  • Tend replaces the old startup skill entirely. It covers both new repo setup and existing repo convergence.
  • For vault operations (scaffold, vault setup), tend delegates to /kerd:kivna scaffold rather than reimplementing vault logic.
  • The vault spec at docs/vault-spec.md defines what belongs in the vault. Tend checks structure against this spec.
  • Category checks are ordered so that earlier categories don't depend on later ones. Directory structure is checked before required files, vault before deprecated patterns.
  • The stale file check (60 days) uses git history, not filesystem mtime. This is intentional: mtime changes when you pull.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.