Install
$ agentstack add skill-loremaster-ai-loremaster-refine-wiki ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
raw → wiki refinement
Core principle
Refinement is restructuring, not compression. Preserve the information content; atomize it into searchable, referenceable concept units. The detail needed to answer an SM/PM's concrete question ("what billing model did we settle on yesterday?") must stay alive.
Preconditions (abort on violation)
- Never refine a topic that is open in
conflicts/. Hold it and notify. - The open check targets
conflicts/CONFLICT-*.mdonly. Diff blocks insidePROPOSAL_*.mdmay still contain leftoverStatus openstrings from the past, so exclude them from the gate check. - Where possible, check only the status line's actual current value (
**Status** open); never mistake a diff deletion line (-**Status** open) or proposal text for an open conflict. - Never infer, fill in, or invent content that is not in the raw source. Leave gaps empty and flag them (→ delegate to conflict-detection as an under-specified decision).
- Never create a wiki page without
sources. Untraceable refinement cannot be trusted.
1 concept = 1 page (atomic — no duplicate splits)
Merge the same topic into one page even when it has multiple sources (raw/PRD.md + raw/decisions/*.md). A concept's current spec (PRD) and its decision history (decisions) live on one page. Read raw via the raw/**/*.md glob (never assume fixed filenames). progress is not part of this pipeline (do not read it).
- ❌ Forbidden: creating
Billing Model(PRD version) andBilling Model Premium Switch(decision version) as separate pages. They are the same concept → merge into the singleBilling Modelpage. - Decisions/reversals are absorbed into that concept page's
## Decision Historysection (date/content/rationale/alternatives/reversal status). Never create a separate decision page. - The test: "what is this decision/progress about?" → that concept's page. Before creating a new concept, first check whether
## Decision Historycan absorb it.
Per-doc_type handling (within the 1-concept=1-page rule above)
- prd (
raw/PRD.md): one page per feature/concept, preserving spec detail. Merge that concept's decisions into the same page. - decision (
raw/decisions/*.md— per-backlog decision detail, backlog ID in the filename): - ⚠️ Skip empty skeletons and drafts (not refinement targets). If the frontmatter says
status: draft, or the decision-log table is empty (header + empty rows only, no filled data rows), it is an unfinished skeleton laid down by backlog-kickoff — do not create empty concepts or empty decision histories in the wiki. Exclude it and log only "draft skipped: ". It gets refined once the developer fills the table and pushesstatus: stable. - Process only filled ones (
status: stable, or actual decision rows in the table): never as standalone pages. Write each row of the decision table (date/decision/rationale/alternatives) as one entry (1 row = 1 entry) in the## Decision Historyof the concept page the decision is about; on reversal, preserve the evolution via status + previous-decision markers. (If that concept page does not exist yet, create it then, with the history section inside it.) Record which backlog (file) each entry came from insourcesfor traceability. - gtm: split per strategy axis (target/channel/messaging/metrics) + cross-link related PRD features.
- meeting: extract decisions and actions only; discard chatter. Meeting decisions become decision-entry candidates, proposals only (authority: 1, no automatic adoption).
- spec: keep the technical spec in its original shape + link related PRD features.
Wiki output frontmatter (required)
---
concept: (concept name — the raw docs' own term verbatim, e.g. Billing Model, Free Plan Policy; no slugs)
sources: [source-file.md, ...] # which raw it came from (traceability, required)
authority: (inherit the highest authority among the sources)
last_synced: (YYYY-MM-DD) # team-local date — TZ="$TEAM_TZ" date +%F (set TEAM_TZ to your team's IANA timezone, e.g. America/New_York)
status: active # default; superseded allowed for reversed decision entries
related: [...] # wikilinks — derived from the graphify graph (below)
---
- Concept-name language = source (raw) language. If the team writes raw docs in a language other than English, then
concept:, the graphlabel,[[ ]]links, and the filename must all be that exact same term in that language. - Output path:
wiki/concepts/.md— the filename is the concept name itself (e.g.Billing Model.md).concept:, label,[[ ]], and filename must be identical strings so that (1) the Obsidian page title reads as the team's own term, (2) the[[Billing Model]]link resolves toBilling Model.md(an English slug for a non-English team term breaks every link), and (3)graphify query "Billing Model"matches. Never slugify to English. 1 concept = 1 file.
Wikilinks (graph-derived, one-way — do NOT fill in during refinement)
- Always leave
relatedas[]. Wikilinks are derived not by this skill but by the deterministic script~/.hermes/scripts/loremaster-derive-wikilinks.pyfrom the graphify graph.json. Reason: when an LLM writes links it invents nonexistent documents (a past failure) — links are computed from the graph only, which blocks fabrication. - Derivation rule (script): only the top-N graph edges by weight (N≈3–5) become
[[ ]]. Graph = source of truth; wikilinks = one-way derived view, regenerated on every rebuild. Neither humans nor LLMs write[[ ]]/relatedby hand. - Do not insert arbitrary
[[ ]]into body text either (except obvious directly-quoted references).
Routing & dedup (Karpathy LLM-wiki pattern)
- One raw change touches multiple wiki pages. Do not look at just one file — find every concept page the change affects and update them together (do not stop at one concept).
- After a raw/PRD alignment, the wiki can look "mostly current" while stale sentences remain. Even if graphify plan reports
NOCHANGE, that can just mean the raw change has not reached the wiki yet. First grepwiki/concepts/andwiki/index.mddirectly for retired terms/fields/flows (e.g. a dropped feature term likequest cardand its bare stemquest, renamed fields likepayload.instructionsorquests.avatars, an obsolete unique constraint, a superseded "single-provider signup" rule and its "provider-based signup" phrasing, a retired "auth-scope consistency check" step). Patch current-spec sentences, decision histories, and index one-liners to the settled raw, then run graphify plan/build. - Cross-cutting changes (auth/onboarding and the like) can span 2+ concept pages. E.g. a signup-method change lingers not only in the
Onboardingpage but also inApp Identity & Release Infrastructureand thewiki/index.mdsummaries. Do not stop after updating one concept page — search out and align stale wording across the related concept pages and the index summaries too. - Before creating a new page, grep the existing
wiki/concepts/first (search_files). If the same concept already exists, do not create a new one — strengthen and update that page (1 concept = 1 file, no scattering). Add the new raw file tosources+ refreshlast_synced.
Wiki catalog wiki/index.md (search entry point, must be maintained)
When refinement finishes, update wiki/index.md — every page, by category, with a one-line summary + link. At small scale, Slack Q&A and search enter through this catalog ("Search via index.md at small scale").
- Format: under
##,- [[Concept]] — one-line summary. Add new pages, refresh summaries of changed pages, remove pages that no longer exist. - index.md is a catalog (derived view), so it is exempt from
sources. But every entry listed in it must be a real wiki page (no links to nonexistent pages = no orphans).
After refinement — graphify + wikilinks, automatic (no human approval)
When refinement (concept-page creation) is done, continue immediately, without human approval:
1. Graph build = the session model (you) doing incremental inline semantic extraction → build script. Never use the headless graphify CLI — it requires a separate provider key (Gemini/OpenAI, etc.) and does not work with the agent session's OAuth (and do not build crude fallbacks like SHARES_SOURCE just because keys are missing). graphify's keyless path = "the session model is the LLM", and here you extract directly. But do not re-extract everything every time — use the graphify cache to extract only the changed pages (saves LLM work; equivalent to graphify --update):
- a. Change detection (plan): run
python3 ~/.hermes/scripts/loremaster-graphify-plan.py wiki/concepts. Using a content-hash cache, it sets unchanged pages aside as reused entries ingraphify-out/.graphify_cached.jsonand writes only the pages needing re-extraction tographify-out/.graphify_uncached.txt. (Use--forcefor a full re-refine / cache reset.) - b. Incremental inline semantic extraction: read only the pages listed in
.graphify_uncached.txt, judge the semantic relationships between concepts, and write graphify extraction-spec JSON tographify-out/.graphify_extract.json. Do not re-extract unchanged pages (the cache covers them). If uncached is empty (NOCHANGE), skip extraction and go to c. - Format:
{"nodes":[{"id","label","file_type":"concept","source_file"}], "edges":[{"source","target","relation","confidence":"EXTRACTED|INFERRED","confidence_score","source_file","weight"}], "hyperedges":[], "input_tokens":0, "output_tokens":0} source_filemust be a cwd-relative path in the formwiki/concepts/.md(cache-key match — same representation as plan/build). Never absolute paths or bare filenames.- node
id: lowercase[a-z0-9_]only — a non-ASCII or spaced concept name must become an ASCII slug (e.g.wiki_concept_pricing).labelis the page'sconcept:value verbatim — not the file stem or slug. In wiki Q&A the team asks in its own terms, andgraphify query ""finds the node only if the label is that term. 1 concept = 1 node. relation: real semantic relations only —conceptually_related_to/references/depends_on/supersedesetc.EXTRACTEDwhen there is explicit evidence,INFERREDwhen inferred. Never invent relations (a gap beats an excess). "Cites the same raw file" alone is not an edge — that is not semantics.- When a changed page produces edges toward unchanged pages, those edges are refreshed. But unchanged-page → changed-page edges come from cache and can occasionally be stale — for a large update with big semantic shifts, use
--forcefor a full re-extraction. - c. Build (merge): run
python3 ~/.hermes/scripts/loremaster-graphify-build.py wiki/concepts→ merges the cache reuse (.graphifycached.json) + the new extraction (.graphifyextract.json) over the full current page set intobuild_from_json+ clusters + report +graphify-out/graph.json(no LLM, no keys needed). Deleted pages drop out automatically. New extractions are stored in the cache for reuse on the next refinement. If the graph is empty, stop and report. - d. (Optional) visualization:
graphify export html(deterministic, no keys). graphify-out/is a build product — never delete it. In particulargraphify-out/cache/is the incremental cache; deleting it turns the next refinement into a full re-extraction (gitignored — not a commit target).
2. Wikilink derivation: python3 ~/.hermes/scripts/loremaster-derive-wikilinks.py --graph graphify-out/graph.json --wiki-dir wiki/concepts derives the related [[ ]] links deterministically.
- The wiki is an artifact derived from raw, so it carries no separate human-approval gate (judgment/approval already happened at the raw/conflict stage). Body text from raw evidence only — that is the one thing to uphold.
Last — commit & origin-push approval (automatic)
When refinement, graph, and wikilinks are done, commit the changes (raw/wiki/graphify-out) to git (e.g. Refine wiki from resolved PRD).
- Pre-commit cleanup: the dot-prefixed working files in
graphify-out/(.graphify_extract.json,.graphify_analysis.json,.graphify_detect.json,.graphify_cached.json,.graphify_uncached.txt) are temporary scratch — do not commit them (gitignored, or excluded fromgit add). Commit targets:graphify-out/graph.json,graphify-out/GRAPH_REPORT.md, and thewiki/changes (plus raw when needed). Right after committing, do not wait for a human to say "push" — immediately raise a "Push to origin?" approval button via therequest_approvaltool. titleexample:origin push — (raw + wiki updates).detail: summary of the commits to push (hash + message) and the remote URL.- If APPROVED, run
git push origin main. If DENIED/NO_RESPONSE, do not push (the local commit stays — it can be approved and pushed next time). No retries, no workarounds. - This approval button covers exactly one thing: the external push to the remote (the external-write gate — any write leaving the host requires human approval). The judged/refined content was already approved at the raw/conflict stage, so do not re-approve content (do not raise a second "apply the refinement?" button here).
- The host is the single writer — push works via the SSH deploy key (
core.sshCommand). On auth failure, do not guess or work around; report it as-is.
Isolation
- Read only this project's (channel/lore vault) documents. Never pull in another project's concepts.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: loremaster-ai
- Source: loremaster-ai/loremaster
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.