* fix(cache): lock and atomically write .manifest.json
update_source was a plain read-modify-write with no mutual exclusion, so
any two overlapping writers lost an entry silently: the second reader's
snapshot predated the first writer's write. This fires in three real
configurations — batch-plan fan-out dispatching parallel ingest subagents,
the Dockerized server writing a vault a local skill is also using, and a
scheduled daily-update overlapping an interactive session.
Reproduced with 12 concurrent update_source processes against one vault:
6 of 12 entries recorded before, 12 of 12 after.
Writes now take an advisory lockfile and replace the manifest atomically
via a temp file plus os.replace. O_CREAT|O_EXCL rather than fcntl because
this ships on Windows. Hashing stays outside the lock — it can take
seconds on a large source tree and nothing in the manifest depends on it.
The contention test spawns real subprocesses; a single-process test
cannot observe this race.
* feat(trust): flag illegal lifecycle transitions in lint
The lifecycle field is a state machine, but nothing enforced its edges.
Ledger entries now record the lifecycle at review time, giving lint a
baseline to compare the current frontmatter against.
Only edges that are illegal for every possible sequence of unobserved
intermediate states are flagged: falling back to draft (only ingest sets
draft) and exiting archived (terminal). draft -> verified is deliberately
not flagged — ledger snapshots are sparse, so a legitimate intermediate
reviewed may simply never have been recorded, and flagging that pair
would fire on valid history.
Additive: entries predating the lifecycle field carry no baseline and are
skipped, so existing vaults behave identically until their next
trust-record. Owner-extended lifecycle states never match the illegal
pairs, so the check degrades to a no-op rather than firing on states it
does not understand. Warns by default, fails under --strict-trust,
matching how the surrounding trust checks were already staged.
* feat(wiki-status): add vault equilibrium mode
The maintenance skills each optimize one shared vault for a different
objective, so any of them can undo another's work and no single skill
reporting clean means maintenance is done.
Equilibrium mode runs every maintenance audit in report-only form and
reports whether any skill still has a pending change. The vault is
converged only when all of them propose nothing.
It also detects oscillation via a snapshot in _insights.md, alongside the
existing GRAPH_SNAPSHOT: a skill whose pending count keeps returning
after being driven to zero is being reversed by another skill, and the
vault can never settle. Reported, never auto-fixed — resolving it is a
decision about whose objective wins.
Pending moves are attributed back to their manifest source, so a source
that repeatedly produces pages needing repair surfaces as a suggestion to
review its source_quality. Report-only; the owner still decides through
the existing trust flow.
Skill-only, no Python: lint already emits JSON counts and the other three
audits are LLM passes.
* docs: document manifest write safety, lifecycle checks, and equilibrium
Covers the advisory lock and atomic manifest write (including the
parallel-run contract), the illegal_lifecycle_transitions check and why
draft -> verified is excluded, and equilibrium mode in the architecture
feature list.
* feat(config): resolve global config from an XDG-style location (#172)
The global config lived at ~/.obsidian-wiki, which isn't XDG-compliant.
It now resolves to $XDG_CONFIG_HOME/obsidian-wiki (default
~/.config/obsidian-wiki).
Existing installs are unaffected: if ~/.obsidian-wiki is present and the
XDG path is not, the legacy directory is used as-is. No migration is
required, and nothing moves on upgrade. Once the XDG path exists it wins,
so `mv ~/.obsidian-wiki ~/.config/obsidian-wiki` is all a migration takes.
Resolution is implemented identically in Python (cli.py), bash (setup.sh,
scripts/daily-update.sh, scripts/wiki-notify.sh), and the Config
Resolution Protocol that every skill defers to, so vault-scoped state and
named `config.<name>` profiles stay in one place.
* fix(config): stop setup from wiping user-added config keys
`write_config` rewrote the global config with only the three setup-managed
keys, so every `obsidian-wiki setup` — including the one a pip upgrade
prompts for — silently destroyed anything else in the file:
OBSIDIAN_LINK_FORMAT, QMD_WIKI_COLLECTION, WIKI_SKIP_PROJECTS, sync
settings, and comments.
Setup now owns only OBSIDIAN_VAULT_PATH, OBSIDIAN_WIKI_REPO and
OBSIDIAN_WIKI_VERSION, updating those in place and carrying every other
line over untouched. Duplicate definitions of a managed key collapse to
one.
Predates the XDG change (same behavior on main) but is fixed here because
this branch already touches config writing, and the XDG work makes
re-running setup more likely.
Also pins PYTHONPATH in both new test files so they exercise this
checkout rather than whatever obsidian_wiki happens to be installed.
Two strands of work.
Session brain — a topic graph over raw agent session history, so you can
find the session where something happened instead of remembering its
UUID. Reads every Claude transcript plus the pruned sessions that survive
only as prompts in history.jsonl, clusters them with local TF-IDF and
community detection (no embeddings, no API calls, no new dependencies),
and writes a sidecar at ~/.claude/session-brain/ — the vault is never
touched. Ships five modules, the sessions-* CLI commands, an interactive
graph.html, and the /session-brain and /wiki-sessions skills. This is
retrieval, deliberately distinct from wiki-history-ingest, which distils
sessions into permanent vault pages.
Docs — README.md was 598 lines and put trust-check flags and a 17-row
agent matrix in front of anyone evaluating the project. Cut it to a 129-
line landing page (problem statement, 60-second install, four blocks of
runnable commands, graph screenshot, why-not-a-notes-folder) and move the
reference material into docs/: installation, agents, skills, cli,
configuration, architecture, session-brain, contributing. README_TW.md
mirrors the new structure; docs/ stays English-only for now.
The restructure also closed real drift:
- Ten skills existed but appeared in no reference — session-brain,
session-search, wiki-dedup, wiki-digest, wiki-import, wiki-context-pack,
wiki-stage-commit, wiki-switch, vault-skill-factory, and
obsidian-layout-adjustment.
- SETUP.md listed 12 of 39 skills and still claimed "no scripts, no
dependencies" despite the pip package. It is now a signpost into docs/.
- Eight config variables were undocumented anywhere, including
WIKI_STAGED_WRITES, which wiki-setup prompts for and three skills read.
Added to .env.example and docs/configuration.md.
- sessions-name and a number of CLI flags were missing from the docs.
Two details worth noting. README links are absolute GitHub URLs because
pyproject sets readme = "README.md" as the PyPI long_description, and PyPI
resolves relative hrefs against pypi.org rather than the repo — docs/
links would have 404'd on the package page. And three doc-drift guards
asserted their facts against README.md; since those facts moved rather
than disappeared, the assertions were repointed at the page that now owns
each one instead of padding content back into the README.
Also gitignore /vault/ (a local knowledge vault, not a fixture) and the
packed browser extension.
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
The readme-sync workflow no longer fails when README.md and
README_TW.md don't change together. Instead, check_readme_sync.py
reports drift: it lists commits that touched README.md after the
last README_TW.md update, plus the pending English diff to translate
and backfill. CI surfaces drift as a warning annotation only.
Claude-Session: https://claude.ai/code/session_01PG9Pz6tcUfgpTHLjq3BT5Q
wiki-narrate saves derived readouts to _readouts/, but cross-linker,
wiki-export, and wiki-lint scanned every .md in the vault and would
have linked, exported, or lint-flagged them. Exclude the directory in
all three and document it in the AGENTS.md vault structure.
Add lossless OKF v0.1 round-trip to wiki-export and wiki-import. OKF
(Google's knowledge-catalog) is a vendor-neutral spec for knowledge as
markdown + YAML frontmatter — structurally near-identical to this vault.
- wiki-export: new "OKF bundle" output mode (wiki-export/okf/), the
canonical frontmatter mapping (category/summary/sources/updated ⇄
type/description/resource/timestamp), [[wikilink]]→file-relative
markdown link transform, per-folder index.md generation, okf_version.
- wiki-import: source-type detection (graph.json vs OKF dir) + Step 4-OKF
that reconstructs full pages (not stubs) via reverse mapping.
- AGENTS.md: routing triggers + OKF-conformance architecture note.
Native frontmatter keys ride along as OKF extension frontmatter, making
the round-trip lossless — unlike the stub-only graph.json round-trip.
Forward-references (wikilinks to not-yet-written pages) are preserved as
links per OKF §5.3 rather than dropped to plain text.
Verified on st3ve (46-page vault): 46/46 exported, 0 OKF §9 conformance
issues, 25/25 frontmatter lossless, 46/46 body/link-graph lossless.
Implements the proposal from issue #96. Turns a cluster of mature, curated
Obsidian wiki pages into a portable Agent Skill (SKILL.md + references/),
the inverse of wiki-capture.
- .skills/vault-skill-factory/SKILL.md: new skill with hard guardrails
(never writes to .skills/, never auto-installs), QMD-based cluster
discovery, maturity filtering, and provenance manifest.
- .env.example: SKILL_FACTORY_OUTPUT_DIR and SKILL_FACTORY_MATURITY keys.
- AGENTS.md: routing row for /vault-skill-factory and related phrasings.
Closes#96
Continues the skill-surface consolidation (#84). Removes three skills
whose capability fully overlaps a survivor, so users and the router stop
disambiguating near-duplicates. No functionality lost.
- obsidian-wiki-ingest: a self-described "wrapper for wiki-ingest" that
never did anything wiki-ingest doesn't. Deleted outright.
- wiki-quick-chat-capture -> wiki-capture --quick: quick mode folded in
as a documented fast path (gate, _raw/ staging, <60s, no manifest
writes). RAW-FORMAT.md moved to wiki-capture/references/. The
session-end Stop hook now asks for `/wiki-capture --quick`.
- ingest-url -> wiki-ingest: URL ingestion folded in. The full URL
mechanics (project detection, defuddle, dedup, slug, project/misc
frontmatter, affinity scoring, stub handling, INGEST_URL log) moved
verbatim to wiki-ingest/references/url-sources.md, pointed to from a
new "Web URL sources" section.
Repointed every reference: AGENTS.md (+CLAUDE.md symlink), README,
wiki-setup, wiki-query, llm-wiki, RAW-FORMAT.md.
data-ingest was effectively wiki-ingest plus a format-detection
preamble — its own process step said "Follow the wiki-ingest skill's
process for creating/updating pages". The split forced users and the
skill router to disambiguate two overlapping ingest skills (a .md
ChatGPT export fit either one).
Fold it in to keep the skill surface small:
- wiki-ingest now handles structured docs AND raw/unstructured text
(chat exports, Slack/Discord JSON, CSV/JSON, transcripts, logs).
- Added an "Unstructured & conversational sources" section to Step 1
with format detection, chat-export shapes, and "distill substance,
not dialogue" guidance carried over from data-ingest.
- Expanded the description to absorb data-ingest's triggers.
- Removed .skills/data-ingest/ and repointed every reference
(CLAUDE.md/AGENTS.md, README, SETUP, llm-wiki, wiki-status,
wiki-rebuild, wiki-quick-chat-capture, and the mirror rule files
for cursor/windsurf/agent/kiro/copilot).
Pairs with wiki-export: takes a graph.json snapshot and rebuilds page stubs
in the target vault with correct frontmatter, wikilinks, and typed relationships.
Supports skip/overwrite/merge conflict modes and updates all vault metadata files.
* feat(skill): add wiki-quick-chat-capture for zero-friction mid-session finding capture
Implements the skill proposed in issue #69. Extracts reusable technical findings
(bugs, gotchas, API quirks) from the current conversation and stages them as
structured _raw/ files in under 60 seconds — no subagents, no QMD, no manifest
writes. Full promotion to wiki pages happens later via /wiki-ingest or /data-ingest.
* refactor(wiki-quick-chat-capture): add agentskills.io frontmatter, RAW-FORMAT reference, OBSIDIAN_RAW_DIR support
- Add compatibility, metadata, and allowed-tools frontmatter fields for cross-agent portability
- Extract body format spec and provenance/confidence calibration table to references/RAW-FORMAT.md
(keeps SKILL.md under 500 lines; details loaded on demand)
- Support OBSIDIAN_RAW_DIR config key so _raw/ can live outside the vault root
- Trim inline format docs from SKILL.md now that they live in the reference file
Incorporates feedback from @BenRoe in PR #70 comment.
Thanks for the well-structured PR — mirrors the existing `claude-history-ingest` / `codex-history-ingest` pattern cleanly and the Pi session-format details (tree JSONL with id/parentId, message roles, compaction/branch_summary) line up with pi.dev.
Reviewed:
- New `pi-history-ingest` skill, routing across `wiki-history-ingest`, `wiki-agent` (`/wiki-pi`), and `memory-bridge`
- `setup.sh`, `.env.example`, `AGENTS.md`, `README.md`, `SETUP.md`, and all four IDE rule files updated consistently
- 38 committed symlinks under `.pi/skills/` + 5 cross-agent symlinks
One small follow-up: the SKILL.md cites `references/pi-data-format.md` but the file isn't shipped (the claude/codex skills both ship that companion reference). I'll add it in a follow-up so the family stays consistent.
* feat: add wiki-dedup skill — identity resolution and page-level deduplication (closes#44)
* fix: correct scoring weights and YAML block scalar title parsing in wiki-dedup
st3ve testing found two bugs:
- Scoring cap of 0.50 was too tight — obvious duplicates like 'Fine-tuning LLMs' vs
'LLM Fine-tuning' scored 0.70 (LOW) instead of MEDIUM. Raised title score cap to 0.65,
tag overlap 3+ bonus to 0.15, giving real duplicate pairs MEDIUM (0.75+) scores.
- YAML block scalar titles (title: >-) were parsed as the literal string '>-', causing
false-positive matches between unrelated pages. Added extraction note covering >-, >, |, |-.
New skill that produces a human-readable digest of what was learned,
updated, and connected in the wiki over a configurable period (day /
week / month). Triggered by "/wiki-digest", "what did I learn this
week", "weekly summary", etc.
What it does:
- Collects pages active in the period by created/updated frontmatter
- Identifies top themes from tags, flagging new vocabulary
- Surfaces notable cross-category wikilinks formed this period, ranked
by interestingness (hub proximity, inferred claims, cross-domain score)
- Reports open threads: drafts, ^[ambiguous] claims, _raw/ files, taxonomy gaps
- Recommends pre-period pages worth revisiting given new connections
- Generates a structured digest with Headlines, New Knowledge, Themes,
Connections, Open Threads, and Re-reads sections
- Optionally saves to journal/digest-YYYY-MM-DD.md and logs to log.md
- Respects visibility/ tags (omits pii pages from output unless asked)
Distinct from wiki-status (which reports *source* ingestion delta) —
wiki-digest summarizes *knowledge*, not pending sources.
Changes:
- .skills/wiki-digest/SKILL.md — full skill instructions
- Symlinks in all 5 mirror dirs (.agents, .claude, .cursor, .windsurf, .kiro)
- AGENTS.md routing table updated with trigger phrases
Adds a new skill that lets users switch between named Obsidian vault
profiles via ~/.obsidian-wiki/config.NAME symlinks. Supports list,
show, switch, and new-vault-scaffold operations.
Introduces /wiki-claude, /wiki-codex, /wiki-hermes, /wiki-openclaw,
/wiki-copilot commands. Unlike wiki-history-ingest (bulk), this does
query-driven targeted search: find sessions about a specific topic in
one agent's raw history, extract the relevant blob using per-agent
extraction strategies, ingest into wiki, and return a synthesized answer
immediately usable in the current session.
Primary use case: you're on agent A, want to pull in how you solved X
in agent B's history, without ingesting all of B's sessions.
Registered across all 5 tool dirs (.claude, .kiro, .agents, .cursor, .windsurf).
- memory-bridge: browse wiki by source tool; diff mode surfaces knowledge
blind spots between AI tools (Claude vs Codex vs Hermes etc.)
- impl-validator: quality-checking subagent spawned by other skills to
verify output correctness before presenting to the user
- daily-update: daily maintenance cycle (freshness check, index reconcile,
hot.md refresh) with launchd cron and zshrc terminal notification
- scripts/: daily-update.sh, wiki-notify.sh, launchd plist
All three skills registered across .claude, .kiro, .agents, .cursor, .windsurf.
source_type mappings verified against actual manifest specs in each history-ingest skill.
Adds a new `OBSIDIAN_LINK_FORMAT` config variable (default: `wikilink`)
that lets users opt into standard relative Markdown links instead of
Obsidian `[[wikilinks]]` for all newly generated or updated pages.
Closes#26
Add a single universal rule in AGENTS.md telling agents to read
$OBSIDIAN_VAULT_PATH/AGENTS.md after config — covers all skills
automatically without per-skill changes. The vault AGENTS.md
carries owner-specific conventions (domain vocabulary, ingest
preferences, writing style, project scoping) that should override
framework defaults for the session.
Mirrors this repo's own AGENTS.md/CLAUDE.md pattern so the same
file works for any agent (Claude Code, Codex, Cursor, etc.).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- wiki-capture: save any conversation as a permanent wiki note; classifies into 5
types (synthesis/concept/source/decision/session) and rewrites content as
declarative knowledge rather than a chat transcript
- wiki-research: autonomous 3-round web research loop that decomposes topics,
fills gaps, resolves contradictions, and self-files into sources/concepts/
entities/synthesis
- wiki-dashboard: creates Obsidian Bases .base files (native, no plugin needed)
for dynamic queryable views — tables, cards, lists filtered from vault frontmatter
- hot.md session cache: ~500-word semantic snapshot of recent activity; all write
skills (wiki-ingest, wiki-update, ingest-url, data-ingest) now update it at the
end of each run; wiki-query reads it first for cheap context
- ingest-url: preflight check for defuddle CLI — uses it for cleaner URL extraction
when available (~40-60% token reduction on articles), falls back to WebFetch
- Routing table in AGENTS.md updated; symlinks created across all 5 platforms
Rewrites .obsidian/graph.json colorGroups from the vault's real vocabulary.
Backs up the existing file and only touches colorGroups so user zoom/physics/filter
prefs stay intact. Modes: by-tag (default), by-category, by-visibility, combined, custom.
- New skill: ingest-url fetches any URL via WebFetch, distills content into
misc/<slug>.md, computes initial project affinity from wikilinks, and
surfaces promotion candidates when a project score reaches 3+
- cross-linker: new Step 5 rescores affinity for all misc/ pages after the
main linking pass and reports promotion candidates in the Cross-Link Report
- wiki-lint: new check #10 flags misc/ pages with affinity >= 3 in the
health report; log line gets promotion_candidates= field
- Skill routing: AGENTS.md updated with /ingest-url trigger phrases
- Platform parity: ingest-url symlink deployed to .agents, .claude, .cursor,
.windsurf, .kiro
Replaces the copied bootstrap file with a symlink so there is a single
source of truth. Also adds the hermes routing entries to AGENTS.md so all
AGENTS.md-aware agents (Codex, OpenClaw, etc.) can trigger hermes-history-ingest.
setup.sh now recreates the symlink on every run so fresh clones stay consistent.
Introduces optional visibility/ tags (visibility/public, visibility/internal,
visibility/pii) that let users mark pages as team-only or sensitive without
splitting the vault. Default behavior is unchanged — all pages visible unless
filtered mode is explicitly requested in a query or export.
README: add `npx skills add Ar9av/obsidian-wiki` as the primary install
method with a link to skills.sh listing. Simplify kepano companion
install to use the same CLI.
AGENTS.md: rewrite for agents arriving from other projects — add vault
structure tree, cross-project workflow (wiki-update/wiki-query), global
config as primary config source, simplified skill routing table, and
merged core principles.
OpenClaw discovers skills from ~/.agents/skills/ (per docs.openclaw.ai/skills)
and reads AGENTS.md for project-level instructions. Both paths are now wired
into the framework:
- setup.sh adds a new global symlink step that mirrors all skills into
~/.agents/skills/, and normalizes ln -s to drop the trailing slash so
re-runs don't churn the per-agent symlink directories.
- AGENTS.md (and CLAUDE.md by mirror) document the new skill discovery paths.
- README adds an OpenClaw row to the agent compatibility table, a manual-setup
collapsible, the new global symlink in the project structure tree, and a
fifth bullet under "Using from other projects".
- Per-agent symlink directories (.claude/.cursor/.windsurf/.agents) get the
new wiki-update entry that was missing, and existing entries normalize to
the no-trailing-slash form.