agentsclimarketplace

Knowledge maintain

Skill voxpelli/vp-claude/skills/knowledge-maintain

Claude Code plugin marketplace + plugin that turns Basic Memory into an actively maintained knowledge graph

Install
npx -y skills add voxpelli/vp-claude --skill knowledge-maintain

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 3 stars3 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

This skill should be used when the user asks to fix, repair, or tidy one or more SPECIFIC named notes — 'fix these notes', 'fix the issues in [note]', 'add the missing relations to [note]', 'tidy up [note]', 'fix orphan [note]', 'apply the gardener findings for [note]'. Applies structural fixes (missing sections, relation-verb drift, frontmatter case) directly and inline, and confirms content-level changes (prose rewrites, merges, archival) with the user before applying them. NOT for read-only auditing (use /knowledge-garden), NOT for creating new notes (use /intel), and NOT for graph-wide or autonomous remediation ('fix the whole audit', 'remediate the graph', research-and-document sweeps) — those belong to the knowledge-maintainer agent, which this skill delegates to when invoked broadly.

SKILL.md

12.6 KB, as published. Nobody here has run it

Knowledge Maintain

Apply targeted fixes to Basic Memory notes — missing sections, relations, structural tidies, archival — with the user confirming changes inline. This is the scoped, interactive sibling of the knowledge-maintainer agent: it owns the common case (repair a few named notes, where being in the main session means the user sees each edit) and delegates heavy, autonomous remediation to the agent.

Write discipline (non-negotiable):

  • edit_note with find_replace ONLY. Never append with section= — it appends to end-of-file, not end-of-section, the documented BM footgun.
  • write_note and delete_note are intentionally excluded. Create new notes via /intel; archive via move_note to archive/.
  • Read the live note before every edit (verify-before-fix). A flagged issue may be a parse artifact, or the note may already be correct.
  • One edit_note per note per message — issue same-note edits sequentially and re-read before re-anchoring after any lands (concurrent same-note edits are a precautionary hazard; see intel's note-write-mechanics.md single-writer rule).
  • schema_validate after every edit. If its output appears to repeat the same value, trust the note body (read_note JSON) as the source of truth rather than inferring a duplication from the validator response alone.

1. Decide venue (scoped inline vs delegate)

Classify the request first:

Delegate to the agent when the work is heavy or autonomous — any of:

  • "Fix the whole audit", "remediate the graph", "fix everything".
  • The fix requires creating notes or running research: "research and document missing packages", anything that would spawn /intel.
  • Brew-note refresh batches, graph-wide orphan linking, or any sweep across a whole ecosystem/type.

To delegate, launch the write agent and stop: call Agent(subagent_type="knowledge-maintainer", description="Graph remediation from audit", prompt="<the user's original request, verbatim; include the gardener report if one is in context>") — i.e. pass a description of "Graph remediation from audit" and a prompt that is the user's original request verbatim, including the gardener report if one is already in context.

If the Agent call fails or returns no usable report (unknown subagent type, error payload, or empty output — the knowledge-maintainer agent may not be installed), say so explicitly and state clearly that no edits were applied — do not fabricate a remediation summary or let the user assume fixes happened. Offer to apply a named scoped subset inline as a fallback.

Run inline (scoped) when the request names a bounded set of notes and a clear set of findings (roughly 1–8 notes). Proceed to step 2. If scope grows mid-task (e.g. a "fix this note" turns into needing a new note), stop and recommend the agent or the relevant intel skill rather than expanding inline.

2. Resolve and load each target

For each named target, resolve it to a canonical note before reading:

  • Plain title (e.g. npm-umzeption) → confirm it exists with read_note directly; if not found, fall back to search_notes.
  • Prefixed identifier (brew:ripgrep) → map the prefix to its directory and locate via list_directory(dir_name="<dir>", file_name_glob="*<name>*").
  • Topic phrase → search_notes(query="<phrase>", page_size=10), take the matching cluster, and present the candidates as the notes to fix (if the match is ambiguous, confirm with the user before editing anything).

Prefix-to-directory mapping (same table /knowledge-garden uses): npm:npm/, crate:crates/, go:go/, composer:composer/, pypi:pypi/, gem:gems/, brew:brew/, cask:casks/, action:actions/, docker:docker/, vscode:vscode/, gh:gh/, plugin:plugins/, skill:plugins/, git:engineering/git/ (git_builtin notes are conventionally plain-titled like git-replay and also resolve via the plain-title path above).

Exclude schema notes (permalinks under /schema/) — they are structural definitions, not subject content.

Once each target resolves, read the live content as the source of truth:

read_note(identifier="<permalink-or-title>", output_format="json")

Confirm the finding still holds against the actual note. If the premise is wrong (the section already exists, the "duplicate" is a stub, the note already ships correctly), STOP and report what was found instead of editing. Derive the exact surrounding text for find_replace from what was read — never assume whitespace or line counts from a third-party report.

3. Classify each fix: auto vs confirm

Auto-fix (apply directly)Confirm first (content-level)
Missing ## Observations / ## Relations headingMerging duplicate notes
Observation section trailing after ## RelationsRewriting prose / observations
Relation verb drift (related_torelates_to)Archiving a note (move_note)
Adding a genuine missing [[wiki-link]] relationChanging a note's meaning or scope
Frontmatter type case / snake_case fixesAnything destructive or hard to reverse

For confirm-first changes, present the exact before/after and wait for the user's response before executing.

When a fix could plausibly fall in either column — especially any edit that alters observation wording rather than purely relocating it — default to confirm-first. The auto-fix column is a positive list; treat anything not clearly in it as confirm-first.

4. Apply the fix

Use edit_note(operation="find_replace") with text anchored on content read in step 2. Typical patterns:

  • Move trailing observations into ## Observations — two find_replaces in strict order: (1) insert first — anchor on the first ## Relations line and prepend the observation lines before it; if this no-matches, STOP (original content is untouched), report, and ask how to proceed. (2) strip second — only after a re-read confirms the lines now appear in ## Observations, strip the stray trailing heading and its now-duplicated lines. Never strip-before- insert: that leaves the note content-less if the insert no-matches.
  • Add a relation — before appending, verify the target exists with read_note(identifier="<exact-target-title-or-permalink>"); if not found, fall back to search_notes(query="<target-title>") for a closer match. read_note is an exact-match lookup and is the only correct primitive for this binary exists/doesn't-exist gate — build_context does fuzzy/related resolution (it can return an unrelated note that merely mentions the target phrase in its own prose as a "related" hit) and must never be used to decide whether a target exists. build_context is only appropriate after existence is confirmed via read_note, to surface additional related/inbound context. If read_note resolves the target directly, anchor on the last existing relation line and append the new relates_to [[target]] line after it. If only the search_notes fallback finds a candidate, that is a fuzzy match, not a resolved target — mirror step 2's Topic-phrase rule and confirm the exact title with the user before appending anything; never auto-write a relation to a fuzzy match. If neither read_note nor search_notes finds anything, do NOT add the relation — report it as an unresolvable target in step 5 instead of silently dropping or silently adding it.
  • Fix a verb — find the exact malformed line, replace with the canonical verb.

Preserve meaning exactly — moves and verb fixes are not rewrites. When dropping a heading would lose date/provenance context, fold a brief inline marker (e.g. (Sprint 20)) onto the moved lines rather than discarding it. For any multi-step fix (especially the insert-then-strip move), proceed to step 5's count assertion before considering the note done.

5. Validate and report

After each note's edits, run schema_validate(identifier="<note>") (validate the single edited note via identifier, not the whole note_type batch).

Confirm content survived, not just that it validates. For any multi-step edit (e.g. the insert-then-strip move): record N_before = observation count from the step-2 JSON read, then after all find_replaces re-read via read_note(output_format="json") and compare N_after. schema_validate passing with N_after < N_before is the exact data-loss signature — a note that silently lost observations still validates cleanly. N_after == N_before (or higher, if observations were intentionally added) is the passing gate. If a multi-step edit landed only partially, the note is in a damaged/partial state: report it explicitly and restore the removed content before continuing.

If error_count is not 0, do NOT report the fix as complete. Determine whether your edit caused it or merely revealed a pre-existing issue (the edit_note re-parse gotcha), surface the exact errors, state that the note is currently schema-invalid, and either correct it or flag it prominently — never close out a maintain pass with an unresolved non-zero error count framed as success.

Then report per note:

  • The before/after of what changed.
  • The find_replace operations run.
  • The post-edit validation result.
  • Anything left out of scope (e.g. a schema question deferred to /schema-evolve, a content change the user declined, or a relation whose target didn't resolve via read_note/search_notes).

Edge Cases

  • Unresolvable relation target — a proposed relates_to [[target]] whose target doesn't resolve via read_note/search_notes is never added and never silently dropped: report it as an unresolvable target and suggest /intel if it looks like an undocumented package/tool, or ask the user to confirm the correct title.
  • edit_note re-parse gotchaedit_note re-parses the ENTIRE note after a raw string replacement, so a pre-existing unrelated issue can trip on your edit. Report it; do not expand scope to fix unrelated problems.
  • Duplicate-frontmatter trap — never let a find_replace cross a --- frontmatter boundary on a schema note; it can create a duplicate frontmatter block. Keep find/replace inside the body or inside the YAML block, never spanning the markers.
  • No-match on find_replace — re-read the note, adjust the anchor once, then report to the user if it still fails. Do not loop.
  • Schema-level finding — unmatched observation categories across a type are a /schema-evolve question, not a note edit. Leave the note untouched.
  • BM write error — the PostToolUseFailure hook classifies edit_note/ move_note errors and emits recovery guidance; follow it.
  • Mid-batch failure — if a write fails for one note in a multi-note pass, stop that note's fix sequence, continue the rest, and report which notes were fully fixed, which were partial, and which were not reached. Never summarize a truncated batch as complete.

Guidelines

  • Venue first — classify scoped vs heavy before touching anything.
  • Verify before fixing — read the live note; confirm the premise.
  • find_replace only — never append+section.
  • Confirm content changes — auto-fix structure; ask before prose/merge/archive.
  • Validate after every editschema_validate, expect 0 errors.
  • Stay in lane — no new notes (use intel skills), no deletes (use move_note to archive/), no graph-wide sweeps (delegate to the agent).

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.