diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index e31c737..d8e1a38 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -5,7 +5,7 @@ "description": "Obsidian vault automation for Claude Code. Save conversations, compile sources into a living wiki, audit the graph, challenge your own thinking. Amalgamation of Karpathy's LLM Wiki + Jens + eugeniu + AgriciDaniel + NicholasSpisak, hardened for operator vaults with live sync.", "author": { "name": "fidgetcoding", - "email": "operator@example.com", + "email": "nate@lorecraft.io", "url": "https://github.com/fidgetcoding" }, "license": "MIT", @@ -39,9 +39,9 @@ ] }, "scheduled": [ - {"name": "morning", "plist": "scheduled/launchd/io..mogging.morning.plist"}, - {"name": "nightly", "plist": "scheduled/launchd/io..mogging.nightly.plist"}, - {"name": "weekly", "plist": "scheduled/launchd/io..mogging.weekly.plist"}, - {"name": "health", "plist": "scheduled/launchd/io..mogging.health.plist"} + {"name": "morning", "plist": "scheduled/launchd/io.lorecraft.mogging.morning.plist"}, + {"name": "nightly", "plist": "scheduled/launchd/io.lorecraft.mogging.nightly.plist"}, + {"name": "weekly", "plist": "scheduled/launchd/io.lorecraft.mogging.weekly.plist"}, + {"name": "health", "plist": "scheduled/launchd/io.lorecraft.mogging.health.plist"} ] } diff --git a/.filter-repo-replacements.example.txt b/.filter-repo-replacements.example.txt index 2aa21c9..fccd716 100644 --- a/.filter-repo-replacements.example.txt +++ b/.filter-repo-replacements.example.txt @@ -36,7 +36,7 @@ # # Defensive rule: use ONLY literal matches in this file. For short names # that coincide with English word fragments, rely on the capitalized form -# (`==>`) and accept that lowercase standalone prose mentions +# (`Uri==>`) and accept that lowercase standalone prose mentions # will not be scrubbed. That is far safer than corrupting the codebase. # # --------------------------------------------------------------------------- diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index c8b5516..d63dd38 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -6,7 +6,7 @@ name: Lint Shell Scripts # # ShellCheck action is pinned to 00cae500 = ludeeus/action-shellcheck@v2.0.0 # because trilogy-group v2.0.0 and prior were moving tags. See -# `reference_action_shellcheck_pin` in the operator's memory for history. +# `reference_action_shellcheck_pin` in Nate's memory for history. # ---------------------------------------------------------------------------- on: diff --git a/.github/workflows/secret-scan.yml b/.github/workflows/secret-scan.yml index 65dde0b..5b57be9 100644 --- a/.github/workflows/secret-scan.yml +++ b/.github/workflows/secret-scan.yml @@ -51,7 +51,7 @@ jobs: persist-credentials: false - name: Run gitleaks with custom config - uses: gitleaks/gitleaks-action@ff98106e4c7b2bc287b24eaf42907196329070c7 # v2.3.9 + uses: gitleaks/gitleaks-action@e0c47f4f8be36e29cdc102c57e68cb5cbf0e8d1e # v3.0.0 env: # Point the action at our pinned config. No GITLEAKS_LICENSE is set, # which is intentional for an OSS repo under the free tier. diff --git a/.gitleaks.private.toml.example b/.gitleaks.private.toml.example index eb0066b..b7ed17f 100644 --- a/.gitleaks.private.toml.example +++ b/.gitleaks.private.toml.example @@ -1,4 +1,4 @@ -***REMOVED*** +# ============================================================================ # .gitleaks.private.toml.example — template for operator-specific gitleaks rules # ---------------------------------------------------------------------------- # The real config lives at .gitleaks.private.toml, which is GITIGNORED so the @@ -13,7 +13,7 @@ # gitleaks detect --config .gitleaks.private.toml --no-git # private rules # # Never commit the real .gitleaks.private.toml. -***REMOVED*** +# ============================================================================ title = "2ndBrain-mogging operator-local secret scan" diff --git a/.gitleaks.toml b/.gitleaks.toml index 06de3ea..a6660e5 100644 --- a/.gitleaks.toml +++ b/.gitleaks.toml @@ -56,12 +56,9 @@ keywords = ["n8n_api_"] # Allowlist — self-referential, docs, and synthetic test data # ============================================================================ [allowlist] -description = "Allow matches inside this config, placeholder docs, synthetic fixtures, and descriptive filename slugs" +description = "Allow matches inside this config, placeholder docs, and synthetic fixtures" paths = [ '''(^|/)\.gitleaks\.toml$''', '''(^|/)docs/placeholder-names\.md$''', '''(^|/)tests/fixtures/''', ] -regexes = [ - '''morgen-[a-z]+-[a-z]+-[a-z]+''', -] diff --git a/CHANGELOG.md b/CHANGELOG.md index 25510f9..dad94bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,11 +8,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Added -- **`install.sh` step 1.5 — auto-install Obsidian.app on macOS ( install-call item 2).** When Obsidian.app is missing from `/Applications/`, the installer now runs `brew install --cask obsidian` automatically (idempotent — no-op when already present). Falls back to a download-pointer message on Linux/WSL or when Homebrew isn't on PATH. Opt out with `--no-obsidian-app`. README "Install Obsidian first" section softened to a one-line TL;DR plus a fallback manual section for non-macOS / opt-out users. Source: `project__install_bugs_2026_04_22` + Apr-22 install-call transcript (3 teammates independently bailed at this wall). +- **`install.sh` step 1.5 — auto-install Obsidian.app on macOS (WAGMI install-call item 2).** When Obsidian.app is missing from `/Applications/`, the installer now runs `brew install --cask obsidian` automatically (idempotent — no-op when already present). Falls back to a download-pointer message on Linux/WSL or when Homebrew isn't on PATH. Opt out with `--no-obsidian-app`. README "Install Obsidian first" section softened to a one-line TL;DR plus a fallback manual section for non-macOS / opt-out users. Source: `project_wagmi_install_bugs_2026_04_22` + WAGMI Apr-22 install-call transcript (3 teammates independently bailed at this wall). - **`bin/doctor.sh` — root-owned `~/.npm` check (item 7).** New `check_npm_cache_ownership` walks `~/.npm` (top 2 levels via `find -maxdepth 2 -user root -print -quit`) and surfaces a `[doctor:FAIL]` with the literal copy/paste fix `sudo chown -R $(whoami) ~/.npm` plus the fully-literal fallback `sudo chown -R :staff ~/.npm` for shells that swallow the substitution. Same check ALSO runs at the very end of `install.sh` so the fix is on-screen the moment install completes — users don't have to remember to invoke `doctor` separately. - **`bin/doctor.sh` — filename-equals-foldername check for `01-Projects/` (item 9).** New `check_project_filename_equals_folder` walks `$VAULT/01-Projects/*/` and verifies `/.md` exists, surfacing `[doctor:FAIL]` per missing index file with the exact `mv` command that fixes it. Vault path is discovered from the `~/.claude/.mogging-vault` statusline marker (or `$VAULT` env override). Never auto-renames — project index files are owner=human per CLAUDE.md hard rule. -- **`bin/doctor.sh` — `Projects-Index.md` stale-wikilink check (item 10).** New `check_projects_index_stale_wikilinks` parses `[[X]]` tokens from `04-Index/Projects-Index.md` and verifies `01-Projects/X/X.md` exists for each. Skips known non-project hubs (Home-Index, Tech-Index, GITHUB, , etc.). Flags stale wikilinks with explicit "do NOT auto-delete; flag for human review" reminder per the vault hard rule against silent removal. -- **`install.sh` step 13 — `print_install_summary` (item 11).** Final post-install banner prints an explicit `Self-learning tier: ON | OFF (opt-in via --with-intelligence)` line so users running default install don't think the install is broken when they don't see `helpers/` in the vault. Also surfaces `--no-obsidian-app` and `--no-obsidian-mcp` skip-states inline so the post-install summary matches what was actually wired up. Source: `project__install_bugs_2026_04_22` + Apr-22 install-call transcript. +- **`bin/doctor.sh` — `Projects-Index.md` stale-wikilink check (item 10).** New `check_projects_index_stale_wikilinks` parses `[[X]]` tokens from `04-Index/Projects-Index.md` and verifies `01-Projects/X/X.md` exists for each. Skips known non-project hubs (Home-Index, Tech-Index, GITHUB, LORECRAFT-HQ, etc.). Flags stale wikilinks with explicit "do NOT auto-delete; flag for human review" reminder per the vault hard rule against silent removal. +- **`install.sh` step 13 — `print_install_summary` (item 11).** Final post-install banner prints an explicit `Self-learning tier: ON | OFF (opt-in via --with-intelligence)` line so users running default install don't think the install is broken when they don't see `helpers/` in the vault. Also surfaces `--no-obsidian-app` and `--no-obsidian-mcp` skip-states inline so the post-install summary matches what was actually wired up. Source: `project_wagmi_install_bugs_2026_04_22` + WAGMI Apr-22 install-call transcript. - README: social-links badge strip (X · LinkedIn · YouTube · Instagram, ruvnet-style for-the-badge) inserted into the centered header block beneath the project license badge. - **`install.sh` step 10.7 — register `obsidian-mcp` with Claude Code.** `--apply` now runs `claude mcp add --scope user obsidian -- npx -y obsidian-mcp "$VAULT"` so Claude Code can read/write the vault out of the box. Idempotent (skips if already registered), opts out with `--no-obsidian-mcp`, and gracefully noops if the `claude` CLI isn't on PATH. Closes the cli-maxxing README cross-reference that previously promised this behavior before it existed (b0c38cd). - **`install.sh` step 10.8 — `~/.claude/.mogging-vault` marker file.** Install writes a marker pointing at the vault root so cli-maxxing's statusline can detect a mogged vault and render the correct `fidgetflo` / mogging indicator. Closes the second half of the cli-maxxing cross-reference (7feeedf). @@ -22,18 +22,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - **NicholasSpisak repo link** — added to the origin story and Credits. ### Fixed -- **`install.sh` `validate_vault` no longer bails when `--vault` points at a missing directory ( install-call item 5).** Previously the script exited with code 21 + a "create it first, then re-run" message, forcing a 2-step install for every fresh teammate. Now `--apply` runs `mkdir -p "$VAULT"` (after the existing `..`-traversal guard) and lets vault-template seeding (step 3.5) populate the empty dir on the same pass. Dry-run logs `would create vault directory: ` instead of erroring. Source: Apr-22 install transcript (Ian, Kostas, Scott all hit this). -- **`install.sh` `link_claude_memory` no longer requires a 2-pass install ( install-call item 8).** Previously the symlink step skipped when `~/.claude/projects//memory/` didn't exist yet (cbrain had to run once first to mint it). Now the installer mkdir -p's that path itself before linking, so `cbrain` works on first invocation post-install. Claude Code's first-run also mkdir -p's the same path, so racing it is a no-op for Claude. -- **`install.sh` no longer references the non-existent `npm cache fix` subcommand ( install-call item 6).** Repo-wide grep returned zero hits at audit time (the bad string had already been stripped during prior cleanup), but the legacy fix message was preserved as a comment in `check_npm_cache_ownership` so future contributors don't reintroduce it. The actual user-facing fix string is now the literal `sudo chown -R $(whoami) ~/.npm` (with a `:staff` fallback for shells that drop the substitution). +- **`install.sh` `validate_vault` no longer bails when `--vault` points at a missing directory (WAGMI install-call item 5).** Previously the script exited with code 21 + a "create it first, then re-run" message, forcing a 2-step install for every fresh teammate. Now `--apply` runs `mkdir -p "$VAULT"` (after the existing `..`-traversal guard) and lets vault-template seeding (step 3.5) populate the empty dir on the same pass. Dry-run logs `would create vault directory: ` instead of erroring. Source: WAGMI Apr-22 install transcript (Ian, Kostas, Scott all hit this). +- **`install.sh` `link_claude_memory` no longer requires a 2-pass install (WAGMI install-call item 8).** Previously the symlink step skipped when `~/.claude/projects//memory/` didn't exist yet (cbrain had to run once first to mint it). Now the installer mkdir -p's that path itself before linking, so `cbrain` works on first invocation post-install. Claude Code's first-run also mkdir -p's the same path, so racing it is a no-op for Claude. +- **`install.sh` no longer references the non-existent `npm cache fix` subcommand (WAGMI install-call item 6).** Repo-wide grep returned zero hits at audit time (the bad string had already been stripped during prior cleanup), but the legacy fix message was preserved as a comment in `check_npm_cache_ownership` so future contributors don't reintroduce it. The actual user-facing fix string is now the literal `sudo chown -R $(whoami) ~/.npm` (with a `:staff` fallback for shells that drop the substitution). - **launchd plist `node` PATH resolution.** The four `scheduled/launchd/*.plist` templates had a `PATH` that listed `/opt/homebrew/bin` but never sourced nvm, so scheduled agents on nvm-managed Node installs hit `sh: exec: node: not found` inside the SessionEnd hook. The plists now source `$HOME/.nvm/nvm.sh` inside `ProgramArguments`, which stays version-agnostic — no hardcoded `vN.N.N` path to maintain (04c796e). - **`install.sh` `merge_intelligence_hooks()` jq bug.** The merge pipeline was `(.[0] * .[1]) as $m | $m | .[0]...` — after the `$m |` step, the pipeline context is the merged object, so `.[0]` threw `Cannot index object with number` and the `--with-intelligence` install aborted mid-flight. Bind `$old` / `$new` before the merge, and the hook-array concat logic goes through untouched. Verified end-to-end: `install.sh --with-intelligence` completes, `doctor` passes, all 4 launchd jobs reload with working `node` PATH, Stop hook preserved, 5 intelligence hooks appended, `settings.json` stays valid JSON (04c796e). - **launchd plist flags.** Stale `--headless --audit` flags dropped from the agent invocations in the four `scheduled/launchd/*.plist` templates (pre-existing carry-over from pre-mogging). -- **the operator → the operator sweep.** Purged every "the operator" / "the operator" reference from shipped skill MDs, commands, README, and migration docs. Canonical is the operator / . +- **Nathan → Nate sweep.** Purged every "Nathan" / "Nathan Davidovich" reference from shipped skill MDs, commands, README, and migration docs. Canonical is Nate Davidovich / Lorecraft LLC. - **Ruvnet/claude-flow/ruflo attribution.** Removed the inaccurate direct-descent claim from README in favor of the actual lineage (FidgetFlo fork). - **15-agent audit-and-fix pass.** Full consistency sweep across `README.md`, `PHILOSOPHY.md`, `CHANGELOG.md`, `CONTRIBUTING.md`, `docs/**`, `references/wiki-schema.md`, and every `skills/*/SKILL.md` to close the residual drift between prose and shipped behavior after v0.1.4. ### Changed -- Git history rewrite: `git filter-repo` collapsed all author/committer identities into a single `the operator ` identity across `main` and all release tags. All `Co-authored-by:` trailers stripped. Two stale dependabot/* branches deleted from the remote. Tag commit hashes for v0.1.0 / v0.1.1 changed; this repo has no published npm artifact, so no downstream impact. +- Git history rewrite: `git filter-repo` collapsed all author/committer identities into a single `Nate Davidovich ` identity across `main` and all release tags. All `Co-authored-by:` trailers stripped. Two stale dependabot/* branches deleted from the remote. Tag commit hashes for v0.1.0 / v0.1.1 changed; this repo has no published npm artifact, so no downstream impact. ## [0.1.4] — 2026-04-17 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8bf5cd9..2221bef 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -14,7 +14,7 @@ Thanks for considering a contribution. This repo is small, opinionated, and inte **No breaking changes without a major version bump.** Anything that changes a frontmatter key, a folder role, a command name, or the `[bot:*]` commit prefix convention is a breaking change. Breaking changes require the version in `.claude-plugin/plugin.json` to go from `0.x.y` to `1.0.0` (or from `1.x.y` to `2.0.0`) and an entry in `CHANGELOG.md` under a `### Breaking` heading. We do not ship breaking changes silently. -**Every PR runs the full test harness.** From the repo root: `bash tests/run_all.sh`. The harness runs every `tests/test_*.sh` script against temp-dir fixtures and reports PASS / SKIP / FAIL per test (SKIP fires when a prerequisite is missing; `--strict` promotes SKIP to FAIL for CI). If your change modifies behavior a test asserts on, update that test in the same PR. +**Every PR runs the full test harness.** From the repo root: `bash tests/run_all.sh`. The harness creates a known-state vault fixture in a temp directory, runs every skill against it, and diffs the output against expected-state files in `tests/expected/`. If your change modifies output, update the expected files in the same PR. **Direct push to `main` is the maintainer default, not the contributor default.** This repo lives under `fidgetcoding` where maintainers push directly to `main` by policy. Contributor PRs are still required to target `main` through review. The direct-push policy does not mean "anyone can push" — it means "once merged, the change is live, no staging branch." diff --git a/LICENSE b/LICENSE index c70612e..4fb9ed4 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2026 the operator / / fidgetcoding (2ndBrain-mogging pack) +Copyright (c) 2026 Nate Davidovich / Lorecraft LLC / fidgetcoding (2ndBrain-mogging pack) Copyright (c) 2024-2026 ruvnet (applies specifically to the vendored helpers under helpers/, inherited from https://github.com/ruvnet/ruflo via the fidgetcoding/fidgetflo intermediate fork — see docs/CREDITS.md and NOTICE) diff --git a/NOTICE b/NOTICE index 2ed5797..923fb1f 100644 --- a/NOTICE +++ b/NOTICE @@ -1,7 +1,7 @@ 2ndBrain-mogging ================ -Copyright (c) 2026 the operator / / fidgetcoding +Copyright (c) 2026 Nate Davidovich / Lorecraft LLC / fidgetcoding Licensed under the MIT License. See LICENSE for the full text. This pack incorporates vendored third-party code under `helpers/`. The files @@ -12,19 +12,19 @@ distributed under the MIT License: Upstream: https://github.com/ruvnet/ruflo Anchor tag: v3.5.80 -The vendored files were imported via the -owned intermediate fork +The vendored files were imported via the Lorecraft-owned intermediate fork `fidgetcoding/fidgetflo`, which was squash-imported from ruflo@v3.5.80 and then extended with additional pattern-graph / intelligence-loop logic by - (the operator). As a result, several files in `helpers/` differ +Lorecraft (Nate Davidovich). As a result, several files in `helpers/` differ in content and length from the corresponding files in the public ruflo v3.5.80 tag, and a handful of files (`memory.js`, `router.js`, `session.js`) -are / FidgetFlo-era additions that do not exist in the upstream +are Lorecraft / FidgetFlo-era additions that do not exist in the upstream tag at all. The dual copyright on these files is therefore: Copyright (c) 2024-2026 ruvnet (original ruflo work carried forward) - Copyright (c) 2026 the operator / / fidgetcoding (FidgetFlo extensions + Copyright (c) 2026 Nate Davidovich / Lorecraft LLC / fidgetcoding (FidgetFlo extensions and 2ndBrain-mogging integration) diff --git a/PHILOSOPHY.md b/PHILOSOPHY.md index 9a1544f..99659fb 100644 --- a/PHILOSOPHY.md +++ b/PHILOSOPHY.md @@ -40,7 +40,7 @@ Compilation is slower per query. It's also much higher quality, and it produces ## The folder is the app -From the Jens project, expressed as a design constraint: the Obsidian folder structure **is** the application's data model. There is no separate index, no sidecar database, no external registry. If a file exists at `01-Projects//.md`, the plugin knows that note is a project index for ``. If a file exists at `05-Tasks/TASKS-.md`, the plugin knows it's the Tasks hub for the same project. +From the Jens project, expressed as a design constraint: the Obsidian folder structure **is** the application's data model. There is no separate index, no sidecar database, no external registry. If a file exists at `01-Projects/LORECRAFT-HQ/LORECRAFT-HQ.md`, the plugin knows that note is a project index for `LORECRAFT-HQ`. If a file exists at `05-Tasks/TASKS-LORECRAFT.md`, the plugin knows it's the Tasks hub for the same project. This is a discipline. It means the plugin cannot invent new structural concepts without expressing them as a folder or file naming rule, which keeps the surface honest. It also means an operator can move files around outside the plugin and the plugin will rediscover them correctly next run. No "re-index" step. No stale database. diff --git a/README.md b/README.md index 550880b..95b98c5 100644 --- a/README.md +++ b/README.md @@ -137,8 +137,6 @@ cd 2ndBrain-mogging | `--no-launchd` | off | Skip the 4 scheduled-agent launchd jobs (morning / nightly / weekly / health). | | `--no-obsidian-mcp` | off | Skip registering the `obsidian-mcp` server with Claude Code (`claude mcp add obsidian … $VAULT`). | | `--no-statusline-brain` | off | Skip writing `~/.claude/.mogging-vault` — the vault-path marker [cli-maxxing](https://github.com/fidgetcoding/cli-maxxing)'s ⚡ fidgetflo statusline reads to light up the 🧠 Brain² indicator. | -| `--no-obsidian-app` | off | Skip auto-installing the Obsidian.app desktop client (macOS; default runs `brew install --cask obsidian` when the app is missing). | -| `--no-shell-shortcuts` | off | Skip writing the `cbrain` / `cbraintg` launchers to `~/.local/bin`. | | `--skip-tests` | off | Skip the onboarding test suite at the end. | | `--merge-stop` | off | Replace the existing Stop hook instead of jq-merging onto it. | | `--no-seed-vault` | off | Skip seeding the 6-folder vault layout from `vault-template/`. By default the installer copies in any of `01-Projects//conversations/`, `02-Sources/`, `03-Concepts/`, `04-Index/Projects-Index.md`, `01-Projects/{example-project-1, example-project-2, example-project-3, INCUBATOR}/`, `05-Tasks/`, `Claude-Memory/`, `CLAUDE.md`, `AGENTS.md` that are missing. Existing files are never overwritten. | @@ -321,7 +319,7 @@ This pack is an amalgamation — not an invention. The best ideas are all borrow - **AgriciDaniel** ([`claude-obsidian`](https://github.com/AgriciDaniel/claude-obsidian)) — the conversation-capture hygiene and the `owner: wiki` vs `owner: human` discipline that makes skills safe to run against live notes. - **eugeniu** ([`obsidian-second-brain`](https://github.com/eugeniughelbur/obsidian-second-brain)) — the concept-atomization rules that keep `03-Concepts/` from becoming a dumping ground. - **Jens Heitmann** ([`ai-second-brain-skills`](https://github.com/NulightJens/ai-second-brain-skills)) — the original folder structure I modded to death, and the taste-making starting point. -- **Karpathy** ([`LLM Wiki` gist](https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f)-era second brain) — the wiki-style synthesis pattern that became `/wiki` and `/emerge`. +- **Karpathy** ([`LLM Wiki`](https://karpathy.ai/zero-to-hero.html)-era second brain) — the wiki-style synthesis pattern that became `/wiki` and `/emerge`. - **NicholasSpisak** ([`second-brain`](https://github.com/NicholasSpisak/second-brain)) — the Canvas-scratchpad pattern that became `/canvas`. Each of them is worth a look even if you install this pack instead. They're the people who did the hard work; I just picked the best of five. diff --git a/agents/health.md b/agents/health.md index 01b111c..d726b52 100644 --- a/agents/health.md +++ b/agents/health.md @@ -2,7 +2,7 @@ name: health description: Sunday 9:00 PM ET vault integrity check — verifies symlink resolution, Obsidian plugin loads, n8n sync freshness, and Morgen↔Obsidian task-count parity (within in-flight tolerance). Writes a one-line status plus a diagnostics block. schedule: "0 21 * * 0 America/New_York" -plist: scheduled/launchd/io..mogging.health.plist +plist: scheduled/launchd/io.lorecraft.mogging.health.plist allowed-tools: Read, Glob, Bash, Write writes: - 01-Projects/VAULT/conversations/reports/health-YYYY-MM-DD.md @@ -16,13 +16,13 @@ reads: # health — Sunday 9pm ET vault integrity check -Triggered by `scheduled/launchd/io..mogging.health.plist` at 21:00 America/New_York on Sundays. The agent's job is signal-to-human: is the vault + sync + plugin pipeline healthy enough that the operator can trust Monday morning's data? +Triggered by `scheduled/launchd/io.lorecraft.mogging.health.plist` at 21:00 America/New_York on Sundays. The agent's job is signal-to-human: is the vault + sync + plugin pipeline healthy enough that Nate can trust Monday morning's data? ## 1. Checks (four gates) ### Gate A — Symlinks resolve -The live vault has a handful of project symlinks (e.g., the `05-Tasks/obsidian-tasks-sync` git submodule → a repo elsewhere on disk; or any repo submoduled under `01-Projects//GITHUB/-REPOS/`). A broken symlink creates ghost paths in `Glob` output and confuses every downstream skill. +The live vault has a handful of project symlinks (e.g., the `05-Tasks/obsidian-tasks-sync` git submodule → a repo elsewhere on disk; or any repo submoduled under `01-Projects/FIDGETCODING/GITHUB/LORECRAFT-REPOS/`). A broken symlink creates ghost paths in `Glob` output and confuses every downstream skill. Check: `find -maxdepth 5 -type l` and `test -e` each target. Report count of broken vs. resolved. @@ -46,7 +46,7 @@ If stale: flag + suggest the user check the n8n dashboard. There's also an hourl Pull the Morgen task count (`list_tasks` with `limit=500` per `reference_morgen_api_pagination`). Pull the Obsidian task count via `Grep -c` on `^- \[ \]` across `05-Tasks/**/*.md` plus an aggregated scan of inline tasks in the project subtrees. -The counts should match within ±5 (the in-flight tolerance covers tasks written to Obsidian in the last 15 minutes that haven't round-tripped through W1 to Morgen yet, per the operator's `feedback_task_state_source_of_truth` rule). +The counts should match within ±5 (the in-flight tolerance covers tasks written to Obsidian in the last 15 minutes that haven't round-tripped through W1 to Morgen yet, per Nate's `feedback_task_state_source_of_truth` rule). If the delta exceeds tolerance: flag the sync as drifting and include the top 10 UUIDs present in one side but not the other. @@ -63,7 +63,7 @@ tags: [health, integrity, health-agent] --- ``` -Body is structured so the first line is a glanceable one-liner — this is the value the operator gets from checking the report at a glance. +Body is structured so the first line is a glanceable one-liner — this is the value Nate gets from checking the report at a glance. **First line (mandatory format):** diff --git a/agents/morning.md b/agents/morning.md index 558077e..f14311c 100644 --- a/agents/morning.md +++ b/agents/morning.md @@ -2,7 +2,7 @@ name: morning description: Daily 8:00 AM ET briefing — pulls today's Morgen events, surfaces overdue/today tasks, and primes Claude-Memory/hot.md with the day's context window. Writes a single daily report; does NOT touch concept or source notes. schedule: "0 8 * * * America/New_York" -plist: scheduled/launchd/io..mogging.morning.plist +plist: scheduled/launchd/io.lorecraft.mogging.morning.plist allowed-tools: Read, Write, Edit, Glob, Bash writes: - 01-Projects/VAULT/conversations/reports/daily-YYYY-MM-DD.md @@ -15,11 +15,11 @@ reads: # morning — daily 8am ET briefing -Triggered by `scheduled/launchd/io..mogging.morning.plist` at 08:00 America/New_York. The agent has exactly two write targets and no others. Per `references/wiki-schema.md` §1, all reports live under `01-Projects/VAULT/conversations/reports/`. +Triggered by `scheduled/launchd/io.lorecraft.mogging.morning.plist` at 08:00 America/New_York. The agent has exactly two write targets and no others. Per `references/wiki-schema.md` §1, all reports live under `01-Projects/VAULT/conversations/reports/`. ## 1. Pull today's Morgen state -Use the `morgen` MCP (the operator's default calendar layer per memory rule "Morgen is Default"): +Use the `morgen` MCP (Nate's default calendar layer per memory rule "Morgen is Default"): 1. `list_events` with `start=` and `end=`. Include all-day events and timed events. Sort ascending by start time. 2. `list_tasks` filtered to overdue (due < today) AND today (due = today). Dedupe on 🆔 — Obsidian-synced tasks return under both Morgen task and event queries. @@ -58,7 +58,7 @@ Body sections in this order: ## 4. Prime `Claude-Memory/hot.md` -`hot.md` is the short working-context file the operator's other skills read at invocation to avoid cold starts. Prime it with: +`hot.md` is the short working-context file Nate's other skills read at invocation to avoid cold starts. Prime it with: - Top 5 overdue tasks (one line each, with UUID). - Top 3 today events (title + start time). diff --git a/agents/nightly.md b/agents/nightly.md index 9bf8563..0184717 100644 --- a/agents/nightly.md +++ b/agents/nightly.md @@ -2,7 +2,7 @@ name: nightly description: Nightly 10:00 PM ET vault audit — AUDIT-ONLY, no writes to concept or source notes. Runs /wiki audit scoped to 02-Sources, 03-Concepts, and 04-Index. Appends the report to the daily audit log and increments the lint counter. schedule: "0 22 * * * America/New_York" -plist: scheduled/launchd/io..mogging.nightly.plist +plist: scheduled/launchd/io.lorecraft.mogging.nightly.plist allowed-tools: Read, Write, Glob, Grep, Bash writes: - 01-Projects/VAULT/conversations/reports/audit-YYYY-MM-DD.md @@ -15,7 +15,7 @@ reads: # nightly — audit-only report at 10pm ET -Triggered by `scheduled/launchd/io..mogging.nightly.plist` at 22:00 America/New_York. The hard contract: **no writes to any note under 02-Sources, 03-Concepts, or 04-Index.** The only writes are the audit report itself and the lint-counter. This separation is the reason the agent is safe to schedule unattended. +Triggered by `scheduled/launchd/io.lorecraft.mogging.nightly.plist` at 22:00 America/New_York. The hard contract: **no writes to any note under 02-Sources, 03-Concepts, or 04-Index.** The only writes are the audit report itself and the lint-counter. This separation is the reason the agent is safe to schedule unattended. ## 1. Scope diff --git a/agents/weekly.md b/agents/weekly.md index 9115840..18a2e2f 100644 --- a/agents/weekly.md +++ b/agents/weekly.md @@ -2,7 +2,7 @@ name: weekly description: Friday 6:00 PM ET weekly review — runs /emerge --days 7 --audit, produces a week-in-review report covering new concepts, killed ideas, unresolved contradictions, and the rolling 7-day audit trend. schedule: "0 18 * * 5 America/New_York" -plist: scheduled/launchd/io..mogging.weekly.plist +plist: scheduled/launchd/io.lorecraft.mogging.weekly.plist allowed-tools: Read, Write, Glob, Grep, Bash writes: - 01-Projects/VAULT/conversations/reports/weekly-YYYY-WW.md @@ -16,7 +16,7 @@ reads: # weekly — Friday 6pm ET week-in-review -Triggered by `scheduled/launchd/io..mogging.weekly.plist` at 18:00 America/New_York on Fridays. ISO week number format (`YYYY-WW`, e.g., `2026-15`) keeps weekly reports sortable across year boundaries. +Triggered by `scheduled/launchd/io.lorecraft.mogging.weekly.plist` at 18:00 America/New_York on Fridays. ISO week number format (`YYYY-WW`, e.g., `2026-15`) keeps weekly reports sortable across year boundaries. ## 1. Source gathering diff --git a/bin/backup-vault.sh b/bin/backup-vault.sh index f7f0504..b75a151 100755 --- a/bin/backup-vault.sh +++ b/bin/backup-vault.sh @@ -5,23 +5,15 @@ # Usage: # backup-vault.sh [VAULT_PATH] # -# Produces ~/WORK/-BACKUPS/-backup-YYYYMMDD-HHMMSS.tar.gz -# from the given vault path. Vault resolution order: $1 arg, then the -# ~/.claude/.mogging-vault marker install.sh writes, then ~/BRAIN2. -# Excludes Obsidian workspace state files and .DS_Store. -# -# NEVER writes to ~/Desktop — modern macOS permission-protects it (TCC), -# and the vault non-negotiables forbid Desktop tarballs outright. +# Produces ~/Desktop/2ndBrain-backup-YYYYMMDD-HHMMSS.tar.gz from the given +# vault path (defaults to ~/Desktop/WORK/OBSIDIAN/2ndBrain). Excludes +# Obsidian workspace state files and .DS_Store. # set -euo pipefail IFS=$'\n\t' -VAULT="${1:-}" -if [[ -z "$VAULT" && -f "$HOME/.claude/.mogging-vault" ]]; then - VAULT="$(head -n 1 "$HOME/.claude/.mogging-vault" | tr -d '\r\n')" -fi -VAULT="${VAULT:-$HOME/BRAIN2}" +VAULT="${1:-$HOME/Desktop/WORK/OBSIDIAN/2ndBrain}" if [[ ! -d "$VAULT" ]]; then echo "backup-vault: not a directory: $VAULT" >&2 @@ -31,9 +23,7 @@ fi VAULT_ABS="$(cd -P "$VAULT" >/dev/null 2>&1 && pwd)" PARENT="$(dirname "$VAULT_ABS")" NAME="$(basename "$VAULT_ABS")" -BACKUP_DIR="$HOME/WORK/${NAME}-BACKUPS" -mkdir -p "$BACKUP_DIR" -OUT="$BACKUP_DIR/${NAME}-backup-$(date +%Y%m%d-%H%M%S).tar.gz" +OUT="$HOME/Desktop/2ndBrain-backup-$(date +%Y%m%d-%H%M%S).tar.gz" tar --exclude='.obsidian/workspace*' \ --exclude='.DS_Store' \ diff --git a/bin/doctor.sh b/bin/doctor.sh index ccd8180..a1fd4e5 100755 --- a/bin/doctor.sh +++ b/bin/doctor.sh @@ -2,20 +2,14 @@ # # 2ndBrain-mogging — doctor # -# Usage: doctor.sh [--vault PATH] -# # Sanity-check that the install is healthy: # - every symlink under ~/.claude/{skills,commands,agents}/ resolves -# (a link that resolves to a DIFFERENT clone is a WARN, not a FAIL) # - every plist shipped in scheduled/launchd/ is installed and loaded # - the plugin is reachable (via symlinks — Claude's plugin registry is # forward-looking; install.sh does not call `claude plugin add`) # -# --vault PATH overrides vault discovery (marker file / $VAULT env) — used -# by install.sh to thread its resolved --vault through. -# # Exit codes: -# 0 = all green (warnings allowed) +# 0 = all green # 3 = one or more checks reported FAIL (intentionally non-standard so # callers using doctor.sh as a CI gate can distinguish real FAILs # from shell errors like "file not found" or "permission denied") @@ -36,32 +30,14 @@ REPO_ROOT="$(cd -P "$BIN_DIR/.." >/dev/null 2>&1 && pwd)" CLAUDE_HOME="${CLAUDE_HOME:-$HOME/.claude}" LAUNCHAGENTS_DIR="$HOME/Library/LaunchAgents" -# ---- argv ------------------------------------------------------------------- -# --vault PATH: explicit vault override (highest precedence). install.sh -# threads its resolved --vault through here so doctor checks the vault THIS -# install run targeted — not whatever ~/.claude/.mogging-vault points at from -# a previous install on the same machine. -VAULT_FLAG="" -while [[ $# -gt 0 ]]; do - case "$1" in - --vault) VAULT_FLAG="${2:-}"; shift 2 ;; - --vault=*) VAULT_FLAG="${1#*=}"; shift ;; - *) shift ;; - esac -done - -# Vault path resolution, in precedence order: -# 1. --vault flag (explicit, always wins) -# 2. the statusline marker that install.sh step 10.8 writes -# (~/.claude/.mogging-vault) -# 3. the $VAULT environment variable -# Empty after all three → vault-scoped checks are skipped with [doctor:info], -# not failed — doctor on a non-vault host is a valid scenario. +# Vault path is discovered at runtime from the statusline marker that +# install.sh step 10.8 writes (~/.claude/.mogging-vault). Falls back to +# the $VAULT environment variable if it's set, then to empty (in which +# case vault-scoped checks are skipped with [doctor:info], not failed — +# doctor on a non-vault host is a valid scenario). MOGGING_VAULT_MARKER="$CLAUDE_HOME/.mogging-vault" VAULT_PATH="" -if [[ -n "$VAULT_FLAG" ]]; then - VAULT_PATH="$VAULT_FLAG" -elif [[ -f "$MOGGING_VAULT_MARKER" ]]; then +if [[ -f "$MOGGING_VAULT_MARKER" ]]; then # Marker contains a single line: the absolute vault path. VAULT_PATH="$(head -n 1 "$MOGGING_VAULT_MARKER" 2>/dev/null | tr -d '\r\n' || true)" fi @@ -70,7 +46,6 @@ if [[ -z "$VAULT_PATH" && -n "${VAULT:-}" ]]; then fi FAIL_COUNT=0 -WARN_COUNT=0 # Exit code for "one or more FAILs fired" — non-standard on purpose so # callers can distinguish a real health-check failure (exit 3) from # shell plumbing errors (exit 1/2/127/etc). @@ -78,29 +53,10 @@ DOCTOR_FAIL_EXIT=3 pass() { printf '[doctor:ok] %s\n' "$*"; } fail() { printf '[doctor:FAIL] %s\n' "$*" >&2; FAIL_COUNT=$((FAIL_COUNT + 1)); } -warn() { printf '[doctor:warn] %s\n' "$*" >&2; WARN_COUNT=$((WARN_COUNT + 1)); } info() { printf '[doctor:info] %s\n' "$*"; } # ---- symlink checks --------------------------------------------------------- -# A symlink that resolves but points at a DIFFERENT clone than the one doctor -# runs from is a WARN, not a FAIL — running doctor from a fresh clone on an -# already-installed machine is a valid scenario. The target counts as a valid -# alternate when it is the same kind of thing (dir vs file) and, for skill -# directories, ships the same SKILL.md the repo entry does. -symlink_target_is_valid_alternate() { - local dest="$1" entry="$2" - [[ -e "$dest" ]] || return 1 - if [[ -d "$entry" ]]; then - [[ -d "$dest" ]] || return 1 - if [[ -f "$entry/SKILL.md" && ! -f "$dest/SKILL.md" ]]; then - return 1 - fi - return 0 - fi - [[ -f "$dest" ]] -} - check_symlinks_for_kind() { local kind="$1" local src_root="$REPO_ROOT/$kind" @@ -118,11 +74,7 @@ check_symlinks_for_kind() { fi target="$(readlink "$dest" 2>/dev/null || true)" if [[ "$target" != "$entry" ]]; then - if symlink_target_is_valid_alternate "$dest" "$entry"; then - warn "$kind/$name -> $target (installed from a different clone than $REPO_ROOT; target valid, accepting)" - else - fail "$dest -> $target (expected $entry)" - fi + fail "$dest -> $target (expected $entry)" continue fi if [[ ! -e "$dest" ]]; then @@ -138,10 +90,6 @@ check_symlinks_for_kind() { check_launchd() { info "checking launchd jobs" - if [[ "$(uname -s)" != "Darwin" ]]; then - info "launchd is macOS-only; skipping on $(uname -s) (scheduled agents need cron/systemd timers here)" - return 0 - fi local src_dir="$REPO_ROOT/scheduled/launchd" [[ -d "$src_dir" ]] || { info "no launchd sources; skipping"; return 0; } shopt -s nullglob @@ -173,22 +121,8 @@ check_launchd() { check_plugin_registered() { info "checking plugin registration (forward-looking)" if ! command -v claude >/dev/null 2>&1; then - # Non-interactive shells (ssh, cron) skip the nvm bootstrap in .bashrc — - # probe the usual install homes before declaring claude missing. - local alt_claude - # `|| true` is load-bearing: with no nvm installs the glob passes through - # unexpanded, ls exits non-zero, and `set -euo pipefail` would kill the - # whole doctor run silently (exit 1, no FAIL output) without it. - alt_claude="$(ls -1 "$HOME"/.nvm/versions/node/*/bin/claude 2>/dev/null | tail -1 || true)" - if [[ -z "$alt_claude" && -x "$HOME/.local/bin/claude" ]]; then - alt_claude="$HOME/.local/bin/claude" - fi - if [[ -n "$alt_claude" ]]; then - PATH="$(dirname "$alt_claude"):$PATH" - else - fail "claude CLI not on PATH" - return - fi + fail "claude CLI not on PATH" + return fi # read plugin name from .claude-plugin/plugin.json if present local plugin_name="" @@ -210,12 +144,12 @@ check_plugin_registered() { fi } -# ---- npm cache ownership check ( install-call 2026-04-22 item 7) ------- +# ---- npm cache ownership check (WAGMI install-call 2026-04-22 item 7) ------- # # obsidian-mcp / magic-mcp / any npx-driven MCP fails silently when ~/.npm is # root-owned (legacy `sudo npm install` damage). Doctor surfaces this with the # literal one-liner that fixes it — DO NOT print "npm cache fix" (not a real -# subcommand; see install-call item 6). The fix is always: +# subcommand; see WAGMI install-call item 6). The fix is always: # # sudo chown -R $(whoami) ~/.npm # @@ -250,8 +184,8 @@ check_npm_cache_ownership() { # ---- vault project-index filename=foldername check (item 9) ----------------- # # Hard rule from CLAUDE.md: every project folder under 01-Projects/ must have -# an index note where filename = foldername (e.g. /.md, never -# /-Index.md). Folder renames (e.g. example-project-1 → +# an index note where filename = foldername (e.g. PARZVL/PARZVL.md, never +# PARZVL/PARZVL-Index.md). Folder renames (e.g. example-project-1 → # NiFe-WARS-Kostas) leave the inner .md unchanged, breaking [[PROJECT]] # wikilink resolution. Surface drift, suggest the rename, never auto-rename # (project index files are owner=human; CLAUDE.md forbids auto-rewrite). @@ -332,29 +266,14 @@ check_projects_index_stale_wikilinks() { [[ -z "$file_target" ]] && continue # Skip well-known non-project wikilinks (other index hubs, common refs). case "$file_target" in - Projects-Index|Home-Index|Tech-Index|Poetry-Index|Index|TASKS|GITHUB|) continue ;; + Projects-Index|Home-Index|Tech-Index|Poetry-Index|Index|TASKS|GITHUB|LORECRAFT-HQ) continue ;; esac - # Project folders may be nested under grouping hubs (INCUBATOR/, ARCHIVE/, - # CREATIVE/, MINDFULNESS/, …) — the layout the vault CLAUDE.md mandates. - # Search /.md at folder depth 1-3 under 01-Projects/ - # instead of assuming depth-1. Glob metachars in the target are escaped - # so find -path matches them literally. - local escaped_target - escaped_target="$(printf '%s' "$file_target" | sed 's/[][*?\\]/\\&/g')" - if ! find "$projects_dir" -mindepth 2 -maxdepth 4 \ - -path "*/$escaped_target/$escaped_target.md" -print -quit 2>/dev/null | grep -q .; then - fail "Projects-Index.md links to [[$file_target]] but no $file_target/$file_target.md exists under 01-Projects/ (searched 3 levels deep)" + if [[ ! -f "$projects_dir/$file_target/$file_target.md" ]]; then + fail "Projects-Index.md links to [[$file_target]] but 01-Projects/$file_target/$file_target.md is missing" fail " flag for human review (do NOT auto-delete; CLAUDE.md hard rule)" stale_count=$((stale_count + 1)) fi - done < <( - # Drop fenced code blocks and inline `code` spans first — wikilinks in - # example/template snippets are documentation, not graph edges, and - # false-fail the check (e.g. the "How to add a new project" how-to). - awk '/^[[:space:]]*```/{inblock=!inblock; next} !inblock' "$index_file" \ - | sed 's/`[^`]*`//g' \ - | grep -oE '\[\[[^]|]+' | sed 's/^\[\[//' - ) + done < <(grep -oE '\[\[[^]|]+' "$index_file" | sed 's/^\[\[//') if [[ "$stale_count" -eq 0 ]]; then pass "Projects-Index.md wikilinks all resolve to existing project folders" fi @@ -370,11 +289,7 @@ main() { check_project_filename_equals_folder check_projects_index_stale_wikilinks if [[ "$FAIL_COUNT" -eq 0 ]]; then - if [[ "$WARN_COUNT" -gt 0 ]]; then - printf '[doctor] all checks passed (%d warning(s))\n' "$WARN_COUNT" - else - printf '[doctor] all checks passed\n' - fi + printf '[doctor] all checks passed\n' exit 0 fi printf '[doctor] %d check(s) FAILED — exiting %d\n' "$FAIL_COUNT" "$DOCTOR_FAIL_EXIT" >&2 diff --git a/commands/challenge.md b/commands/challenge.md index a96f6cf..bad7c3e 100644 --- a/commands/challenge.md +++ b/commands/challenge.md @@ -1,5 +1,5 @@ --- -description: "Adversarial vault agent. Takes an idea and argues against it using the operator's own past notes, feedback files, and Claude-Memory. Read-only by default; writes only with --save." +description: "Adversarial vault agent. Takes an idea and argues against it using Nate's own past notes, feedback files, and Claude-Memory. Read-only by default; writes only with --save." --- Read the `challenge` skill at `skills/challenge/SKILL.md`, then run the workflow. Invocation: `/challenge "idea text"` with optional `--scope `, `--days N`, `--source` (verbose citation mode with file paths + line numbers), and `--save` (write the full report to `03-Concepts/challenges/YYYY-MM-DD-.md`; without this flag output is terminal-only). The skill resolves the idea into a proposition + anchors, gathers evidence from `03-Concepts/`, `01-Projects/`, `Claude-Memory/`, and classifies each hit as CONTRADICTS / CONSTRAINT / COST_PATTERN / STAKEHOLDER_CONFLICT / DEPENDENCY_BROKEN / SUPPORTS / IRRELEVANT, then renders a ranked report with a GO / PAUSE / STOP / NET-NEW verdict. diff --git a/commands/emerge.md b/commands/emerge.md index 373318a..71982b1 100644 --- a/commands/emerge.md +++ b/commands/emerge.md @@ -2,4 +2,4 @@ description: "Surface rising topics, killed ideas, and new links across a time window. Optional --audit flag for weekly-review output." --- -Read the `emerge` skill at `skills/emerge/SKILL.md`, then run the workflow. Flags: `--days N` (default 30), `--scope ` (restrict to a folder), `--min-cluster N` (default 3, clusters below this are treated as noise), `--audit` (non-interactive mode for the scheduled Sunday 9pm agent — writes to `01-Projects/VAULT/conversations/reports/emerge-YYYY-WW.md`), `--promote ` (skip mining and promote a previously-identified cluster to a full `03-Concepts/.md` note). The skill globs recently-modified files (capped at 500), extracts entities/concepts/tags/actions/sentiment markers, clusters semantically, names each cluster per the operator's anti-jargon naming DNA, scores + ranks, and reports the top 10. +Read the `emerge` skill at `skills/emerge/SKILL.md`, then run the workflow. Flags: `--days N` (default 30), `--scope ` (restrict to a folder), `--min-cluster N` (default 3, clusters below this are treated as noise), `--audit` (non-interactive mode for the scheduled Sunday 9pm agent — writes to `01-Projects/VAULT/conversations/reports/emerge-YYYY-WW.md`), `--promote ` (skip mining and promote a previously-identified cluster to a full `03-Concepts/.md` note). The skill globs recently-modified files (capped at 500), extracts entities/concepts/tags/actions/sentiment markers, clusters semantically, names each cluster per Nate's anti-jargon naming DNA, scores + ranks, and reports the top 10. diff --git a/commands/tether.md b/commands/tether.md index 401d8cd..0455515 100644 --- a/commands/tether.md +++ b/commands/tether.md @@ -2,4 +2,4 @@ description: "Repair orphaned notes and bidirectionally link projects, sub-projects, MOCs, and hubs — closes broken graph bridges." --- -Read the `tether` skill at `skills/tether/SKILL.md`, then run the workflow. Flags: `--scope ` or `--all` (mutually exclusive), `--dry-run` (default, reports only) or `--execute` (atomic per-project fixes). The skill enforces the CLAUDE.md tethering rules: filename-equals-folder (no `-Index` suffix), bidirectional UP/DOWN links, `04-Index/Projects-Index.md` membership, client-work-to-org-hub tethering (`[[]]`), and code-project-to-`[[GITHUB]]` tethering. Violations classify into filename mismatches, missing Projects-Index entries, broken bidirectional links, and unlinked mentions (surfaced to `Claude-Memory/tether-candidates-YYYY-MM-DD.md`, never auto-converted). Respects `tether: none` frontmatter opt-outs. Never touches anything inside `01-Projects/GITHUB///` or deletes notes. +Read the `tether` skill at `skills/tether/SKILL.md`, then run the workflow. Flags: `--scope ` or `--all` (mutually exclusive), `--dry-run` (default, reports only) or `--execute` (atomic per-project fixes). The skill enforces the CLAUDE.md tethering rules: filename-equals-folder (no `-Index` suffix), bidirectional UP/DOWN links, `04-Index/Projects-Index.md` membership, client-work-to-org-hub tethering (`[[LORECRAFT-HQ]]`), and code-project-to-`[[GITHUB]]` tethering. Violations classify into filename mismatches, missing Projects-Index entries, broken bidirectional links, and unlinked mentions (surfaced to `Claude-Memory/tether-candidates-YYYY-MM-DD.md`, never auto-converted). Respects `tether: none` frontmatter opt-outs. Never touches anything inside `01-Projects/GITHUB///` or deletes notes. diff --git a/config/nathan.pii.example b/config/nathan.pii.example index 08123d9..b8fb977 100644 --- a/config/nathan.pii.example +++ b/config/nathan.pii.example @@ -1,4 +1,4 @@ -***REMOVED*** +# ============================================================================ # config/nathan.pii.example — template for the local PII sweep pattern list # ---------------------------------------------------------------------------- # The real patterns live in config/nathan.pii, which is GITIGNORED so the @@ -16,7 +16,7 @@ # # Invocation: # bash scripts/prepublish-check.sh -***REMOVED*** +# ============================================================================ # Owner attribution (keep your public author email here, for reference; the # prepublish sweep allowlists it — this is not an exclusion list for secrets, diff --git a/config/secrets.patterns b/config/secrets.patterns index c23428a..bac61f1 100644 --- a/config/secrets.patterns +++ b/config/secrets.patterns @@ -1,4 +1,4 @@ -***REMOVED*** +# ============================================================================ # config/secrets.patterns — bash-sourceable regex arrays # ---------------------------------------------------------------------------- # Two arrays: @@ -13,7 +13,7 @@ # done # # Patterns are ERE-flavored so they work with `grep -E` on macOS + Linux. -***REMOVED*** +# ============================================================================ # ---------------------------------------------------------------------------- # HARDBLOCK — exit non-zero on any match. Deny list. No overrides. diff --git a/docs/CLAUDE-MD-PATCH.md b/docs/CLAUDE-MD-PATCH.md index 9324f1c..6ef21cb 100644 --- a/docs/CLAUDE-MD-PATCH.md +++ b/docs/CLAUDE-MD-PATCH.md @@ -119,7 +119,7 @@ Scheduled agents are audit-only by default. Any write-capable scheduled agent re These override every skill-local policy. A skill that skips one of these is broken and must be halted. -1. **Backup before mutation.** Before any multi-file structural change, tarball the vault to `~/WORK/-BACKUPS/-backup-*.tar.gz` — NEVER `~/Desktop/` (TCC-protected on modern macOS, and Desktop tarballs are forbidden outright). Before overwriting ANY single file that already exists, snapshot it to `Claude-Memory/backups/YYYY-MM-DD/HHMMSS--.bak`. If the backup write fails (disk full, permissions), abort the primary write. No exceptions. +1. **Backup before mutation.** Before any multi-file structural change, tarball the vault to `~/Desktop/2ndBrain-backup-*.tar.gz`. Before overwriting ANY single file that already exists, snapshot it to `Claude-Memory/backups/YYYY-MM-DD/HHMMSS--.bak`. If the backup write fails (disk full, permissions), abort the primary write. No exceptions. 2. **Stop-hook jq-merge discipline.** The `Stop` hook payload MUST be merged into `~/.claude/settings.json` using `jq --slurp 'add'` semantics — never naive concatenation, never overwrite. Raw string append corrupts settings and breaks `/save --backfill --resume`. If `jq` is unavailable on the system path, the hook prints a WARN and no-ops rather than writing partial state. 3. **n8n path filters stay current.** Any skill that adds a new top-level vault folder or a new externally-synced `01-Projects///` subtree MUST update the n8n W1 path filter so the new subtree is ingested. The W1/W2 filters have been migrated from legacy `08-Tasks/` to `05-Tasks/` as of the 2026-04-17 swarm; W2 phantom-write prefix is removed, defensive strippers are left as no-ops. (W3 was deprecated 2026-05-04 when Notion was dropped from the sync stack.) The canonical path-filter file lives in the private `obsidian-tasks-sync` config repo — if it is not mounted, the skill prints a TODO row in its report and continues rather than silently creating an untracked subtree. diff --git a/docs/CREDITS.md b/docs/CREDITS.md index 9c451ca..536b3a0 100644 --- a/docs/CREDITS.md +++ b/docs/CREDITS.md @@ -6,7 +6,7 @@ ### Andrej Karpathy — LLM Wiki gist -- **Source:** https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f +- **Source:** https://gist.github.com/karpathy/3d3797cfe72b4fd78dab7a5c35caf0f9 - **License:** not formally stated; public gist, treated as reference / fair use. I do not copy verbatim code from the gist into this pack. - **What I took:** - The compilation-over-retrieval thesis (core rationale in `PHILOSOPHY.md`) @@ -64,23 +64,23 @@ ### claude-flow / agentic-flow (ruvnet) — Intelligence Loop -- **Source:** https://github.com/ruvnet/ruflo (re-shipped through the fork `fidgetcoding/fidgetflo`, which was squash-imported from ruflo v3.5.80 and has since diverged) -- **License:** MIT (c) 2024-2026 ruvnet, with / the operator (c) 2026 additions. The FidgetFlo LICENSE preserves ruvnet's original copyright alongside 's rebrand + extension additions. -- **What I took:** the entire **self-learning intelligence tier** — ADR-050's pattern-graph routing loop and the ADR-048/049 auto-memory bridge. The vendored files under `helpers/` (`intelligence.cjs`, `router.js`, `hook-handler.cjs`, `auto-memory-hook.mjs`, `pattern-consolidator.sh`, `learning-hooks.sh`, `learning-optimizer.sh`, `learning-service.mjs`, `memory.js`, `session.js`, `metrics-db.mjs`) are copied from the FidgetFlo build — a FidgetFlo-internal descendant of ruvnet/ruflo@v3.5.80 with extended pattern-graph logic on top of the upstream. They are **not byte-identical to upstream ruflo**: an audit pass against ruflo@v3.5.80 confirmed divergence in the pattern-graph code paths. Each file carries a provenance header documenting the ruflo ancestry, the FidgetFlo extension, and the dual copyright. +- **Source:** https://github.com/ruvnet/ruflo (re-shipped through the Lorecraft fork `fidgetcoding/fidgetflo`, which was squash-imported from ruflo v3.5.80 and has since diverged) +- **License:** MIT (c) 2024-2026 ruvnet, with Lorecraft LLC / Nate Davidovich (c) 2026 additions. The FidgetFlo LICENSE preserves ruvnet's original copyright alongside Lorecraft's rebrand + extension additions. +- **What I took:** the entire **self-learning intelligence tier** — ADR-050's pattern-graph routing loop and the ADR-048/049 auto-memory bridge. The vendored files under `helpers/` (`intelligence.cjs`, `router.js`, `hook-handler.cjs`, `auto-memory-hook.mjs`, `pattern-consolidator.sh`, `learning-hooks.sh`, `learning-optimizer.sh`, `learning-service.mjs`, `memory.js`, `session.js`, `metrics-db.mjs`) are copied from the Lorecraft FidgetFlo build — a FidgetFlo-internal descendant of ruvnet/ruflo@v3.5.80 with extended pattern-graph logic on top of the upstream. They are **not byte-identical to upstream ruflo**: an audit pass against ruflo@v3.5.80 confirmed divergence in the pattern-graph code paths. Each file carries a provenance header documenting the ruflo ancestry, the FidgetFlo extension, and the dual copyright. - **How it wires in:** the optional `install.sh --with-intelligence` flag hardlinks the helpers into `$VAULT/.claude/helpers/` and jq-merges 5 hook types (PreToolUse / PostToolUse / UserPromptSubmit / SessionStart / SessionEnd) into `~/.claude/settings.json`. The mogging Stop hook from `hooks/stop-save.sh` is preserved via append-merge, never replaced. -- **Attribution:** every vendored file carries a provenance header naming the ruflo v3.5.80 ancestor, the FidgetFlo intermediate build, and the pattern-graph extension. The README Credits section lists this as the sixth upstream. This tier is opt-in so existing mogging users don't get surprise hooks. +- **Attribution:** every vendored file carries a provenance header naming the ruflo v3.5.80 ancestor, the FidgetFlo intermediate build, and the Lorecraft pattern-graph extension. The README Credits section lists this as the sixth upstream. This tier is opt-in so existing mogging users don't get surprise hooks. ## Secondary influences (three) ### rohitg00 — LLM-Wiki-v2 -- **Source:** `rohitg00/LLM-Wiki-v2` on GitHub (repo since deleted — link dead as of 2026-06-12; attribution preserved). +- **Source:** https://github.com/rohitg00/LLM-Wiki-v2 - **License:** check repository. - **What I took:** the template-per-output-type idea, applied narrowly to source notes in `02-Sources/` (the pack's equivalent of the upstream `02-Literature/` folder). The broader template catalog was not adopted. ### huytieu — COG (Chain-of-Going) -- **Source:** https://github.com/huytieu/COG-second-brain (the original `huytieu/COG` URL is dead; the project now expands COG as "Cognition + Obsidian + Git") +- **Source:** https://github.com/huytieu/COG - **License:** check repository. - **What I took:** the visible-trajectory pattern — the LLM commits to its next steps explicitly before executing them. Used in `/autoresearch` round transitions. The open-ended chain format was not adopted; my research loop is bounded to three rounds. diff --git a/docs/MIGRATION.md b/docs/MIGRATION.md index f72bd60..62922d0 100644 --- a/docs/MIGRATION.md +++ b/docs/MIGRATION.md @@ -33,12 +33,9 @@ Killed folders: `00-Inbox/`, `01-Fleeting/`, `05-Templates/`, `06-Assets/`. cd /path/to/2ndBrain git tag v0-pre-migration git push origin v0-pre-migration -mkdir -p ~/WORK/2ndBrain-BACKUPS -tar czf ~/WORK/2ndBrain-BACKUPS/2ndBrain-backup-$(date +%Y%m%d-%H%M%S).tar.gz . +tar czf ~/Desktop/2ndBrain-backup-$(date +%Y%m%d-%H%M%S).tar.gz . ``` -(Never tarball to `~/Desktop/` — it's TCC permission-protected on modern macOS and Desktop tarballs are forbidden by non-negotiable #1.) - The tag is your full-rollback anchor. The tarball is your oh-shit anchor if git itself corrupts. --- @@ -280,7 +277,7 @@ grep -c '' CLAUDE.md | Last step only | `git reset --hard HEAD~1` | | Last N steps | `git reset --hard HEAD~N` | | Full rollback to pre-migration | `git reset --hard v0-pre-migration` | -| Tarball (git corrupted) | `tar xzf ~/WORK/2ndBrain-BACKUPS/2ndBrain-backup-*.tar.gz -C /tmp/restore` | +| Tarball (git corrupted) | `tar xzf ~/Desktop/2ndBrain-backup-*.tar.gz -C /tmp/restore` | Phase boundaries are natural checkpoints. If Phase C surfaces 200+ broken wikilinks, reset to end of Phase B and fix in a branch before proceeding. diff --git a/docs/PARSING-GUIDE.md b/docs/PARSING-GUIDE.md index 3cbb5d4..50a0fef 100644 --- a/docs/PARSING-GUIDE.md +++ b/docs/PARSING-GUIDE.md @@ -24,7 +24,7 @@ This is the post-mogging vault layout. The folders below are the only writable t ### `01-Projects//conversations/` (post-2026-05-08; `01-Projects//conversations/` was retired) — full-fidelity chat captures - Output of `/save` and `/import-claude`. -- Subfolder-mirrors the structure of `01-Projects/` (so `/` conversations land under `01-Projects//conversations/`). +- Subfolder-mirrors the structure of `01-Projects/` (so `FIDGETCODING/` conversations land under `01-Projects/FIDGETCODING/conversations/`). - Filename: `YYYY-MM-DD-.md`. - Frontmatter: `type: conversation`, `owner: human` — blocks future auto-mutation. - A `VAULT/` subtree holds vault-about-vault captures (conversations *about* the system itself). diff --git a/docs/SECURITY.md b/docs/SECURITY.md index 8471255..88f9f92 100644 --- a/docs/SECURITY.md +++ b/docs/SECURITY.md @@ -14,7 +14,7 @@ vulnerabilities. - Preferred: open a private advisory via GitHub Security Advisories — -- Backup channel: email `operator@example.com` with `[security]` in the +- Backup channel: email `nate@lorecraft.io` with `[security]` in the subject line. - Expected first response: within **72 hours** on weekdays - Please include: @@ -99,7 +99,7 @@ The repo runs two independent secret scanners and one PII sweep. - PEM private keys of any kind - Morgen API keys (via custom gitleaks rule `morgen-api`) - n8n PATs (via custom gitleaks rule `n8n-api`) -- Owner email `operator@example.com` and private collaborator first names +- Owner email `nate@lorecraft.io` and private collaborator first names (via `config/nathan.pii`) **What gets flagged for manual review:** diff --git a/docs/claude-project-sync-guide.md b/docs/claude-project-sync-guide.md index 70161e9..808550b 100644 --- a/docs/claude-project-sync-guide.md +++ b/docs/claude-project-sync-guide.md @@ -15,7 +15,7 @@ How to route the contents of a single Claude.ai Project (or ChatGPT folder) into assets/ ← real binaries only (PDFs, zips — things that can't be markdown) ``` -The index filename **must match the folder name exactly** — `/.md`, not `/-Index.md`. This is the vault-wide rule (see [`CLAUDE.md`](../CLAUDE.md)). +The index filename **must match the folder name exactly** — `PARZVL/PARZVL.md`, not `PARZVL/PARZVL-Index.md`. This is the vault-wide rule (see [`CLAUDE.md`](../CLAUDE.md)). --- diff --git a/docs/foundations/01-karpathy-canonical.md b/docs/foundations/01-karpathy-canonical.md index 3684417..1b32a24 100644 --- a/docs/foundations/01-karpathy-canonical.md +++ b/docs/foundations/01-karpathy-canonical.md @@ -2,7 +2,7 @@ The `LLM Wiki` gist by Andrej Karpathy is the origin point for the second-brain-over-Claude-Code genre. This foundations note captures the exact primitives as Karpathy described them, so that downstream skills in this pack can be understood as specific extensions of a well-defined base. -Source: https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f +Source: https://gist.github.com/karpathy/3d3797cfe72b4fd78dab7a5c35caf0f9 ## The primitives diff --git a/docs/foundations/05-extensions-analysis.md b/docs/foundations/05-extensions-analysis.md index 33d4f6c..3f8eabc 100644 --- a/docs/foundations/05-extensions-analysis.md +++ b/docs/foundations/05-extensions-analysis.md @@ -2,9 +2,9 @@ This note covers three smaller projects that extend the Karpathy primitive in different directions. None of them is the primary influence on this pack, but each contributes a specific pattern worth naming. Sources: -- rohitg00/LLM-Wiki-v2 — repo since deleted from GitHub (link dead as of 2026-06-12) +- rohitg00/LLM-Wiki-v2 — https://github.com/rohitg00/LLM-Wiki-v2 - NicholasSpisak/second-brain — https://github.com/NicholasSpisak/second-brain -- huytieu/COG — https://github.com/huytieu/COG-second-brain (original `huytieu/COG` URL is dead) +- huytieu/COG — https://github.com/huytieu/COG ## rohitg00/LLM-Wiki-v2 diff --git a/docs/github-vault-guide.md b/docs/github-vault-guide.md index cb8c67e..8f90a00 100644 --- a/docs/github-vault-guide.md +++ b/docs/github-vault-guide.md @@ -54,7 +54,7 @@ gh repo view YOUR-ORG/REPO-NAME Once connected, you can tell Claude things like: -- "Check the `` repo for the latest README and update my vault." +- "Check the `wagmi` repo for the latest README and update my vault." - "Pull the spec from the `clocked-hq` repo into my project notes." - "Search my GitHub repos for anything about authentication and put the hits into `03-Concepts/`." diff --git a/docs/placeholder-names.md b/docs/placeholder-names.md index 69ef356..646e6fa 100644 --- a/docs/placeholder-names.md +++ b/docs/placeholder-names.md @@ -6,9 +6,6 @@ This skill pack is an **operator's personal vault tooling**. It was extracted fr Before this repo was made public, every real personal name and every private client-project name was redacted and replaced with a **stable placeholder**. You will see tokens like the following throughout the skills, commands, agents, tests, and sample memory: -- `the operator` — the person who built and runs this vault. Appears in prose where the operator's name would otherwise be used. -- `operator@example.com` — the operator's email address. -- `` through `` — the operator's own organizations, brands, and project hubs (LLCs, GitHub orgs, branded project folders). These are distinct from `` tokens, which represent *client* projects. - ``, ``, ``, ... — individual humans (collaborators, clients, cofounders, teammates, vendors) - ``, ``, ... — peers in ongoing conversations where the human is not a client but is named in the transcript - ``, ``, ... — private client projects, product names, or internal codenames that the operator does not want associated with their public-facing work @@ -36,8 +33,6 @@ When you install this pack into your own vault, your `Claude-Memory/aliases.yaml The current public release uses the following placeholder families. New placeholders may be added as the pack grows; removed placeholders are never re-used. -- `the operator` / `operator@example.com` — the vault operator's identity and email -- `` through `` — 5 operator-owned organizations and brands - `` through `` — 9 individuals - `` through `` — 3 client projects diff --git a/helpers/auto-memory-hook.mjs b/helpers/auto-memory-hook.mjs index 4b98504..2bb6d3b 100644 --- a/helpers/auto-memory-hook.mjs +++ b/helpers/auto-memory-hook.mjs @@ -1,8 +1,8 @@ #!/usr/bin/env node -/* Vendored from FidgetFlo (fidgetcoding/fidgetflo) — a FidgetFlo-internal build +/* Vendored from FidgetFlo (lorecraft-io/fidgetflo) — a FidgetFlo-internal build * descended from ruvnet/ruflo@v3.5.80 with additional pattern-graph logic - * extended by . Upstream: https://github.com/ruvnet/ruflo/tree/v3.5.80 - * License: MIT (c) 2024-2026 ruvnet, (c) 2026 / the operator + * extended by Lorecraft. Upstream: https://github.com/ruvnet/ruflo/tree/v3.5.80 + * License: MIT (c) 2024-2026 ruvnet, (c) 2026 Lorecraft LLC / Nate Davidovich * Synced: 2026-04-20 * See: docs/CREDITS.md for the full attribution chain + NOTICE for license text. */ diff --git a/helpers/hook-handler.cjs b/helpers/hook-handler.cjs index 88bf74f..ecf2c89 100644 --- a/helpers/hook-handler.cjs +++ b/helpers/hook-handler.cjs @@ -1,8 +1,8 @@ #!/usr/bin/env node -/* Vendored from FidgetFlo (fidgetcoding/fidgetflo) — a FidgetFlo-internal build +/* Vendored from FidgetFlo (lorecraft-io/fidgetflo) — a FidgetFlo-internal build * descended from ruvnet/ruflo@v3.5.80 with additional pattern-graph logic - * extended by . Upstream: https://github.com/ruvnet/ruflo/tree/v3.5.80 - * License: MIT (c) 2024-2026 ruvnet, (c) 2026 / the operator + * extended by Lorecraft. Upstream: https://github.com/ruvnet/ruflo/tree/v3.5.80 + * License: MIT (c) 2024-2026 ruvnet, (c) 2026 Lorecraft LLC / Nate Davidovich * Synced: 2026-04-20 * See: docs/CREDITS.md for the full attribution chain + NOTICE for license text. */ diff --git a/helpers/intelligence.cjs b/helpers/intelligence.cjs index 3235836..e8a47ce 100644 --- a/helpers/intelligence.cjs +++ b/helpers/intelligence.cjs @@ -1,8 +1,8 @@ #!/usr/bin/env node -/* Vendored from FidgetFlo (fidgetcoding/fidgetflo) — a FidgetFlo-internal build +/* Vendored from FidgetFlo (lorecraft-io/fidgetflo) — a FidgetFlo-internal build * descended from ruvnet/ruflo@v3.5.80 with additional pattern-graph logic - * extended by . Upstream: https://github.com/ruvnet/ruflo/tree/v3.5.80 - * License: MIT (c) 2024-2026 ruvnet, (c) 2026 / the operator + * extended by Lorecraft. Upstream: https://github.com/ruvnet/ruflo/tree/v3.5.80 + * License: MIT (c) 2024-2026 ruvnet, (c) 2026 Lorecraft LLC / Nate Davidovich * Synced: 2026-04-20 * See: docs/CREDITS.md for the full attribution chain + NOTICE for license text. */ diff --git a/helpers/learning-hooks.sh b/helpers/learning-hooks.sh index 5e629b6..9d112b2 100644 --- a/helpers/learning-hooks.sh +++ b/helpers/learning-hooks.sh @@ -1,8 +1,8 @@ -#!/usr/bin/env bash -# Vendored from FidgetFlo (fidgetcoding/fidgetflo) — a FidgetFlo-internal build +#!/bin/bash +# Vendored from FidgetFlo (lorecraft-io/fidgetflo) — a FidgetFlo-internal build # descended from ruvnet/ruflo@v3.5.80 with additional pattern-graph logic -# extended by . Upstream: https://github.com/ruvnet/ruflo/tree/v3.5.80 -# License: MIT (c) 2024-2026 ruvnet, (c) 2026 / the operator +# extended by Lorecraft. Upstream: https://github.com/ruvnet/ruflo/tree/v3.5.80 +# License: MIT (c) 2024-2026 ruvnet, (c) 2026 Lorecraft LLC / Nate Davidovich # Synced: 2026-04-20 # See: docs/CREDITS.md for the full attribution chain + NOTICE for license text. # @@ -44,9 +44,9 @@ generate_session_id() { echo "session_$(date +%Y%m%d_%H%M%S)_$$" } -# ============================================================================ +# ============================================================================= # Session Start Hook -# ============================================================================ +# ============================================================================= session_start() { local session_id="${1:-$(generate_session_id)}" @@ -97,9 +97,9 @@ EOF fi } -# ============================================================================ +# ============================================================================= # Session End Hook -# ============================================================================ +# ============================================================================= session_end() { log "Consolidating learning data..." @@ -158,9 +158,9 @@ session_end() { return 0 } -# ============================================================================ +# ============================================================================= # Store Pattern (called by post-edit hooks) -# ============================================================================ +# ============================================================================= store_pattern() { local strategy="$1" local domain="${2:-general}" @@ -197,9 +197,9 @@ store_pattern() { fi } -# ============================================================================ +# ============================================================================= # Search Patterns (called by pre-edit hooks) -# ============================================================================ +# ============================================================================= search_patterns() { local query="$1" local k="${2:-3}" @@ -230,9 +230,9 @@ search_patterns() { fi } -# ============================================================================ +# ============================================================================= # Record Pattern Usage (for promotion tracking) -# ============================================================================ +# ============================================================================= record_usage() { local pattern_id="$1" local success="${2:-true}" @@ -246,9 +246,9 @@ record_usage() { log "Recording usage: $pattern_id (success=$success)" } -# ============================================================================ +# ============================================================================= # Run Benchmark -# ============================================================================ +# ============================================================================= run_benchmark() { log "Running HNSW benchmark..." @@ -273,9 +273,9 @@ run_benchmark() { fi } -# ============================================================================ +# ============================================================================= # Get Stats -# ============================================================================ +# ============================================================================= get_stats() { local result if result=$(node "$LEARNING_SERVICE" stats 2>&1); then @@ -287,28 +287,24 @@ get_stats() { fi } -# ============================================================================ +# ============================================================================= # Main -# ============================================================================ +# ============================================================================= case "${1:-help}" in "session-start"|"start") - # ${N:-} defaults are load-bearing: this file runs under `set -u`, so a - # bare "$2" crashes with "unbound variable" on every documented - # optional-arg invocation (e.g. `learning-hooks.sh session-start`, - # `store "strategy"`). The functions own the real defaults. - session_start "${2:-}" + session_start "$2" ;; "session-end"|"end") session_end ;; "store") - store_pattern "${2:-}" "${3:-}" "${4:-}" + store_pattern "$2" "$3" "$4" ;; "search") - search_patterns "${2:-}" "${3:-}" + search_patterns "$2" "$3" ;; "record-usage"|"usage") - record_usage "${2:-}" "${3:-}" + record_usage "$2" "$3" ;; "benchmark") run_benchmark diff --git a/helpers/learning-optimizer.sh b/helpers/learning-optimizer.sh index d149fa6..69a8338 100644 --- a/helpers/learning-optimizer.sh +++ b/helpers/learning-optimizer.sh @@ -1,8 +1,8 @@ -#!/usr/bin/env bash -# Vendored from FidgetFlo (fidgetcoding/fidgetflo) — a FidgetFlo-internal build +#!/bin/bash +# Vendored from FidgetFlo (lorecraft-io/fidgetflo) — a FidgetFlo-internal build # descended from ruvnet/ruflo@v3.5.80 with additional pattern-graph logic -# extended by . Upstream: https://github.com/ruvnet/ruflo/tree/v3.5.80 -# License: MIT (c) 2024-2026 ruvnet, (c) 2026 / the operator +# extended by Lorecraft. Upstream: https://github.com/ruvnet/ruflo/tree/v3.5.80 +# License: MIT (c) 2024-2026 ruvnet, (c) 2026 Lorecraft LLC / Nate Davidovich # Synced: 2026-04-20 # See: docs/CREDITS.md for the full attribution chain + NOTICE for license text. # @@ -75,11 +75,6 @@ optimize_patterns() { short_count=$(sqlite3 "$PATTERNS_DB" "SELECT COUNT(*) FROM short_term_patterns" 2>/dev/null || echo "0") long_count=$(sqlite3 "$PATTERNS_DB" "SELECT COUNT(*) FROM long_term_patterns" 2>/dev/null || echo "0") avg_quality=$(sqlite3 "$PATTERNS_DB" "SELECT ROUND(AVG(quality), 3) FROM short_term_patterns" 2>/dev/null || echo "0") - # AVG() over zero rows is NULL → sqlite3 prints an empty string and the - # `|| echo 0` above never fires (the query itself succeeded). Without this - # default, the learning.json heredoc below emits `"avgQuality": ,` — - # invalid JSON that breaks the `status` subcommand's jq read. - avg_quality="${avg_quality:-0}" routing_accuracy=$(calculate_routing_accuracy) # Calculate intelligence score diff --git a/helpers/learning-service.mjs b/helpers/learning-service.mjs index cf96e35..fdb73a3 100644 --- a/helpers/learning-service.mjs +++ b/helpers/learning-service.mjs @@ -1,8 +1,8 @@ #!/usr/bin/env node -/* Vendored from FidgetFlo (fidgetcoding/fidgetflo) — a FidgetFlo-internal build +/* Vendored from FidgetFlo (lorecraft-io/fidgetflo) — a FidgetFlo-internal build * descended from ruvnet/ruflo@v3.5.80 with additional pattern-graph logic - * extended by . Upstream: https://github.com/ruvnet/ruflo/tree/v3.5.80 - * License: MIT (c) 2024-2026 ruvnet, (c) 2026 / the operator + * extended by Lorecraft. Upstream: https://github.com/ruvnet/ruflo/tree/v3.5.80 + * License: MIT (c) 2024-2026 ruvnet, (c) 2026 Lorecraft LLC / Nate Davidovich * Synced: 2026-04-20 * See: docs/CREDITS.md for the full attribution chain + NOTICE for license text. */ diff --git a/helpers/memory.js b/helpers/memory.js index beb3039..03bb715 100644 --- a/helpers/memory.js +++ b/helpers/memory.js @@ -1,9 +1,9 @@ #!/usr/bin/env node -/* Vendored from FidgetFlo (fidgetcoding/fidgetflo) — a FidgetFlo-internal build +/* Vendored from FidgetFlo (lorecraft-io/fidgetflo) — a FidgetFlo-internal build * descended from ruvnet/ruflo@v3.5.80 with additional pattern-graph logic - * extended by . This file is FidgetFlo-era (not present in the ruflo + * extended by Lorecraft. This file is FidgetFlo-era (not present in the ruflo * v3.5.80 public tag). Upstream root: https://github.com/ruvnet/ruflo/tree/v3.5.80 - * License: MIT (c) 2024-2026 ruvnet, (c) 2026 / the operator + * License: MIT (c) 2024-2026 ruvnet, (c) 2026 Lorecraft LLC / Nate Davidovich * Synced: 2026-04-20 * See: docs/CREDITS.md for the full attribution chain + NOTICE for license text. */ diff --git a/helpers/metrics-db.mjs b/helpers/metrics-db.mjs index 8493bcb..1d0bf1e 100644 --- a/helpers/metrics-db.mjs +++ b/helpers/metrics-db.mjs @@ -1,8 +1,8 @@ #!/usr/bin/env node -/* Vendored from FidgetFlo (fidgetcoding/fidgetflo) — a FidgetFlo-internal build +/* Vendored from FidgetFlo (lorecraft-io/fidgetflo) — a FidgetFlo-internal build * descended from ruvnet/ruflo@v3.5.80 with additional pattern-graph logic - * extended by . Upstream: https://github.com/ruvnet/ruflo/tree/v3.5.80 - * License: MIT (c) 2024-2026 ruvnet, (c) 2026 / the operator + * extended by Lorecraft. Upstream: https://github.com/ruvnet/ruflo/tree/v3.5.80 + * License: MIT (c) 2024-2026 ruvnet, (c) 2026 Lorecraft LLC / Nate Davidovich * Synced: 2026-04-20 * See: docs/CREDITS.md for the full attribution chain + NOTICE for license text. */ diff --git a/helpers/pattern-consolidator.sh b/helpers/pattern-consolidator.sh index 3f055f7..8e17805 100644 --- a/helpers/pattern-consolidator.sh +++ b/helpers/pattern-consolidator.sh @@ -1,8 +1,8 @@ -#!/usr/bin/env bash -# Vendored from FidgetFlo (fidgetcoding/fidgetflo) — a FidgetFlo-internal build +#!/bin/bash +# Vendored from FidgetFlo (lorecraft-io/fidgetflo) — a FidgetFlo-internal build # descended from ruvnet/ruflo@v3.5.80 with additional pattern-graph logic -# extended by . Upstream: https://github.com/ruvnet/ruflo/tree/v3.5.80 -# License: MIT (c) 2024-2026 ruvnet, (c) 2026 / the operator +# extended by Lorecraft. Upstream: https://github.com/ruvnet/ruflo/tree/v3.5.80 +# License: MIT (c) 2024-2026 ruvnet, (c) 2026 Lorecraft LLC / Nate Davidovich # Synced: 2026-04-20 # See: docs/CREDITS.md for the full attribution chain + NOTICE for license text. # diff --git a/helpers/router.js b/helpers/router.js index 2156dec..af3e678 100644 --- a/helpers/router.js +++ b/helpers/router.js @@ -1,9 +1,9 @@ #!/usr/bin/env node -/* Vendored from FidgetFlo (fidgetcoding/fidgetflo) — a FidgetFlo-internal build +/* Vendored from FidgetFlo (lorecraft-io/fidgetflo) — a FidgetFlo-internal build * descended from ruvnet/ruflo@v3.5.80 with additional pattern-graph logic - * extended by . This file is FidgetFlo-era (not present in the ruflo + * extended by Lorecraft. This file is FidgetFlo-era (not present in the ruflo * v3.5.80 public tag). Upstream root: https://github.com/ruvnet/ruflo/tree/v3.5.80 - * License: MIT (c) 2024-2026 ruvnet, (c) 2026 / the operator + * License: MIT (c) 2024-2026 ruvnet, (c) 2026 Lorecraft LLC / Nate Davidovich * Synced: 2026-04-20 * See: docs/CREDITS.md for the full attribution chain + NOTICE for license text. */ diff --git a/helpers/session.js b/helpers/session.js index d6990a3..7de7c5b 100644 --- a/helpers/session.js +++ b/helpers/session.js @@ -1,9 +1,9 @@ #!/usr/bin/env node -/* Vendored from FidgetFlo (fidgetcoding/fidgetflo) — a FidgetFlo-internal build +/* Vendored from FidgetFlo (lorecraft-io/fidgetflo) — a FidgetFlo-internal build * descended from ruvnet/ruflo@v3.5.80 with additional pattern-graph logic - * extended by . This file is FidgetFlo-era (not present in the ruflo + * extended by Lorecraft. This file is FidgetFlo-era (not present in the ruflo * v3.5.80 public tag). Upstream root: https://github.com/ruvnet/ruflo/tree/v3.5.80 - * License: MIT (c) 2024-2026 ruvnet, (c) 2026 / the operator + * License: MIT (c) 2024-2026 ruvnet, (c) 2026 Lorecraft LLC / Nate Davidovich * Synced: 2026-04-20 * See: docs/CREDITS.md for the full attribution chain + NOTICE for license text. */ diff --git a/install.sh b/install.sh index 2a5c211..9fbc5da 100755 --- a/install.sh +++ b/install.sh @@ -238,7 +238,7 @@ preflight() { fi vlog "claude version ok: $raw" - # install-call (2026-04-22): three teammates hit a silent obsidian-mcp + # WAGMI install-call (2026-04-22): three teammates hit a silent obsidian-mcp # failure caused by `~/.npm` being root-owned (legacy `sudo npm install` # damage). The error messages we used to print referenced "npm cache fix" — # which is NOT a real npm subcommand, just internal jargon. The real fix is @@ -247,12 +247,12 @@ preflight() { check_npm_cache_ownership } -# ---- npm cache ownership check (post- 2026-04-22) ---------------------- +# ---- npm cache ownership check (post-WAGMI 2026-04-22) ---------------------- # # Detect the legacy `sudo npm install` damage (root-owned ~/.npm) and print # the LITERAL fix the user can paste. Non-fatal — we warn, then continue, # because most npx invocations will still work; obsidian-mcp + magic-mcp are -# the two known canaries that fail silently on this. See install-call +# the two known canaries that fail silently on this. See WAGMI install-call # transcript 2026-04-22 for full repro. # # IMPORTANT: do NOT print "run npm cache fix" — that string was the original @@ -283,7 +283,7 @@ check_npm_cache_ownership() { # ---- step 1.5: ensure Obsidian.app is installed ----------------------------- # -# install-call (2026-04-22) — three teammates independently hit the same +# WAGMI install-call (2026-04-22) — three teammates independently hit the same # wall: they didn't have Obsidian.app installed yet, the vault folder didn't # exist, and install.sh bailed at step 2. Auto-install the desktop client on # macOS via Homebrew so the rest of the pipeline can proceed. Idempotent @@ -368,7 +368,7 @@ validate_vault() { fi if [[ -n "$VAULT" && ! -d "$VAULT" ]]; then - # install-call (2026-04-22): teammates were getting bounced here when + # WAGMI install-call (2026-04-22): teammates were getting bounced here when # they'd just installed Obsidian and the vault folder didn't exist yet # (e.g. Obsidian created `~/BRAIN2` but they passed # `--vault ~/BRAIN2/`-with-typo, OR they hadn't opened Obsidian @@ -531,14 +531,9 @@ JSON local ours_already_present=0 if [[ -f "$SETTINGS_PATH" ]]; then existing_stop_count="$(jq '(.hooks.Stop // []) | length' "$SETTINGS_PATH" 2>/dev/null || echo 0)" - # Idempotency guard: detect if our own hook is already present by path - # fingerprint. Match on the script name only, case-insensitively — the - # checkout dir is user-chosen (often lowercase `2ndbrain-mogging`), so - # fingerprinting on the repo dir name misses real installs and re-runs - # append duplicate hooks. - if jq -e --arg p "hooks/stop-save.sh" ' - (.hooks.Stop // []) | map(.hooks // []) | add | map(.command // "") - | any(ascii_downcase | contains($p)) + # Idempotency guard: detect if our own hook is already present by path fingerprint. + if jq -e --arg p "2ndBrain-mogging/hooks/stop-" ' + (.hooks.Stop // []) | map(.hooks // []) | add | map(.command // "") | any(contains($p)) ' "$SETTINGS_PATH" >/dev/null 2>&1; then ours_already_present=1 fi @@ -591,17 +586,11 @@ JSON else # Append: concat .hooks.Stop arrays, keep rest of settings via deep merge, # then overwrite .hooks.Stop with the concatenation. - # NOTE: bind $old/$new BEFORE piping into the merged object — after `| $m` - # the pipeline context is an object, so `.[0]` would throw "Cannot index - # object with number" and silently punt every run to the fallback below. - # Same bug class as the merge_intelligence_hooks() fix in CHANGELOG 0.1.x - # (04c796e); this is the missed sibling instance. if ! jq -s ' - .[0] as $old - | .[1] as $new - | ($old * $new) + ( .[0] * .[1] ) as $m + | $m | .hooks = (.hooks // {}) - | .hooks.Stop = (($old.hooks.Stop // []) + ($new.hooks.Stop // [])) + | .hooks.Stop = ((.[0].hooks.Stop // []) + (.[1].hooks.Stop // [])) ' "$base" "$overlay_resolved" > "$merged" 2>/dev/null; then # Fallback: do it in two passes (older jq) if ! jq -s --slurpfile o <(cat "$overlay_resolved") ' @@ -679,7 +668,7 @@ link_claude_memory() { CLAUDE_MEMORY_SRC="$CLAUDE_HOME/projects/${encoded}/memory" vlog "claude memory src: $CLAUDE_MEMORY_SRC" - # install-call (2026-04-22): the previous behavior was "skip the + # WAGMI install-call (2026-04-22): the previous behavior was "skip the # symlink if the Claude-encoded project-memory dir doesn't exist yet," # which forced a 2-pass install (run cbrain once to make Claude Code mint # the dir, then re-run install.sh --apply to actually link it). Eliminate @@ -1427,14 +1416,7 @@ run_doctor() { log "step 12: doctor" local d="$REPO_ROOT/bin/doctor.sh" if [[ -x "$d" ]]; then - # Thread the resolved vault through — doctor must check the vault THIS - # install run targeted, not whatever ~/.claude/.mogging-vault points at - # from a previous install on the same machine. - local -a doctor_args=() - if [[ -n "$VAULT" ]]; then - doctor_args+=(--vault "$VAULT") - fi - if ! bash "$d" ${doctor_args[@]+"${doctor_args[@]}"}; then + if ! bash "$d"; then warn "doctor reported issues (non-fatal on install)" fi else @@ -1472,7 +1454,7 @@ run_doctor() { # step 11 run_tests tests/test_onboarding.sh (gated on --apply) # step 12 run_doctor bin/doctor.sh (non-fatal — issues warn only) # step 13 print_install_summary explicit on/off summary for self-learning tier + -# opt-out states (post- clarity fix) +# opt-out states (post-WAGMI clarity fix) # main() { @@ -1501,14 +1483,14 @@ main() { log "done." } -# ---- install summary (post- 2026-04-22 messaging) ---------------------- +# ---- install summary (post-WAGMI 2026-04-22 messaging) ---------------------- # # Three teammates thought their install was broken because they didn't see a # `helpers/` dir under the vault. Cause: --with-intelligence is opt-in, so # `helpers/` only appears when the flag is passed. Make the opt-in vs not # state explicit at the end of every install so nobody has to guess. # -# Also reminds about the Obsidian.app + npm-cache items so the fixes +# Also reminds about the Obsidian.app + npm-cache items so the WAGMI fixes # are visible at the top of the user's terminal scrollback when install ends. print_install_summary() { @@ -1533,7 +1515,7 @@ print_install_summary() { echo "└──────────────────────────────────────────────────────────────┘" echo "" - # install-call (2026-04-22) item 7: surface root-owned ~/.npm at + # WAGMI install-call (2026-04-22) item 7: surface root-owned ~/.npm at # the END of install so the fix is visible without running `doctor` # separately. We re-implement the cheap top-level scan inline rather # than sourcing bin/doctor.sh — keeps install.sh self-contained. diff --git a/references/wiki-schema.md b/references/wiki-schema.md index 624d52a..2f3fe23 100644 --- a/references/wiki-schema.md +++ b/references/wiki-schema.md @@ -19,7 +19,7 @@ Downstream consumers (all required to reference this file): ## 1. Folder contract -The vault follows the operator's stripped operator layout. The plugin treats each folder as having exactly one writer role plus a set of constraints. Skills that violate the writer role get hard-rejected in their own failure-mode table. +The vault follows Nate's stripped operator layout. The plugin treats each folder as having exactly one writer role plus a set of constraints. Skills that violate the writer role get hard-rejected in their own failure-mode table. | Folder | Role | Primary writer | Secondary writers | Constraints | |---|---|---|---|---| @@ -42,7 +42,7 @@ These override every skill-local policy. A skill that skips one of these must be 2. **Stop-hook-jq-merge.** The `Stop` hook payload MUST be merged into existing session state using `jq --slurp 'add'` semantics, never naive concatenation. Raw string append corrupts `Claude-Memory/sessions/.json` silently and breaks `/save --backfill --resume`. If `jq` is unavailable on the system path, the hook prints a WARN and no-ops rather than writing partial state. -3. **n8n-path-filter-update.** Any skill that adds a new vault subtree (new top-level folder, new `01-Projects///` with externally-synced tasks) MUST also update the n8n W1 path filter so the new subtree is ingested. The canonical path filter lives in `01-Projects//n8n-workflows/W1-paths.yaml` in the main vault. If that file is inaccessible (no symlink, no vault mounted), the skill prints a TODO row in its report and continues — it does not silently create untracked subtrees. +3. **n8n-path-filter-update.** Any skill that adds a new vault subtree (new top-level folder, new `01-Projects///` with externally-synced tasks) MUST also update the n8n W1 path filter so the new subtree is ingested. The canonical path filter lives in `01-Projects/LORECRAFT-HQ/n8n-workflows/W1-paths.yaml` in the main vault. If that file is inaccessible (no symlink, no vault mounted), the skill prints a TODO row in its report and continues — it does not silently create untracked subtrees. ## 3. Linking rules @@ -114,7 +114,7 @@ superseded_by: "[[ADR-012-new-name]]" # optional; filled when a later ADR ## 5. Obsidian Tasks plugin syntax -the operator's task pipeline (Obsidian ↔ Morgen via n8n W1/W2, orchestrated by `W0-Sync-Orchestrator`) is downstream of this exact shape. Rewriting tokens in the wrong order or dropping the UUID breaks sync. (Notion was dropped from the sync stack on 2026-05-04; the historical W3 worker is archived.) +Nate's task pipeline (Obsidian ↔ Morgen via n8n W1/W2, orchestrated by `W0-Sync-Orchestrator`) is downstream of this exact shape. Rewriting tokens in the wrong order or dropping the UUID breaks sync. (Notion was dropped from the sync stack on 2026-05-04; the historical W3 worker is archived.) ### Canonical line @@ -134,7 +134,7 @@ Glyphs: ### UUID rules (non-negotiable) 1. **Every new task gets a 🆔.** Generate with `uuidgen | tr '[:upper:]' '[:lower:]'`. Append AFTER date/recurrence tokens, never inside the body. -2. **Edits preserve 🆔 byte-for-byte.** A rewrite that changes or drops the UUID creates a duplicate task in Morgen that cannot be silently undone. The fix costs the operator 15+ minutes of manual deduping. (Pre-2026-05-04 the duplicate also appeared in Notion; Notion was dropped from the sync stack on 2026-05-04.) +2. **Edits preserve 🆔 byte-for-byte.** A rewrite that changes or drops the UUID creates a duplicate task in Morgen that cannot be silently undone. The fix costs Nate 15+ minutes of manual deduping. (Pre-2026-05-04 the duplicate also appeared in Notion; Notion was dropped from the sync stack on 2026-05-04.) 3. **Missing UUID on a legacy task = mint + log.** If a skill touches a task line that lacks 🆔, it mints one AND appends a line to `Claude-Memory/task-uuid-mints.log` recording (file, line, uuid, timestamp). The mint is a side effect, so it must be auditable. ## 6. Security scrub @@ -160,9 +160,9 @@ Every write path — file body AND commit message — passes through this regex | `-----BEGIN (RSA|EC|DSA|OPENSSH|PRIVATE) KEY-----` + body + `-----END ...-----` | `PEM_PRIVATE_KEY` | | `^[A-Z][A-Z0-9_]+=.+$` inside a block that looks like `.env` (≥3 matching lines in a row) | `ENV_LINE` | -### the operator-specific PII +### Nate-specific PII -- `operator@example.com` stays as-is in plugin code but is redacted from any note body that would land in a public-sync branch. +- `nate@lorecraft.io` stays as-is in plugin code but is redacted from any note body that would land in a public-sync branch. - Named collaborators identified as `internal_only: true` in the private aliases registry MUST be redacted from READMEs, release notes, migration docs, or any commit subject. (Memory rule: never reference internal-only collaborators by name in any public repo artifact.) - Client names flagged `visibility: private` in the same allowlist are redacted the same way. Public mentions are fine only when the allowlist marks them `visibility: public`. @@ -170,7 +170,7 @@ Scrub failure closed: if the regex engine errors (malformed pattern, OOM on huge ## 7. Git conventions -The vault is a git repo; the mogging plugin ships commits from skills and agents alike. the operator's `obsidian-tasks-sync` infra uses commit prefixes to distinguish human commits from bot commits for n8n W1 filtering. +The vault is a git repo; the mogging plugin ships commits from skills and agents alike. Nate's `obsidian-tasks-sync` infra uses commit prefixes to distinguish human commits from bot commits for n8n W1 filtering. ### Branch naming @@ -190,13 +190,13 @@ Date format is ISO (`YYYY-MM-DD`). Slugs are lowercase, hyphenated, ≤40 chars. | `[bot:wiki-heal]` | `wiki heal`, `nightly audit` fixups | Link repair, frontmatter backfill, orphan dressing. | | `[bot:backfill]` | `backfill` skill (non-save entry) | Historical content ingestion outside `save`. | -All five prefixes MUST be listed in the n8n W1 filter or the bot will get stuck in a self-retrigger loop. The filter is kept in `01-Projects//obsidian-tasks-sync/config/bot-prefixes.yaml` in the live vault. +All five prefixes MUST be listed in the n8n W1 filter or the bot will get stuck in a self-retrigger loop. The filter is kept in `01-Projects/LORECRAFT-HQ/obsidian-tasks-sync/config/bot-prefixes.yaml` in the live vault. ### Rules - **No force-push.** Ever. If a branch is broken, create a new one. - **No interactive rebase via skill.** `git rebase -i` requires a human at the keyboard. -- **Direct-to-main is allowed** on the vault repo per the operator's fidgetcoding convention — skills SHOULD still push to a short-lived branch and fast-forward merge so the branch name carries the session context, but they MUST NOT fail if the remote configuration blocks branching (degraded mode: commit to main directly). +- **Direct-to-main is allowed** on the vault repo per Nate's fidgetcoding convention — skills SHOULD still push to a short-lived branch and fast-forward merge so the branch name carries the session context, but they MUST NOT fail if the remote configuration blocks branching (degraded mode: commit to main directly). - **Never `git commit --no-verify`** or `--no-gpg-sign`. Hooks exist to protect the repo; bypassing them erases their value. ## 8. Forbidden paths (all skills) diff --git a/scheduled/launchd/io.lorecraft.mogging.health.plist b/scheduled/launchd/io.lorecraft.mogging.health.plist index 528b867..2253df0 100644 --- a/scheduled/launchd/io.lorecraft.mogging.health.plist +++ b/scheduled/launchd/io.lorecraft.mogging.health.plist @@ -4,7 +4,7 @@ Label - io..mogging.health + io.lorecraft.mogging.health ProgramArguments diff --git a/scheduled/launchd/io.lorecraft.mogging.morning.plist b/scheduled/launchd/io.lorecraft.mogging.morning.plist index 4952028..4c7c28f 100644 --- a/scheduled/launchd/io.lorecraft.mogging.morning.plist +++ b/scheduled/launchd/io.lorecraft.mogging.morning.plist @@ -4,7 +4,7 @@ Label - io..mogging.morning + io.lorecraft.mogging.morning ProgramArguments diff --git a/scheduled/launchd/io.lorecraft.mogging.nightly.plist b/scheduled/launchd/io.lorecraft.mogging.nightly.plist index 02a5220..1d8ef0a 100644 --- a/scheduled/launchd/io.lorecraft.mogging.nightly.plist +++ b/scheduled/launchd/io.lorecraft.mogging.nightly.plist @@ -4,7 +4,7 @@ Label - io..mogging.nightly + io.lorecraft.mogging.nightly ProgramArguments diff --git a/scheduled/launchd/io.lorecraft.mogging.weekly.plist b/scheduled/launchd/io.lorecraft.mogging.weekly.plist index 0077410..aede32b 100644 --- a/scheduled/launchd/io.lorecraft.mogging.weekly.plist +++ b/scheduled/launchd/io.lorecraft.mogging.weekly.plist @@ -4,7 +4,7 @@ Label - io..mogging.weekly + io.lorecraft.mogging.weekly ProgramArguments diff --git a/scripts/import-claude.sh b/scripts/import-claude.sh index 3d763cb..eb437f9 100755 --- a/scripts/import-claude.sh +++ b/scripts/import-claude.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash set -uo pipefail -# ============================================================================ +# ============================================================================= # import-claude.sh # Import a Claude.ai (or ChatGPT) data export into your 2ndBrain-mogging vault. # Unzips the export to a staging area and hands the parsing off to Claude @@ -18,7 +18,7 @@ set -uo pipefail # 0 — success (including dry-run) # 1 — user-facing runtime error (no vault, no zip, extraction failed, etc.) # 2 — usage error (unknown flag, missing flag value) -# ============================================================================ +# ============================================================================= RED='\033[0;31m' GREEN='\033[0;32m' @@ -170,13 +170,7 @@ fi if [ -z "$VAULT_PATH" ]; then VAULT_CANDIDATES=() - # Home-dir candidates first — they're the documented recommendation - # (~/BRAIN2; Desktop/Documents are TCC-protected on modern macOS). for candidate in \ - "$HOME/BRAIN2" \ - "$HOME/BRAIN" \ - "$HOME/2ndBrain" \ - "$HOME/Second-Brain" \ "$HOME/Desktop/BRAIN" \ "$HOME/Desktop/BRAIN2" \ "$HOME/Desktop/2ndBrain" \ diff --git a/scripts/import-notes.sh b/scripts/import-notes.sh index 5f77287..11648c6 100755 --- a/scripts/import-notes.sh +++ b/scripts/import-notes.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash set -uo pipefail -# ============================================================================ +# ============================================================================= # import-notes.sh # Pre-flight helper for importing existing notes (Apple Notes, OneNote, # Notion, Evernote, raw files) into your 2ndBrain-mogging vault. @@ -31,7 +31,7 @@ set -uo pipefail # 0 — success # 1 — user-facing runtime error (no vault, missing --source, …) # 2 — usage error (unknown flag, missing flag value, bad --kind) -# ============================================================================ +# ============================================================================= RED='\033[0;31m' GREEN='\033[0;32m' @@ -226,13 +226,7 @@ fi if [ -z "$VAULT_PATH" ]; then VAULT_CANDIDATES=() - # Home-dir candidates first — they're the documented recommendation - # (~/BRAIN2; Desktop/Documents are TCC-protected on modern macOS). for candidate in \ - "$HOME/BRAIN2" \ - "$HOME/BRAIN" \ - "$HOME/2ndBrain" \ - "$HOME/Second-Brain" \ "$HOME/Desktop/BRAIN" \ "$HOME/Desktop/BRAIN2" \ "$HOME/Desktop/2ndBrain" \ diff --git a/scripts/prepublish-check.sh b/scripts/prepublish-check.sh index bff9589..79ca4a5 100755 --- a/scripts/prepublish-check.sh +++ b/scripts/prepublish-check.sh @@ -134,12 +134,16 @@ else trap 'rm -f "${PII_TMP}"' EXIT grep -vE '^\s*(#|$)' config/nathan.pii > "${PII_TMP}" || true - # Only scan git-tracked files — gitignored files (private operator skills, - # local-only configs) are never published and legitimately contain PII. - # Exclude test fixtures and the gitleaks config (which references patterns). - if git ls-files -z \ - -- ':!tests/fixtures' ':!.gitleaks.toml' ':!.gitleaks.private.toml' \ - | xargs -0 grep -IEn -f "${PII_TMP}" --; then + # -I skips binary, --exclude-dir drops .git + fixtures, --exclude drops + # the gitleaks config (which legitimately references these patterns). + if grep -rIEn -f "${PII_TMP}" . \ + --exclude-dir=.git \ + --exclude-dir=tests/fixtures \ + --exclude-dir=node_modules \ + --exclude=.gitleaks.toml \ + --exclude=.gitleaks.private.toml \ + --exclude=nathan.pii \ + --exclude=.filter-repo-replacements.txt; then fail "nathan.pii patterns matched — scrub before publishing" fi ok "nathan.pii sweep clean" diff --git a/skills/aliases/SKILL.md b/skills/aliases/SKILL.md index 08e30be..dce8f58 100644 --- a/skills/aliases/SKILL.md +++ b/skills/aliases/SKILL.md @@ -8,7 +8,7 @@ allowed-tools: Read, Write, Edit, Glob, Grep > All example names in this file are placeholders. The real-name mapping is private. See docs/placeholder-names.md. -Downstream skills can only route transcripts to the correct project if they know that "" means / and "" is a different person entirely. This skill owns the registry that makes that call. +Downstream skills can only route transcripts to the correct project if they know that "" means PARZVL/ and "" is a different person entirely. This skill owns the registry that makes that call. ## Location @@ -36,23 +36,23 @@ version: 1 updated: 2026-04-16 projects: - : - path: 01-Projects/ - aliases: ["", ""] - /: - path: 01-Projects// + PARZVL: + path: 01-Projects/PARZVL + aliases: ["parzvl", "Parzvl"] + PARZVL/: + path: 01-Projects/PARZVL/ aliases: ["", "", ""] - /: - path: 01-Projects// + MMA/: + path: 01-Projects/MMA/ aliases: ["", "", "", "", "'s funnel"] # ...one entry per 01-Projects folder people: - person_a_: + person_a_parzvl: canonical: - project: / + project: PARZVL/ aliases: [""] - disambig_note: " (with one L) — collaborator. NOT ." + disambig_note: " (with one L) — PARZVL collaborator. NOT ." public_safe: true person_b_unknown: canonical: @@ -67,12 +67,12 @@ people: public_safe: false person_d_placeholder: canonical: - project: + project: PARZVL aliases: [""] public_safe: true person_h_placeholder: canonical: - project: / + project: MMA/ aliases: ["", ""] public_safe: true person_e_placeholder: @@ -82,13 +82,13 @@ people: public_safe: true person_i_placeholder: canonical: - project: /content + project: FIDGETCODING/content aliases: [""] disambig_note: " — NFX AI Bigger Than SaaS article author. Tied to SaaS Death Video idea." public_safe: true person_f_placeholder: canonical: - project: + project: WAGMI aliases: [""] public_safe: true @@ -99,23 +99,23 @@ concepts: aliases: ["tribecoding", "tribe coding", "collab coding"] concept_project_c: canonical: - project: / + project: MMA/ aliases: ["", "", "c&w funnel"] concept_project_a: canonical: - project: / + project: PARZVL/ aliases: ["", ""] concept_fidgetcoding: - canonical: - project: + canonical: FIDGETCODING + project: FIDGETCODING aliases: ["fidget coding", "fidgetcoding", "coding for fun"] orgs: - org_: - canonical: - aliases: ["", "", "", " HQ"] + org_lorecraft: + canonical: LORECRAFT-HQ + aliases: ["Lorecraft", "lorecraft", "Lorecraft LLC", "Lorecraft HQ"] org_lava_foundation: - canonical: + canonical: LAVA-NET aliases: ["Lava", "Lava Foundation", "lava net", "LavaNet"] org_morgen: canonical: MORGEN-MCP @@ -124,29 +124,29 @@ orgs: # Alternate spellings that don't belong to a specific entity but need # to be normalized before matching (e.g. autocorrect drift, typos). aliases: - "the operator": user_nathan - "operator@example.com": user_nathan + "Nate": user_nathan + "nate@lorecraft.io": user_nathan ``` ## vs — canonical disambiguation Two distinct people. Never collapse. -- **** (one L) → `person_a_` → /. the operator's collaborator on the pitch. +- **** (one L) → `person_a_parzvl` → PARZVL/. Nate's collaborator on the pitch. - **** (two L's) → `person_b_unknown` → project unknown (TBD). **Rules:** 1. **Case-sensitive when spelling distinguishes.** "" and "" are two different lookup keys. Do not lowercase before matching. -2. **Context scoring as tiebreaker.** If a transcript mentions "" near / terms, confidence is high. If "" appears cold with no project context and the surrounding conversation is about a non- area, mark low confidence and surface to pending. -3. **Prompt on genuine ambiguity.** If the transcript actually says something like " or " or the spelling is illegible (OCR, autocorrect drift), write both candidates into `aliases-pending.md` with the surrounding quote and let the operator resolve. +2. **Context scoring as tiebreaker.** If a transcript mentions "" near PARZVL / terms, confidence is high. If "" appears cold with no project context and the surrounding conversation is about a non-PARZVL area, mark low confidence and surface to pending. +3. **Prompt on genuine ambiguity.** If the transcript actually says something like " or " or the spelling is illegible (OCR, autocorrect drift), write both candidates into `aliases-pending.md` with the surrounding quote and let Nate resolve. 4. **Honor `public_safe: false`.** and both carry this flag per `feedback_no_public_placeholders.md`. Any skill generating public artifacts (READMEs, release notes, public repo commits) must read this flag and substitute a placeholder. Private vault notes are fine. ## Bootstrap sources `--bootstrap` populates `aliases.yaml` by pulling from: -1. **Folder scan of `01-Projects/`.** Every direct child folder becomes an entry in `projects:`. Sub-project folders (`/`, `/`) get their own entries. +1. **Folder scan of `01-Projects/`.** Every direct child folder becomes an entry in `projects:`. Sub-project folders (`PARZVL/`, `MMA/`) get their own entries. 2. **Memory file grep.** Walk `~/.claude/projects/**/memory/MEMORY.md` and the project-specific memory files referenced there. Extract canonical IDs (`project_*`, `person_*`, `user_*`, `concept_*`). 3. **Proper-noun scan of the vault.** Run a capitalized-word frequency analysis across all `.md` files. Candidates with ≥ 3 mentions get surfaced as person/concept proposals. 4. **Task file `@name` mentions.** `Grep` `05-Tasks/**` for `@Name` patterns — Obsidian Tasks assignee mentions. diff --git a/skills/backfill/SKILL.md b/skills/backfill/SKILL.md index 64a0d6a..11763b7 100644 --- a/skills/backfill/SKILL.md +++ b/skills/backfill/SKILL.md @@ -67,7 +67,7 @@ For each session that clears the `--since` filter and is not already in `backfil 8. Research conclusions 5. **Classification.** Load `Claude-Memory/aliases.yaml` (the `aliases` skill is the upstream producer). Route the session to a project by: - Direct `[[PROJECT]]` wikilinks found in the transcript. - - Aliased entity mentions (`` → /, `` → /, etc.). + - Aliased entity mentions (`` → PARZVL/, `` → MMA/, etc.). - File-path cues (any edits inside `01-Projects/FOO/` → FOO). - Fallback: `MISC-CLAUDE`. 6. **Routing.** Write to `01-Projects/{PROJECT}/conversations/YYYY-MM-DD-{slug}.md` where `YYYY-MM-DD` is the session's first-turn timestamp and `{slug}` is a 3–6 word kebab-case summary of the dominant topic. @@ -123,9 +123,9 @@ title: "short topic summary" date: 2026-04-16 type: conversation source: session-abc123 -project: +project: PARZVL tags: [backfilled] -related: [[]] +related: [[PARZVL]] --- ## Summary @@ -161,9 +161,9 @@ related: [[]] `Claude-Memory/backfill-log.md` gets one entry per session processed, appended chronologically: ``` -- 2026-04-16 18:04 · session-abc123 · /2026-04-13--pitch.md · extracted · 4.2k tokens · $0.0008 +- 2026-04-16 18:04 · session-abc123 · PARZVL/2026-04-13--pitch.md · extracted · 4.2k tokens · $0.0008 - 2026-04-16 18:04 · session-def456 · skipped: tiny (1.3k tokens) -- 2026-04-16 18:05 · session-ghi789 · /2026-04-10-marketing-engagement.md · chunked-summarize · 42k tokens · $0.018 +- 2026-04-16 18:05 · session-ghi789 · LAVA-NET/2026-04-10-marketing-engagement.md · chunked-summarize · 42k tokens · $0.018 ``` ## Security diff --git a/skills/challenge/SKILL.md b/skills/challenge/SKILL.md index a0fce98..f6bacb0 100644 --- a/skills/challenge/SKILL.md +++ b/skills/challenge/SKILL.md @@ -1,27 +1,27 @@ --- name: challenge -description: Adversarial vault agent. Takes an idea and argues against it using the operator's own past notes, feedback files, and Claude-Memory — surfacing contradictions, constraints, cost patterns, stakeholder conflicts, and broken dependencies. Read-only by default; writes only with --save. Use when the user says /challenge, wants a devil's advocate, wants to stress-test a pitch/plan/purchase, or asks "am I wrong about X" / "poke holes in this." +description: Adversarial vault agent. Takes an idea and argues against it using Nate's own past notes, feedback files, and Claude-Memory — surfacing contradictions, constraints, cost patterns, stakeholder conflicts, and broken dependencies. Read-only by default; writes only with --save. Use when the user says /challenge, wants a devil's advocate, wants to stress-test a pitch/plan/purchase, or asks "am I wrong about X" / "poke holes in this." allowed-tools: Read, Grep, Glob --- # /challenge — Adversarial Vault Agent -the operator's vault already holds the counter-arguments to most of his new ideas. He just hasn't re-read them. `/challenge` reads them for him and argues back — analytically, with citations, never with snark. +Nate's vault already holds the counter-arguments to most of his new ideas. He just hasn't re-read them. `/challenge` reads them for him and argues back — analytically, with citations, never with snark. ## When to Invoke - User types `/challenge "idea text"` directly. - User pitches a new idea and asks for pushback, red-teaming, or stress-testing. -- Before the operator ships something irreversible (signs a contract, publishes a release, commits a purchase, commits architecture). -- `/emerge` emits a candidate pattern the operator is about to promote — auto-run `/challenge` over the pattern first. +- Before Nate ships something irreversible (signs a contract, publishes a release, commits a purchase, commits architecture). +- `/emerge` emits a candidate pattern Nate is about to promote — auto-run `/challenge` over the pattern first. -Do NOT invoke for creative work-in-progress (poetry drafts, script drafts) unless the operator explicitly asks. Creative friction kills creative flow. +Do NOT invoke for creative work-in-progress (poetry drafts, script drafts) unless Nate explicitly asks. Creative friction kills creative flow. ## Invocation Forms ``` /challenge "charge $2k flat for funnel" -/challenge --scope "pitch CMO role retainer" +/challenge --scope LAVA-NET "pitch CMO role retainer" /challenge --days 30 --source "add Todoist back as secondary task tool" /challenge --save "ship Morgen MCP v0.2 without task-to-calendar gap fixed" ``` @@ -32,7 +32,7 @@ If invoked with no argument, prompt the user once: `What idea should I stress-te | Flag | Behavior | |---|---| -| `--scope ` | Restrict evidence search to a single project folder under `01-Projects/` (e.g. `--scope `). Defaults to whole vault. | +| `--scope ` | Restrict evidence search to a single project folder under `01-Projects/` (e.g. `--scope LAVA-NET`). Defaults to whole vault. | | `--days N` | Only weigh evidence newer than N days. Default: no time filter, but recency always boosts ranking. | | `--save` | Write the full report to `03-Concepts/challenges/YYYY-MM-DD-.md` and link it into `MOC-Challenges.md` if it exists. Without this flag, output is terminal-only. | | `--source` | Verbose citation mode — every claim gets file path + line number + quoted excerpt, not just the filename. | @@ -57,7 +57,7 @@ Run four parallel passes per anchor: - **Semantic**: Read conceptually adjacent notes (use Grep for synonyms + Glob for topic folders). - **Keyword**: Literal match on anchors. - **Wikilink graph**: Every note linking to or linked from resolved target notes becomes a candidate. -- **Claude-Memory scan**: Grep MEMORY.md for every anchor — these entries are gold because they already encode the operator's stated preferences. +- **Claude-Memory scan**: Grep MEMORY.md for every anchor — these entries are gold because they already encode Nate's stated preferences. ### 4. Classify each hit @@ -66,8 +66,8 @@ Every evidence fragment gets one of seven labels: | Label | Meaning | |---|---| | `CONTRADICTS` | Direct opposition. Past note says the opposite of the proposition. | -| `CONSTRAINT` | Rule, policy, or boundary the operator set (e.g. `feedback_no_prs`, `feedback_motion_auto_schedule`). Proposition violates it. | -| `COST_PATTERN` | Evidence the operator consistently under/over-estimates cost/time/effort on similar work. | +| `CONSTRAINT` | Rule, policy, or boundary Nate set (e.g. `feedback_no_prs`, `feedback_motion_auto_schedule`). Proposition violates it. | +| `COST_PATTERN` | Evidence Nate consistently under/over-estimates cost/time/effort on similar work. | | `STAKEHOLDER_CONFLICT` | The idea involves someone (, , , Dad, , , ) whose documented preferences push back. | | `DEPENDENCY_BROKEN` | The idea depends on something documented as broken/stalled (`google_workspace_mcp_oauth_broken`, `task-to-calendar API gap`, etc.). | | `SUPPORTS` | Past note agrees with the proposition. Still collect these — needed for the balance check. | @@ -92,7 +92,7 @@ Structure the output: One-paragraph summary of the strongest counter-argument. ## Strong (do not ignore) -- [CONTRADICTS] — `feedback_no_prs.md:3` "Push direct to main on all repos, no branches, no PRs" +- [CONTRADICTS] — `feedback_no_prs.md:3` "Push direct to main on all lorecraft-io repos, no branches, no PRs" - [CONSTRAINT] — `feedback_motion_auto_schedule.md:1` ... ## Medium (worth addressing) @@ -119,7 +119,7 @@ Verdicts: ## Tone -Analytical, not confrontational. Write like a research memo. No sarcasm, no "gotcha" framing. the operator is arguing with his past self — the job is to make that past self's strongest case, not to score points. Every claim cited with file path and line number. Never hallucinate a citation; if the vault is silent on something, say so explicitly. +Analytical, not confrontational. Write like a research memo. No sarcasm, no "gotcha" framing. Nate is arguing with his past self — the job is to make that past self's strongest case, not to score points. Every claim cited with file path and line number. Never hallucinate a citation; if the vault is silent on something, say so explicitly. ## Edge Cases diff --git a/skills/connect/SKILL.md b/skills/connect/SKILL.md index 1a2694f..7e404a3 100644 --- a/skills/connect/SKILL.md +++ b/skills/connect/SKILL.md @@ -21,14 +21,14 @@ Do NOT invoke for trivially-related pairs (same folder, overlapping tags) — th ``` /connect [[-funnel]] [[content-ideas]] /connect [[morgen-mcp]] [[POETRY]] --depth deep -/connect [[]] [[fidgetcoding]] --via [[brand-ideation]] +/connect [[lava-net]] [[fidgetcoding]] --via [[brand-ideation]] ``` ## Flags | Flag | Default | Behavior | |---|---|---| -| `--via ` | none | Force the bridge to route through a specific intermediate note. Useful when the operator has a hypothesis and wants verification. | +| `--via ` | none | Force the bridge to route through a specific intermediate note. Useful when Nate has a hypothesis and wants verification. | | `--depth surface\|deep` | `surface` | `surface` = direct adjacency only (1-2 hops). `deep` = up to 3-hop paths through shared tags, entities, stakeholders. | ## Hard Rule: NEVER WRITES @@ -38,13 +38,13 @@ Do NOT invoke for trivially-related pairs (same folder, overlapping tags) — th - No `Edit` tool access. - No file creation under any circumstance. -Output is terminal-only. If the operator wants to persist a connection, he copy-pastes manually. This is by design — most connections are junk, and writing them would pollute the vault. The friction of manual copy is the filter. +Output is terminal-only. If Nate wants to persist a connection, he copy-pastes manually. This is by design — most connections are junk, and writing them would pollute the vault. The friction of manual copy is the filter. ## Pipeline ### 1. Resolve both targets -Parse `[[note-A]]` and `[[note-B]]`. Glob for matching filenames. On ambiguity (e.g. `[[]]` matches both the project index and its task file): +Parse `[[note-A]]` and `[[note-B]]`. Glob for matching filenames. On ambiguity (e.g. `[[PARZVL]]` matches both the project index and its task file): - Prefer project index over task file (respects the canonical-index rule). - Prefer exact filename over substring. - If still ambiguous, ask once. Don't guess. @@ -75,7 +75,7 @@ Compare neighborhoods for: | Type | Meaning | |---|---| -| **Structural analogy** | Structurally-similar situations in different domains. (e.g. `[[-funnel]]` and `[[]]` both = expert-to-audience translation.) | +| **Structural analogy** | Structurally-similar situations in different domains. (e.g. `[[-funnel]]` and `[[lava-net]]` both = expert-to-audience translation.) | | **Transfer opportunity** | Technique from A plausibly works in B's domain. (e.g. Morgen-MCP NL-date-parser → literature-note timestamp parser.) | | **Collision idea** | A × B = genuinely new thing. (e.g. `[[POETRY]]` × `[[morgen-mcp]]` → scheduled weekly poem-draft prompt.) | @@ -127,7 +127,7 @@ Neutral and concrete. No "interesting!" filler. Every claim grounded in a file b - **Stub note (<200 words or frontmatter-only)**: refuse. Output `[STUB DETECTED] [[note-name]] too thin to connect. Expand first.` - **Self-connect**: `[SAME NOTE] Nothing to bridge.` - **Missing note**: fuzzy-suggest 3 closest filenames, ask which one. Don't guess. -- **Hub-index inflation** (e.g. `[[]]` has 60+ backlinks): down-weight generic hub backlinks. Require ≥1 non-hub bridge for a connection to rank. +- **Hub-index inflation** (e.g. `[[LORECRAFT-HQ]]` has 60+ backlinks): down-weight generic hub backlinks. Require ≥1 non-hub bridge for a connection to rank. ## Soft-Call Format (called by /emerge or /challenge) diff --git a/skills/emerge/SKILL.md b/skills/emerge/SKILL.md index 3cd92a9..7746acd 100644 --- a/skills/emerge/SKILL.md +++ b/skills/emerge/SKILL.md @@ -12,7 +12,7 @@ The vault gets denser every day. Some of that density is signal — a concept sh - User runs `/emerge` manually, usually at end of week or start of a review. - Scheduled weekly agent (Friday 6pm ET) runs `/emerge --days 7 --audit` non-interactively and writes the report to `01-Projects/VAULT/conversations/reports/emerge-YYYY-WW.md`. -- After a burst of activity (e.g. the operator just closed a Lava deliverable sprint and wants to see what emerged). +- After a burst of activity (e.g. Nate just closed a Lava deliverable sprint and wants to see what emerged). Do NOT auto-run `/emerge` inside another skill's pipeline except the scheduled agent. It's expensive and slow. @@ -21,7 +21,7 @@ Do NOT auto-run `/emerge` inside another skill's pipeline except the scheduled a ``` /emerge /emerge --days 14 -/emerge --days 7 --scope 01-Projects/ --min-cluster 2 +/emerge --days 7 --scope 01-Projects/FIDGETCODING --min-cluster 2 /emerge --days 7 --audit /emerge --promote cluster-3 ``` @@ -31,7 +31,7 @@ Do NOT auto-run `/emerge` inside another skill's pipeline except the scheduled a | Flag | Default | Behavior | |---|---|---| | `--days N` | 30 | Only consider files modified in the last N days. | -| `--scope ` | whole vault | Restrict to a single folder (e.g. `01-Projects/`). | +| `--scope ` | whole vault | Restrict to a single folder (e.g. `01-Projects/LAVA-NET`). | | `--min-cluster N` | 3 | Minimum file count for a cluster to be reported. Below this, treated as noise. | | `--audit` | off | Non-interactive mode for the scheduled weekly agent. Writes directly to the reports folder, no prompts. | | `--promote ` | — | Skip mining. Take a previously-identified cluster and promote it to a full `03-Concepts/.md` note. | @@ -42,7 +42,7 @@ Do NOT auto-run `/emerge` inside another skill's pipeline except the scheduled a Glob all vault files modified in the time window. Exclude `node_modules/`, `.obsidian/`, `.git/`, `.claude/`, `.agents/`. **Cap at 500 files.** If over cap, sample by: - Recency (newer = higher weight) -- Project diversity (one `01-Projects//content/` note ≠ ten of them — cap per-folder contribution) +- Project diversity (one `01-Projects/FIDGETCODING/content/` note ≠ ten of them — cap per-folder contribution) ### 2. Extract signals @@ -51,7 +51,7 @@ Per file, extract: - **Concepts**: noun phrases appearing ≥2 times or in H1/H2 headings. - **Tags**: frontmatter tags + inline `#tag` mentions. - **Actions**: verbs attached to project names (e.g. "shipped Morgen", "killed "). -- **Sentiment markers**: the operator's loaded language — "panic", "theater", "clean", "mogging", "janky", "ship-and-fix-forward", all caps emphasis. +- **Sentiment markers**: Nate's loaded language — "panic", "theater", "clean", "mogging", "janky", "ship-and-fix-forward", all caps emphasis. Signals are stored as `(file_path, signal_type, signal_value, weight)` tuples. @@ -71,7 +71,7 @@ For every surviving cluster, generate 2-3 candidate names. **Name discipline**: - **Short**: 2-5 words. - **Concrete**: prefer nouns over gerunds, compounds over abstractions. - **Anti-jargon**: do not use "synergy", "orchestration", "framework", "paradigm", "leverage", "ecosystem", "stack" unless the cluster is literally about a software stack. -- **Match the operator's naming DNA**: reference `feedback_cli_maxxing_folder`, `project_tribecoding`, `project_fidgetcoding_rename` in Claude-Memory. Names are playful-terse ("tribecoding", "mogging", "task-maxxing"), not PMish ("collaborative coding ecosystem"). +- **Match Nate's naming DNA**: reference `feedback_cli_maxxing_folder`, `project_tribecoding`, `project_fidgetcoding_rename` in Claude-Memory. Names are playful-terse ("tribecoding", "mogging", "task-maxxing"), not PMish ("collaborative coding ecosystem"). - **No emoji**. No brackets. No trailing ellipses. Pick the strongest candidate as primary, list the other two as alternates. @@ -102,7 +102,7 @@ Clusters surviving: Z ## Cluster 1: Alternates: , -Score: 8.4 | Files: 7 | Projects: 3 (, , ) +Score: 8.4 | Files: 7 | Projects: 3 (LAVA-NET, LORECRAFT-HQ, FIDGETCODING) Recency: median 4 days ago **Gist**: one-paragraph synthesis of what's emerging. @@ -160,7 +160,7 @@ Weekly agent config (managed in `~/.claude/hooks/` not here): The `--audit` flag means: - No interactive prompts. - Skip clusters below `--min-cluster` silently. -- Never promote automatically — leave that to the operator. +- Never promote automatically — leave that to Nate. - If no clusters survive, still write the report (noting "no emergent patterns this week") — silence is also data. ## Edge Cases diff --git a/skills/import-claude/SKILL.md b/skills/import-claude/SKILL.md index 548e33d..b4d657b 100644 --- a/skills/import-claude/SKILL.md +++ b/skills/import-claude/SKILL.md @@ -152,7 +152,7 @@ Tell the user to run `/tether` next — it fixes any missed backlinks. /import-claude --scan /import-claude --dry-run /import-claude --apply -/import-claude --since 2026-01-01 --project "" --apply +/import-claude --since 2026-01-01 --project "LORECRAFT-HQ" --apply /import-claude --resume ``` diff --git a/skills/import-notes/SKILL.md b/skills/import-notes/SKILL.md index b388845..6736435 100644 --- a/skills/import-notes/SKILL.md +++ b/skills/import-notes/SKILL.md @@ -165,7 +165,7 @@ Tell the user to run `/tether` next so bidirectional project-note links settle, /import-notes --source ~/Desktop/apple-notes-export --scan /import-notes --source ~/Desktop/apple-notes-export --dry-run /import-notes --source ~/Desktop/apple-notes-export --apply -/import-notes --source ~/Desktop/notion-export --kind notion --project --apply +/import-notes --source ~/Desktop/notion-export --kind notion --project LAVA-NET --apply /import-notes --resume ``` diff --git a/skills/save/SKILL.md b/skills/save/SKILL.md index 8620597..98c3246 100644 --- a/skills/save/SKILL.md +++ b/skills/save/SKILL.md @@ -6,7 +6,7 @@ allowed-tools: Read, Write, Edit, Glob, Grep, Bash # save — conversation capture into 2ndBrain -Shared schema: see `./references/wiki-schema.md` (source of truth for frontmatter keys, folder roles, and linking grammar used by both `save` and `wiki`). +Shared schema: see `../references/wiki-schema.md` (source of truth for frontmatter keys, folder roles, and linking grammar used by both `save` and `wiki`). `save` is the single canonical entry point for "commit this conversation (or this slice of it, or this thing I just dictated) to the vault." It replaces every ad-hoc "just append to Inbox" habit. It is classification-first, preview-before-write, and append-only toward existing notes — never overwrite an existing file without showing the diff and getting explicit approval. @@ -35,18 +35,18 @@ If the user types a number not in `1..5`, re-prompt. If they describe the conten ## 2. Aliases as classification source -Before routing any content, load `Claude-Memory/aliases.yaml` from the vault root via `Read`. The aliases file maps natural-language signals to canonical vault destinations. Schema recap (full definition in `./references/wiki-schema.md`): +Before routing any content, load `Claude-Memory/aliases.yaml` from the vault root via `Read`. The aliases file maps natural-language signals to canonical vault destinations. Schema recap (full definition in `../references/wiki-schema.md`): ```yaml aliases: - key: names: [, , , ] - destination: 01-Projects///.md - tags: [org-d, client, ] + destination: 01-Projects/MMA//.md + tags: [mma, client, ] confidence_boost: 0.15 - key: morgen-mcp names: [morgen mcp, morgen-mcp, morgen bot, w1, obsidian-tasks-sync] - destination: 01-Projects//morgen-mcp.md + destination: 01-Projects/LORECRAFT-HQ/morgen-mcp.md ... ``` @@ -77,8 +77,8 @@ Before any `Write` or `Edit`, print a table: ┌───────────────────────────────┬────────────────────────────────────────────────────┬──────────────┐ │ Signal │ Destination │ Confidence │ ├───────────────────────────────┼────────────────────────────────────────────────────┼──────────────┤ -│ "", "" │ 01-Projects///…/2026-04-16.md │ 0.88 │ -│ "stripe webhook" (ambiguous) │ 01-Projects//stripe-notes.md [stub] │ 0.41 │ +│ "", "" │ 01-Projects/MMA//…/2026-04-16.md │ 0.88 │ +│ "stripe webhook" (ambiguous) │ 01-Projects/LORECRAFT-HQ/stripe-notes.md [stub] │ 0.41 │ │ "tax deduction" │ 01-Projects/LEGAL-FINANCE/tax-notes-2025.md │ 0.72 │ └───────────────────────────────┴────────────────────────────────────────────────────┴──────────────┘ @@ -86,7 +86,7 @@ Commit on all writes: [bot:save] capture session 2026-04-16 Proceed? (y/n/edit) ``` -`edit` drops the user into a mini-loop where they can re-map any row (`row 2 → /stripe.md`). Only `y` triggers writes. `n` aborts cleanly with zero side effects. +`edit` drops the user into a mini-loop where they can re-map any row (`row 2 → LORECRAFT-HQ/stripe.md`). Only `y` triggers writes. `n` aborts cleanly with zero side effects. ### Auto-commit when nothing is ambiguous @@ -108,7 +108,7 @@ When auto-committing, the skill still prints the preview table after the fact, p - Tool-call traces: ON. - Artifacts: ON (any files written this thread are listed with absolute paths + one-line purpose). -These match what the operator picks every time. Skip directly to classification + preview + write. +These match what Nate picks every time. Skip directly to classification + preview + write. Behavior: @@ -116,7 +116,7 @@ Behavior: 2. Print preview table (§3). 3. Auto-commit if no flags fire (§3 auto-commit rule); else prompt `y/n/edit`. 4. On write — choose path by classification (post-2026-05-08 conversations-into-projects restructure): - - **Project-tied** (alias resolves to a single `01-Projects//`): write the full transcript to `01-Projects//conversations/[/]-.md`. **No pointer, no LIT mirror** — the project folder is the sole source of truth. If the project has substructure (e.g. `//`, `/career/`), mirror it under `conversations/` (Pattern A flat). + - **Project-tied** (alias resolves to a single `01-Projects//`): write the full transcript to `01-Projects//conversations/[/]-.md`. **No pointer, no LIT mirror** — the project folder is the sole source of truth. If the project has substructure (e.g. `PARZVL/Beard Club/`, `LORECRAFT-HQ/career/`), mirror it under `conversations/` (Pattern A flat). - **Cross-cutting** (no single project owner — multi-project strategy threads, generic dictation, vault-spanning topics): write to `02-Sources/LIT-conversation--.md`. LIT is reserved for cross-cutting captures only. - **Vault-meta** (vault architecture sessions, graph repairs, mogging-pack-dev work, scheduled-agent reports): write to `01-Projects/VAULT/conversations/[/]-.md`. Subfolders: `architecture-sessions/`, `graph-repairs/`, `mogging-pack-dev/`, `reports/`. - **Meeting-style captures** (Granola transcripts, multi-stakeholder calls): optionally route under `/conversations/meetings/` for tighter organization. @@ -169,7 +169,7 @@ Write to `Claude-Memory/adr/ADR--.md`. Auto-link in `Claude-Memory/ad ## 8. Obsidian Tasks plugin syntax (05-Tasks writes) -Anything the skill emits into `05-Tasks/` (any branch, any path under that prefix) MUST obey the plugin grammar — the operator's entire task pipeline is downstream of this file's exact shape. +Anything the skill emits into `05-Tasks/` (any branch, any path under that prefix) MUST obey the plugin grammar — Nate's entire task pipeline is downstream of this file's exact shape. Required grammar: @@ -286,4 +286,4 @@ Backfill commits use `[bot:save --backfill]` as the prefix so they're still W1-t - `save` does not run audits, heals, or contradiction detection — that is also `wiki`. - `save` does not touch `.env*`, `.claude/settings.json`, or anything outside the vault tree. -Reference: `./references/wiki-schema.md` is the binding definition for every frontmatter key, folder role, and linking grammar token referenced above. +Reference: `../references/wiki-schema.md` is the binding definition for every frontmatter key, folder role, and linking grammar token referenced above. diff --git a/skills/save/references/wiki-schema.md b/skills/save/references/wiki-schema.md deleted file mode 100644 index 624d52a..0000000 --- a/skills/save/references/wiki-schema.md +++ /dev/null @@ -1,250 +0,0 @@ -# wiki-schema.md — canonical rules for 2ndBrain-mogging - -This file is the single source of truth for every skill in `skills/*/SKILL.md`. Any skill that writes, reads, or audits the vault must resolve its folder targets, frontmatter keys, link grammar, security posture, and git contract from here. If a skill contradicts this doc, the doc wins. - -Downstream consumers (all required to reference this file): - -- `skills/save/SKILL.md` -- `skills/wiki/SKILL.md` -- `skills/challenge/SKILL.md` -- `skills/emerge/SKILL.md` -- `skills/backfill/SKILL.md` -- `skills/aliases/SKILL.md` -- `skills/autoresearch/SKILL.md` -- `skills/canvas/SKILL.md` -- `skills/tether/SKILL.md` -- `skills/connect/SKILL.md` -- `agents/{morning,nightly,weekly,health}.md` -- `hooks/stop-save.sh` - -## 1. Folder contract - -The vault follows the operator's stripped operator layout. The plugin treats each folder as having exactly one writer role plus a set of constraints. Skills that violate the writer role get hard-rejected in their own failure-mode table. - -| Folder | Role | Primary writer | Secondary writers | Constraints | -|---|---|---|---|---| -| `01-Projects//conversations/` (post-2026-05-08; `01-Projects//conversations/` was retired) | Conversation captures, daily notes, scheduled-agent reports, interactive `/wiki audit` output | `save` (branches 1–3), `wiki` (`audit` branch) | `agents/morning`, `agents/nightly`, `agents/weekly`, `agents/health` | Append-only per file. All audit and daily reports — interactive or scheduled — live under `01-Projects/VAULT/conversations/reports/` (`audit-YYYY-MM-DD.md`, `daily-YYYY-MM-DD.md`, `weekly-YYYY-WW.md`, `health-YYYY-MM-DD.md`). Scheduled agents write here and nowhere else. | -| `02-Sources/` | Source-of-truth notes for external content (articles, videos, transcripts, emails) | `save` (branch 2 `--source`), `autoresearch` | `wiki` (heal only) | Each file must carry `source_url` + `source_type` + `captured` in frontmatter. Body is summary; raw fetched text lives in a `> [!source]` callout or a fenced block. | -| `03-Concepts/` | Refined atomic concept notes | `wiki` | `save` (branch 3, type `p`), `emerge` | One concept per file. Must have ≥1 inbound from a `02-Sources/` note and ≥1 outbound to `04-Index/`. `needs_review: true` on first write; promoted by `wiki` once it has 3+ inbound links. | -| `04-Index/` | Maps of content (MOCs), hub pages, topic indexes | `wiki`, `tether` | `emerge` (weekly only) | Never append freeform text — only link lists + terse one-liners. Must list every concept in its topic cluster; `tether` fails the graph audit if an `03-Concepts/` note has no MOC entry. | -| `01-Projects/` | Project hubs mirroring Claude Projects | `save` (branches 1–3), `tether` | `wiki` (heal only) | Each project folder has an index note where filename matches folder name (`FOO/FOO.md`, never `FOO-Index.md`). Bidirectional links up to `04-Index/Projects-Index.md` are mandatory. | -| `05-Tasks/` | Obsidian Tasks plugin files + inline tasks | `save` (UUID-preserving edits only) | none | `/wiki` and `/autoresearch` are FORBIDDEN from writing here. `/save` is edit-safe only with strict UUID preservation (§5). No agent writes here. | -| `Claude-Memory/` (vault root) | Plugin working state: aliases, ADRs, manifests, hot context | `aliases`, `save` (ADR branch + backfill manifest), `emerge` (hot.md) | `agents/morning` (hot.md prime) | Not user-facing notes — treat as config. `aliases.yaml` is the canonical alias source; `adr/` holds ADRs; `backfill-manifest.jsonl` is append-only. | -| `.obsidian/` (root sidecar) | Obsidian app config | none (user-owned) | none | Forbidden path (§8). | -| `CLAUDE.md` (vault root) | Vault instructions for Claude Code | user | `wiki` (append-only to "Updated rules" section) | Never rewritten wholesale. New rules are appended with a date heading. | -| `README.md` (vault root) | Human-readable vault overview | user | `wiki` (heal only, edit existing sections) | Never created by a skill if absent — warn instead. | - -## 2. Three non-negotiables - -These override every skill-local policy. A skill that skips one of these must be treated as broken and halted. - -1. **Backup-before-write.** Before overwriting ANY file that already exists on disk, snapshot it to `Claude-Memory/backups/YYYY-MM-DD/HHMMSS--.bak`. Preserve directory structure in the backup path (flatten separators with `--`). If the backup write fails (disk full, permissions), abort the primary write. No exceptions. - -2. **Stop-hook-jq-merge.** The `Stop` hook payload MUST be merged into existing session state using `jq --slurp 'add'` semantics, never naive concatenation. Raw string append corrupts `Claude-Memory/sessions/.json` silently and breaks `/save --backfill --resume`. If `jq` is unavailable on the system path, the hook prints a WARN and no-ops rather than writing partial state. - -3. **n8n-path-filter-update.** Any skill that adds a new vault subtree (new top-level folder, new `01-Projects///` with externally-synced tasks) MUST also update the n8n W1 path filter so the new subtree is ingested. The canonical path filter lives in `01-Projects//n8n-workflows/W1-paths.yaml` in the main vault. If that file is inaccessible (no symlink, no vault mounted), the skill prints a TODO row in its report and continues — it does not silently create untracked subtrees. - -## 3. Linking rules - -Graph density is the product. Each rule below exists to prevent an orphan. - -- **Wikilinks only.** Always `[[Note Name]]` or `[[Note Name|Alias]]`. Never raw vault paths (`02-Sources/2026-04-16-uri.md`) in body text — Obsidian renders them but they break on rename. -- **Inbound + outbound minimum.** Every new concept page (anything written into `03-Concepts/`) needs at least one inbound wikilink from its source(s) AND at least one outbound wikilink to a `04-Index/` MOC. Zero-inbound or zero-outbound concept pages fail `/wiki audit` and get flagged in the nightly report. -- **50/50 ambiguity.** If alias classification scores the top two candidates within 10% of each other, the content is ambiguous. Primary file is written to the higher-confidence target with full content. Stub file is written at the secondary target with `stub_of: "[[primary]]"` in frontmatter and a one-line body: `> See [[primary-basename]] — classification was 50/50. Resolved to primary on {{date}}.` Both files carry tag `#ambiguous-routing` so they can be reviewed via query. See §9 for the full rule. -- **Dead-link handling.** When `/wiki heal` or any audit detects a wikilink target that does not resolve (file removed, renamed without update), the link is rewritten to `~~[[orphaned-target]]~~ ` — strike-through in Obsidian rendering plus an HTML comment carrying the detection date. The comment lets us diff history. Never remove the link itself without flagging it for human review — removal is a human-only action. -- **Rename propagation.** If a skill renames a note, it MUST grep the vault for all `[[old-name]]` references and update them in the same commit. An unupdated reference is a bug, not a "nice to have". -- **Never link to a folder.** `[[01-Projects]]` is not a link; `[[Projects-Index]]` is. Folders do not have notes; MOCs/Indexes do. - -## 4. Frontmatter contract - -Every note the plugin writes must open with YAML frontmatter. Five fields are universal; per-type additions follow. - -### Universal fields (all types) - -```yaml ---- -title: "Human-readable title" # required, quote if it contains : -date: 2026-04-16 # ISO date, required -type: source | concept | synthesis | conversation | adr | moc -tags: [lowercase-hyphenated] # list, may be empty -aliases: ["Alt Name 1", "Alt Name 2"] # list, used by Obsidian link autocomplete ---- -``` - -`type` is closed-set; a skill encountering an unknown type value halts with a parse error rather than guessing. - -### Per-type additions - -**type: source** (goes to `02-Sources/`) - -```yaml -source_url: "https://example.com/article" # required; use [REDACTED] for private Slack etc. -source_type: article | video | podcast | email | transcript | pdf | book -captured: 2026-04-16T14:22:00-04:00 # RFC 3339 with TZ -last_confirmed: 2026-04-16 # last date a human verified the URL resolves -author: "Name or @handle" # optional; use "unknown" if not attributable -``` - -**type: concept** (goes to `03-Concepts/`) - -```yaml -last_confirmed: 2026-04-16 # required; used by /wiki audit staleness check -needs_review: true # auto-true on first write, flipped by /wiki promote -owner: human | llm # 'human' locks the note from silent LLM edits -``` - -**type: synthesis** (cross-concept rollups, also in `03-Concepts/` or `04-Index/`) - -```yaml -answers_question: "What is the cheapest path from X to Y?" # the question this note resolves -sources: ["[[LIT-note-a]]", "[[LIT-note-b]]"] # wikilinks to the sources feeding it -``` - -**type: adr** (goes to `Claude-Memory/adr/`) - -```yaml -status: proposed | accepted | superseded -supersedes: "[[ADR-007-old-name]]" # optional -superseded_by: "[[ADR-012-new-name]]" # optional; filled when a later ADR overrides this -``` - -**type: conversation** (goes to `01-Projects//conversations/` (post-2026-05-08; `01-Projects//conversations/` was retired)): no per-type additions beyond universal. Rely on `source: "claude-cli session "` in the body if needed. - -**type: moc** (goes to `04-Index/`): no additions beyond universal. The body is the MOC structure itself. - -## 5. Obsidian Tasks plugin syntax - -the operator's task pipeline (Obsidian ↔ Morgen via n8n W1/W2, orchestrated by `W0-Sync-Orchestrator`) is downstream of this exact shape. Rewriting tokens in the wrong order or dropping the UUID breaks sync. (Notion was dropped from the sync stack on 2026-05-04; the historical W3 worker is archived.) - -### Canonical line - -``` -- [ ] 📅 YYYY-MM-DD <🔁 recurrence?> 🆔 -``` - -**Token order is mandatory.** The Tasks plugin parses positionally in several render paths. Deviating breaks Morgen tag-sync. - -Glyphs: - -- Priority: 🔺 highest · ⏫ high · 🔼 medium · 🔽 low · ⏬ lowest -- Dates: 📅 due · ⏳ scheduled · 🛫 start · ✅ done · ❌ cancelled -- Recurrence: `🔁 every week`, `🔁 every 2 weeks`, `🔁 every month on the 1st` -- 🆔 stable identifier, UUIDv4, mandatory on every new task - -### UUID rules (non-negotiable) - -1. **Every new task gets a 🆔.** Generate with `uuidgen | tr '[:upper:]' '[:lower:]'`. Append AFTER date/recurrence tokens, never inside the body. -2. **Edits preserve 🆔 byte-for-byte.** A rewrite that changes or drops the UUID creates a duplicate task in Morgen that cannot be silently undone. The fix costs the operator 15+ minutes of manual deduping. (Pre-2026-05-04 the duplicate also appeared in Notion; Notion was dropped from the sync stack on 2026-05-04.) -3. **Missing UUID on a legacy task = mint + log.** If a skill touches a task line that lacks 🆔, it mints one AND appends a line to `Claude-Memory/task-uuid-mints.log` recording (file, line, uuid, timestamp). The mint is a side effect, so it must be auditable. - -## 6. Security scrub - -Every write path — file body AND commit message — passes through this regex panel first. Matches are replaced in-place with `[REDACTED:]`. Matches in commit messages also cause a preview warning row so the user sees what got swapped out. - -| Pattern | Type | -|---|---| -| `sk-ant-[A-Za-z0-9_-]{20,}` | `ANTHROPIC_KEY` | -| `sk-proj-[A-Za-z0-9_-]{20,}` | `OPENAI_PROJECT_KEY` | -| `ntn_[A-Za-z0-9]{20,}` | `NOTION_INTEGRATION_TOKEN` | -| `ghp_[A-Za-z0-9]{36,}` | `GITHUB_PAT_CLASSIC` | -| `gho_[A-Za-z0-9]{36,}` | `GITHUB_OAUTH_TOKEN` | -| `github_pat_[A-Za-z0-9_]{22,}` | `GITHUB_PAT_FINE` | -| `AKIA[0-9A-Z]{16}` | `AWS_ACCESS_KEY` | -| `xox[baprs]-[A-Za-z0-9-]{10,}` | `SLACK_TOKEN` | -| `ya29\.[A-Za-z0-9_-]+` | `GOOGLE_OAUTH_TOKEN` | -| `sbp_[A-Za-z0-9]{40,}` | `SUPABASE_KEY` | -| `sk_live_[A-Za-z0-9]{24,}` | `STRIPE_LIVE_KEY` | -| `rk_live_[A-Za-z0-9]{24,}` | `STRIPE_LIVE_RESTRICTED` | -| `v1\.0-[A-Za-z0-9_-]{30,}` | `CLOUDFLARE_API_TOKEN` | -| `eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}` | `JWT` | -| `-----BEGIN (RSA|EC|DSA|OPENSSH|PRIVATE) KEY-----` + body + `-----END ...-----` | `PEM_PRIVATE_KEY` | -| `^[A-Z][A-Z0-9_]+=.+$` inside a block that looks like `.env` (≥3 matching lines in a row) | `ENV_LINE` | - -### the operator-specific PII - -- `operator@example.com` stays as-is in plugin code but is redacted from any note body that would land in a public-sync branch. -- Named collaborators identified as `internal_only: true` in the private aliases registry MUST be redacted from READMEs, release notes, migration docs, or any commit subject. (Memory rule: never reference internal-only collaborators by name in any public repo artifact.) -- Client names flagged `visibility: private` in the same allowlist are redacted the same way. Public mentions are fine only when the allowlist marks them `visibility: public`. - -Scrub failure closed: if the regex engine errors (malformed pattern, OOM on huge paste), the write is refused rather than proceeding with partial scrub. - -## 7. Git conventions - -The vault is a git repo; the mogging plugin ships commits from skills and agents alike. the operator's `obsidian-tasks-sync` infra uses commit prefixes to distinguish human commits from bot commits for n8n W1 filtering. - -### Branch naming - -- `wiki-add/YYYY-MM-DD-slug` — new concept, new MOC, or net-new folder scaffolding. -- `wiki-heal/YYYY-MM-DD` — audit fixes: dead links, missing frontmatter, orphan repair. -- `backfill/YYYY-MM-DD` — `/save --backfill` historical transcript ingestion. - -Date format is ISO (`YYYY-MM-DD`). Slugs are lowercase, hyphenated, ≤40 chars. - -### Commit prefixes (MUST appear as first token in the subject line) - -| Prefix | Used by | Purpose | -|---|---|---| -| `[bot:save]` | `save` (all non-backfill branches) | Skip n8n W1 re-fire; flag for human audit. | -| `[bot:save --backfill]` | `save --backfill` | Same as above but trivially filterable in `git log`. | -| `[bot:wiki-add]` | `wiki add`, `connect`, `tether` (new-note paths) | New concept/MOC/link scaffolding. | -| `[bot:wiki-heal]` | `wiki heal`, `nightly audit` fixups | Link repair, frontmatter backfill, orphan dressing. | -| `[bot:backfill]` | `backfill` skill (non-save entry) | Historical content ingestion outside `save`. | - -All five prefixes MUST be listed in the n8n W1 filter or the bot will get stuck in a self-retrigger loop. The filter is kept in `01-Projects//obsidian-tasks-sync/config/bot-prefixes.yaml` in the live vault. - -### Rules - -- **No force-push.** Ever. If a branch is broken, create a new one. -- **No interactive rebase via skill.** `git rebase -i` requires a human at the keyboard. -- **Direct-to-main is allowed** on the vault repo per the operator's fidgetcoding convention — skills SHOULD still push to a short-lived branch and fast-forward merge so the branch name carries the session context, but they MUST NOT fail if the remote configuration blocks branching (degraded mode: commit to main directly). -- **Never `git commit --no-verify`** or `--no-gpg-sign`. Hooks exist to protect the repo; bypassing them erases their value. - -## 8. Forbidden paths (all skills) - -Every skill refuses to read, write, or list these paths. Path allowlist check runs BEFORE every `Write`/`Edit`/`Bash`: - -``` -.obsidian/** -.git/** -node_modules/** -**/.env* -**/credentials* -**/*.key -**/*.pem -**/*.p12 -**/.ssh/** -``` - -Additional per-skill forbidden paths: - -- **`/wiki` and `/autoresearch`** are additionally forbidden from writing anywhere under `05-Tasks/**`. Task management is human-sovereign plus `/save`-only. -- **`/save` is the sole exception** for `05-Tasks/` — and even then only edit-safe with strict UUID preservation (§5). -- **No skill writes** to `CLAUDE.md` in the vault root wholesale — only append a dated block to the "Updated rules" section if one exists. - -Refusal output format (required): - -``` -REFUSED: is in the forbidden list (). -Suggestion: . -``` - -## 9. 50/50 wikilink rule (ambiguous classification) - -When alias scoring produces two top candidates within 10% of each other, the content gets double-filed — primary at the higher-confidence target, stub at the secondary — with explicit breadcrumbs. - -**Primary file** (higher confidence): - -- Full content body is written here. -- Frontmatter includes the normal per-type fields plus `ambiguous_with: "[[secondary-basename]]"`. -- Tag `#ambiguous-routing` is appended to `tags`. -- Commit message calls out the ambiguity. - -**Stub file** (secondary): - -- Body is a single `> See [[primary-basename]] — classification was 50/50 between this project and that one. Resolved to primary on YYYY-MM-DD.` -- Frontmatter includes `stub_of: "[[primary-basename]]"` plus the same `#ambiguous-routing` tag. -- No further content. No auto-promotion. Stub stays stub until a human upgrades it with `/save` branch 2 + explicit destination. - -Both files are surfaced in the dry-run preview table so the user can override with `edit` before writing. If the secondary candidate scores below 30% confidence, the 50/50 rule does NOT fire — instead, the skill routes to `02-Sources/` with a TODO (the pre-mogging `00-Inbox/` was killed on 2026-04-16). Stubbing random weak candidates adds noise, not signal. - -End of `wiki-schema.md`. Any skill contradicting this file is the bug; fix the skill. diff --git a/skills/tether/SKILL.md b/skills/tether/SKILL.md index 786792f..6e1ef90 100644 --- a/skills/tether/SKILL.md +++ b/skills/tether/SKILL.md @@ -1,6 +1,6 @@ --- name: tether -description: Audit and repair the tethering rules in `01-Projects/` — filename-equals-folder, bidirectional links to Projects-Index, org-hub tethering (, GITHUB), sub-project back-links, and unlinked-mention detection. Dry-run by default; atomic per-project transactions on execute. Respects `tether: none` frontmatter opt-outs and never touches cloned repos under any `01-Projects//GITHUB/` subtree. +description: Audit and repair the tethering rules in `01-Projects/` — filename-equals-folder, bidirectional links to Projects-Index, org-hub tethering (LORECRAFT-HQ, GITHUB), sub-project back-links, and unlinked-mention detection. Dry-run by default; atomic per-project transactions on execute. Respects `tether: none` frontmatter opt-outs and never touches cloned repos under any `01-Projects//GITHUB/` subtree. allowed-tools: Read, Write, Edit, Glob, Grep --- @@ -12,7 +12,7 @@ Project folders drift. Index files get renamed with stray `-Index` suffixes. New | Flag | Purpose | |------|---------| -| `--scope ` | Audit exactly one project folder (e.g. `--scope `). Sub-project paths also accepted (`--scope /`). | +| `--scope ` | Audit exactly one project folder (e.g. `--scope PARZVL`). Sub-project paths also accepted (`--scope PARZVL/`). | | `--all` | Audit every project in `01-Projects/`. | | `--dry-run` | **Default.** Report violations; do not write. | | `--execute` | Apply fixes. Atomic per-project — if any step fails for a project, roll that project back. Other projects continue. | @@ -25,18 +25,18 @@ Project folders drift. Index files get renamed with stray `-Index` suffixes. New Every project folder has an index note whose filename matches the folder exactly, **with no `-Index` suffix**. -- Correct: `01-Projects//.md`, `01-Projects//GITHUB/GITHUB.md`, `01-Projects//.md`. -- Wrong: `-Index.md`, `GITHUB-Index.md`, `-Index.md`. +- Correct: `01-Projects/PARZVL/PARZVL.md`, `01-Projects//GITHUB/GITHUB.md`, `01-Projects/MMA/MMA.md`. +- Wrong: `PARZVL-Index.md`, `GITHUB-Index.md`, `MMA-Index.md`. Wrong filenames break `[[PROJECT]]` wikilink resolution — the wikilink goes stale and the project drifts off the main graph. -Sub-projects follow the same rule: `01-Projects///.md`, `01-Projects///.md`. +Sub-projects follow the same rule: `01-Projects/PARZVL//.md`, `01-Projects/MMA//.md`. ### Rule 2 — Bidirectional links Every project index note must link: -- **UP** to `Projects-Index.md` and to any relevant org hub (`[[]]`, `[[GITHUB]]`). +- **UP** to `Projects-Index.md` and to any relevant org hub (`[[LORECRAFT-HQ]]`, `[[GITHUB]]`). - **DOWN** to every sub-project under the folder. And every sub-project index must link back UP to its parent project. One-way links create islands. @@ -47,13 +47,13 @@ And every sub-project index must link back UP to its parent project. One-way lin ### Rule 4 — Client work tethered to org hub -If a project was built under (or any org), the project's index has `[[]]` in its **Related** section. The org hub (`.md`) lists the project under its **## Repos** or **## Projects** section. Both directions required. +If a project was built under Lorecraft (or any org), the project's index has `[[LORECRAFT-HQ]]` in its **Related** section. The org hub (`LORECRAFT-HQ.md`) lists the project under its **## Repos** or **## Projects** section. Both directions required. -Example: `/` links to `[[]]` (its parent) AND `[[]]` (its org). `.md` lists the under its projects section. +Example: `PARZVL/` links to `[[PARZVL]]` (its parent) AND `[[LORECRAFT-HQ]]` (its org). `LORECRAFT-HQ.md` lists the under its projects section. ### Rule 5 — Code projects tethered to GITHUB hub -If a project has a cloned repo under any `01-Projects//GITHUB/` hub (the canonical pattern — e.g. a -owned repo lives under `01-Projects//GITHUB/`), the project's main note links `[[GITHUB]]` in its Related section, and the matching `01-Projects//GITHUB/GITHUB.md` hub lists the project under its **## Owned By** section. +If a project has a cloned repo under any `01-Projects//GITHUB/` hub (the canonical pattern — e.g. a FIDGETCODING-owned repo lives under `01-Projects/FIDGETCODING/GITHUB/`), the project's main note links `[[GITHUB]]` in its Related section, and the matching `01-Projects//GITHUB/GITHUB.md` hub lists the project under its **## Owned By** section. ## Violation categories @@ -80,7 +80,7 @@ A single failing project never halts the full run. The final summary reports per - **Filename mismatch:** rename `FOO-Index.md` → `FOO.md`. Then `Grep` the vault for `[[FOO-Index]]` references and update them in the same transaction. If a rename would clobber an existing file, abort that project and flag manually. - **Missing Projects-Index entry:** insert `[[PROJECT]]` into the appropriate section of `Projects-Index.md` (business / creative / tech / personal — match sibling projects' section). - **Broken bidirectional link:** append the missing `[[X]]` into the correct section (Related, sub-projects, ## Repos, ## Owned By). Never replace existing content — only append. -- **Unlinked mentions:** **never auto-convert.** Write candidates to `Claude-Memory/tether-candidates-YYYY-MM-DD.md` for the operator to review. Each candidate includes the file path, line, surrounding context, and suggested wikilink. +- **Unlinked mentions:** **never auto-convert.** Write candidates to `Claude-Memory/tether-candidates-YYYY-MM-DD.md` for Nate to review. Each candidate includes the file path, line, surrounding context, and suggested wikilink. ### Dead-link handling @@ -117,16 +117,16 @@ Dry-run output is a grouped violation list: → 3 wikilinks reference [[FOO-Index]] and need rewrite ### Missing Projects-Index entries (2) -- / — not listed in Projects-Index.md -- — not listed in Projects-Index.md +- PARZVL/ — not listed in Projects-Index.md +- FIDGETCODING — not listed in Projects-Index.md ### Broken bidirectional links (4) -- / links to [[]] but .md does not list it -- / links to [[]] but .md ## Sub-projects omits it +- PARZVL/ links to [[LORECRAFT-HQ]] but LORECRAFT-HQ.md does not list it +- MMA/ links to [[MMA]] but MMA.md ## Sub-projects omits it - ... ### Unlinked mention candidates (12) -- 01-Projects//conversations/2026-04-13-misc.md:42 — "" (not linked to [[/]]) +- 01-Projects//conversations/2026-04-13-misc.md:42 — "" (not linked to [[PARZVL/]]) - ... ## Summary diff --git a/skills/wiki/SKILL.md b/skills/wiki/SKILL.md index 4911b1b..dcd3ee1 100644 --- a/skills/wiki/SKILL.md +++ b/skills/wiki/SKILL.md @@ -6,7 +6,7 @@ allowed-tools: Read, Write, Edit, Glob, Grep, Bash # wiki — add, audit, heal, find -Shared schema: `./references/wiki-schema.md` is the binding source of truth for frontmatter keys, folder roles, wikilink grammar, and the entity/concept/claim data model used below. This file defines the operator-facing behavior; the schema file defines the data. +Shared schema: `../references/wiki-schema.md` is the binding source of truth for frontmatter keys, folder roles, wikilink grammar, and the entity/concept/claim data model used below. This file defines the operator-facing behavior; the schema file defines the data. `wiki` is the single entry point for anything that treats the vault as a knowledge graph rather than a capture bucket. The `save` skill handles conversational capture. `wiki` handles graph-aware work: ingesting sources, auditing graph health, healing known deformations, and searching with citations. @@ -33,7 +33,7 @@ These are non-negotiable and apply to every branch below: 2. **Never write to `01-Projects/*/.md` or any file directly named as a project index.** Project index files are human-curated (per vault rules in `CLAUDE.md`). `wiki` may LINK into them but never mutate them. Scaffolding new projects is explicitly out of scope for this skill. 3. **Never write anywhere under `05-Tasks/`.** Task state is owned by the Obsidian Tasks plugin and the n8n 2-way sync (Obsidian ↔ Morgen, post-2026-05-04 Notion drop). `wiki` may READ tasks to resolve wikilink targets but never creates, edits, completes, or deletes a task. 4. **Every branch that writes uses its own git branch.** No direct writes to `main`. Branch names below are the contract. -5. **Every write file includes the frontmatter keys `source_of_truth`, `last_confirmed`, and `owner` per `./references/wiki-schema.md`.** +5. **Every write file includes the frontmatter keys `source_of_truth`, `last_confirmed`, and `owner` per `../references/wiki-schema.md`.** 6. **Branch pollution discipline.** If a branch already exists for today, append to it; do not create `-v2` siblings. ## 3. Branch 1 — ADD @@ -110,7 +110,7 @@ Source pages (`02-Sources/`) are strictly evidence. No interpretation, no opinio # ## Summary -<2–5 sentences, strictly what the source says. No the operator-voice. No editorial.> +<2–5 sentences, strictly what the source says. No Nate-voice. No editorial.> ## Key Claims - Claim 1 (with in-source citation if available). @@ -130,7 +130,7 @@ Source pages (`02-Sources/`) are strictly evidence. No interpretation, no opinio <optional: bullet dump of other notable quotes or data points> ``` -Interpretation, synthesis, and the operator-voice live in concept pages (`03-Concepts/`). Source pages are the audit trail. (The pre-mogging `03-Permanent/` folder was collapsed into `03-Concepts/` during the 2026-04-16 refactor.) +Interpretation, synthesis, and Nate-voice live in concept pages (`03-Concepts/`). Source pages are the audit trail. (The pre-mogging `03-Permanent/` folder was collapsed into `03-Concepts/` during the 2026-04-16 refactor.) ### 3.3 Concept page updates (prefer update) @@ -164,7 +164,7 @@ AUDIT never writes except to a timestamped report. It scans: | Dead wikilinks | `[[foo]]` where no file `foo.md` (or alias-resolved target) exists. | | Missing cross-refs | Concept A references Concept B, but Concept B has no reverse mention of A. | | Index consistency | `04-Index/Index.md` lists a page that no longer exists, or a page that exists but isn't in the index. | -| Data gaps | Pages with frontmatter fields missing per `./references/wiki-schema.md` (e.g., `source_of_truth` empty). | +| Data gaps | Pages with frontmatter fields missing per `../references/wiki-schema.md` (e.g., `source_of_truth` empty). | ### 4.1 Mechanics @@ -340,6 +340,6 @@ A critical FIND rule: the skill MUST NOT emit a `[[wikilink]]` to a page that is - **FIND → save.** FIND can propose saving a synthesis; the actual write is delegated to `/save` branch 3. - **ADD "discuss before write" residue → save.** If during DISCUSS the user says "this is really a fleeting thought, not a source," the ADD run aborts cleanly and suggests `/save` branch 3. -Both skills read the same `./references/wiki-schema.md` and the same `Claude-Memory/aliases.yaml`. If those two files ever drift, fix the schema first — it's the source of truth, and both skills are downstream. +Both skills read the same `../references/wiki-schema.md` and the same `Claude-Memory/aliases.yaml`. If those two files ever drift, fix the schema first — it's the source of truth, and both skills are downstream. -Reference: `./references/wiki-schema.md` is the binding definition for every frontmatter key, folder role, and linking grammar token used above. Read it before any write. +Reference: `../references/wiki-schema.md` is the binding definition for every frontmatter key, folder role, and linking grammar token used above. Read it before any write. diff --git a/skills/wiki/references/wiki-schema.md b/skills/wiki/references/wiki-schema.md deleted file mode 100644 index 624d52a..0000000 --- a/skills/wiki/references/wiki-schema.md +++ /dev/null @@ -1,250 +0,0 @@ -# wiki-schema.md — canonical rules for 2ndBrain-mogging - -This file is the single source of truth for every skill in `skills/*/SKILL.md`. Any skill that writes, reads, or audits the vault must resolve its folder targets, frontmatter keys, link grammar, security posture, and git contract from here. If a skill contradicts this doc, the doc wins. - -Downstream consumers (all required to reference this file): - -- `skills/save/SKILL.md` -- `skills/wiki/SKILL.md` -- `skills/challenge/SKILL.md` -- `skills/emerge/SKILL.md` -- `skills/backfill/SKILL.md` -- `skills/aliases/SKILL.md` -- `skills/autoresearch/SKILL.md` -- `skills/canvas/SKILL.md` -- `skills/tether/SKILL.md` -- `skills/connect/SKILL.md` -- `agents/{morning,nightly,weekly,health}.md` -- `hooks/stop-save.sh` - -## 1. Folder contract - -The vault follows the operator's stripped operator layout. The plugin treats each folder as having exactly one writer role plus a set of constraints. Skills that violate the writer role get hard-rejected in their own failure-mode table. - -| Folder | Role | Primary writer | Secondary writers | Constraints | -|---|---|---|---|---| -| `01-Projects/<PROJECT>/conversations/` (post-2026-05-08; `01-Projects/<PROJECT>/conversations/` was retired) | Conversation captures, daily notes, scheduled-agent reports, interactive `/wiki audit` output | `save` (branches 1–3), `wiki` (`audit` branch) | `agents/morning`, `agents/nightly`, `agents/weekly`, `agents/health` | Append-only per file. All audit and daily reports — interactive or scheduled — live under `01-Projects/VAULT/conversations/reports/` (`audit-YYYY-MM-DD.md`, `daily-YYYY-MM-DD.md`, `weekly-YYYY-WW.md`, `health-YYYY-MM-DD.md`). Scheduled agents write here and nowhere else. | -| `02-Sources/` | Source-of-truth notes for external content (articles, videos, transcripts, emails) | `save` (branch 2 `--source`), `autoresearch` | `wiki` (heal only) | Each file must carry `source_url` + `source_type` + `captured` in frontmatter. Body is summary; raw fetched text lives in a `> [!source]` callout or a fenced block. | -| `03-Concepts/` | Refined atomic concept notes | `wiki` | `save` (branch 3, type `p`), `emerge` | One concept per file. Must have ≥1 inbound from a `02-Sources/` note and ≥1 outbound to `04-Index/`. `needs_review: true` on first write; promoted by `wiki` once it has 3+ inbound links. | -| `04-Index/` | Maps of content (MOCs), hub pages, topic indexes | `wiki`, `tether` | `emerge` (weekly only) | Never append freeform text — only link lists + terse one-liners. Must list every concept in its topic cluster; `tether` fails the graph audit if an `03-Concepts/` note has no MOC entry. | -| `01-Projects/` | Project hubs mirroring Claude Projects | `save` (branches 1–3), `tether` | `wiki` (heal only) | Each project folder has an index note where filename matches folder name (`FOO/FOO.md`, never `FOO-Index.md`). Bidirectional links up to `04-Index/Projects-Index.md` are mandatory. | -| `05-Tasks/` | Obsidian Tasks plugin files + inline tasks | `save` (UUID-preserving edits only) | none | `/wiki` and `/autoresearch` are FORBIDDEN from writing here. `/save` is edit-safe only with strict UUID preservation (§5). No agent writes here. | -| `Claude-Memory/` (vault root) | Plugin working state: aliases, ADRs, manifests, hot context | `aliases`, `save` (ADR branch + backfill manifest), `emerge` (hot.md) | `agents/morning` (hot.md prime) | Not user-facing notes — treat as config. `aliases.yaml` is the canonical alias source; `adr/` holds ADRs; `backfill-manifest.jsonl` is append-only. | -| `.obsidian/` (root sidecar) | Obsidian app config | none (user-owned) | none | Forbidden path (§8). | -| `CLAUDE.md` (vault root) | Vault instructions for Claude Code | user | `wiki` (append-only to "Updated rules" section) | Never rewritten wholesale. New rules are appended with a date heading. | -| `README.md` (vault root) | Human-readable vault overview | user | `wiki` (heal only, edit existing sections) | Never created by a skill if absent — warn instead. | - -## 2. Three non-negotiables - -These override every skill-local policy. A skill that skips one of these must be treated as broken and halted. - -1. **Backup-before-write.** Before overwriting ANY file that already exists on disk, snapshot it to `Claude-Memory/backups/YYYY-MM-DD/HHMMSS--<relpath>.bak`. Preserve directory structure in the backup path (flatten separators with `--`). If the backup write fails (disk full, permissions), abort the primary write. No exceptions. - -2. **Stop-hook-jq-merge.** The `Stop` hook payload MUST be merged into existing session state using `jq --slurp 'add'` semantics, never naive concatenation. Raw string append corrupts `Claude-Memory/sessions/<id>.json` silently and breaks `/save --backfill --resume`. If `jq` is unavailable on the system path, the hook prints a WARN and no-ops rather than writing partial state. - -3. **n8n-path-filter-update.** Any skill that adds a new vault subtree (new top-level folder, new `01-Projects/<ORG>/<repo>/` with externally-synced tasks) MUST also update the n8n W1 path filter so the new subtree is ingested. The canonical path filter lives in `01-Projects/<ORG-A>/n8n-workflows/W1-paths.yaml` in the main vault. If that file is inaccessible (no symlink, no vault mounted), the skill prints a TODO row in its report and continues — it does not silently create untracked subtrees. - -## 3. Linking rules - -Graph density is the product. Each rule below exists to prevent an orphan. - -- **Wikilinks only.** Always `[[Note Name]]` or `[[Note Name|Alias]]`. Never raw vault paths (`02-Sources/2026-04-16-uri.md`) in body text — Obsidian renders them but they break on rename. -- **Inbound + outbound minimum.** Every new concept page (anything written into `03-Concepts/`) needs at least one inbound wikilink from its source(s) AND at least one outbound wikilink to a `04-Index/` MOC. Zero-inbound or zero-outbound concept pages fail `/wiki audit` and get flagged in the nightly report. -- **50/50 ambiguity.** If alias classification scores the top two candidates within 10% of each other, the content is ambiguous. Primary file is written to the higher-confidence target with full content. Stub file is written at the secondary target with `stub_of: "[[primary]]"` in frontmatter and a one-line body: `> See [[primary-basename]] — classification was 50/50. Resolved to primary on {{date}}.` Both files carry tag `#ambiguous-routing` so they can be reviewed via query. See §9 for the full rule. -- **Dead-link handling.** When `/wiki heal` or any audit detects a wikilink target that does not resolve (file removed, renamed without update), the link is rewritten to `~~[[orphaned-target]]~~ <!-- dead: YYYY-MM-DD -->` — strike-through in Obsidian rendering plus an HTML comment carrying the detection date. The comment lets us diff history. Never remove the link itself without flagging it for human review — removal is a human-only action. -- **Rename propagation.** If a skill renames a note, it MUST grep the vault for all `[[old-name]]` references and update them in the same commit. An unupdated reference is a bug, not a "nice to have". -- **Never link to a folder.** `[[01-Projects]]` is not a link; `[[Projects-Index]]` is. Folders do not have notes; MOCs/Indexes do. - -## 4. Frontmatter contract - -Every note the plugin writes must open with YAML frontmatter. Five fields are universal; per-type additions follow. - -### Universal fields (all types) - -```yaml ---- -title: "Human-readable title" # required, quote if it contains : -date: 2026-04-16 # ISO date, required -type: source | concept | synthesis | conversation | adr | moc -tags: [lowercase-hyphenated] # list, may be empty -aliases: ["Alt Name 1", "Alt Name 2"] # list, used by Obsidian link autocomplete ---- -``` - -`type` is closed-set; a skill encountering an unknown type value halts with a parse error rather than guessing. - -### Per-type additions - -**type: source** (goes to `02-Sources/`) - -```yaml -source_url: "https://example.com/article" # required; use [REDACTED] for private Slack etc. -source_type: article | video | podcast | email | transcript | pdf | book -captured: 2026-04-16T14:22:00-04:00 # RFC 3339 with TZ -last_confirmed: 2026-04-16 # last date a human verified the URL resolves -author: "Name or @handle" # optional; use "unknown" if not attributable -``` - -**type: concept** (goes to `03-Concepts/`) - -```yaml -last_confirmed: 2026-04-16 # required; used by /wiki audit staleness check -needs_review: true # auto-true on first write, flipped by /wiki promote -owner: human | llm # 'human' locks the note from silent LLM edits -``` - -**type: synthesis** (cross-concept rollups, also in `03-Concepts/` or `04-Index/`) - -```yaml -answers_question: "What is the cheapest path from X to Y?" # the question this note resolves -sources: ["[[LIT-note-a]]", "[[LIT-note-b]]"] # wikilinks to the sources feeding it -``` - -**type: adr** (goes to `Claude-Memory/adr/`) - -```yaml -status: proposed | accepted | superseded -supersedes: "[[ADR-007-old-name]]" # optional -superseded_by: "[[ADR-012-new-name]]" # optional; filled when a later ADR overrides this -``` - -**type: conversation** (goes to `01-Projects/<PROJECT>/conversations/` (post-2026-05-08; `01-Projects/<PROJECT>/conversations/` was retired)): no per-type additions beyond universal. Rely on `source: "claude-cli session <id>"` in the body if needed. - -**type: moc** (goes to `04-Index/`): no additions beyond universal. The body is the MOC structure itself. - -## 5. Obsidian Tasks plugin syntax - -the operator's task pipeline (Obsidian ↔ Morgen via n8n W1/W2, orchestrated by `W0-Sync-Orchestrator`) is downstream of this exact shape. Rewriting tokens in the wrong order or dropping the UUID breaks sync. (Notion was dropped from the sync stack on 2026-05-04; the historical W3 worker is archived.) - -### Canonical line - -``` -- [ ] <task text> <priority?> 📅 YYYY-MM-DD <🔁 recurrence?> 🆔 <uuidv4> -``` - -**Token order is mandatory.** The Tasks plugin parses positionally in several render paths. Deviating breaks Morgen tag-sync. - -Glyphs: - -- Priority: 🔺 highest · ⏫ high · 🔼 medium · 🔽 low · ⏬ lowest -- Dates: 📅 due · ⏳ scheduled · 🛫 start · ✅ done · ❌ cancelled -- Recurrence: `🔁 every week`, `🔁 every 2 weeks`, `🔁 every month on the 1st` -- 🆔 stable identifier, UUIDv4, mandatory on every new task - -### UUID rules (non-negotiable) - -1. **Every new task gets a 🆔.** Generate with `uuidgen | tr '[:upper:]' '[:lower:]'`. Append AFTER date/recurrence tokens, never inside the body. -2. **Edits preserve 🆔 byte-for-byte.** A rewrite that changes or drops the UUID creates a duplicate task in Morgen that cannot be silently undone. The fix costs the operator 15+ minutes of manual deduping. (Pre-2026-05-04 the duplicate also appeared in Notion; Notion was dropped from the sync stack on 2026-05-04.) -3. **Missing UUID on a legacy task = mint + log.** If a skill touches a task line that lacks 🆔, it mints one AND appends a line to `Claude-Memory/task-uuid-mints.log` recording (file, line, uuid, timestamp). The mint is a side effect, so it must be auditable. - -## 6. Security scrub - -Every write path — file body AND commit message — passes through this regex panel first. Matches are replaced in-place with `[REDACTED:<TYPE>]`. Matches in commit messages also cause a preview warning row so the user sees what got swapped out. - -| Pattern | Type | -|---|---| -| `sk-ant-[A-Za-z0-9_-]{20,}` | `ANTHROPIC_KEY` | -| `sk-proj-[A-Za-z0-9_-]{20,}` | `OPENAI_PROJECT_KEY` | -| `ntn_[A-Za-z0-9]{20,}` | `NOTION_INTEGRATION_TOKEN` | -| `ghp_[A-Za-z0-9]{36,}` | `GITHUB_PAT_CLASSIC` | -| `gho_[A-Za-z0-9]{36,}` | `GITHUB_OAUTH_TOKEN` | -| `github_pat_[A-Za-z0-9_]{22,}` | `GITHUB_PAT_FINE` | -| `AKIA[0-9A-Z]{16}` | `AWS_ACCESS_KEY` | -| `xox[baprs]-[A-Za-z0-9-]{10,}` | `SLACK_TOKEN` | -| `ya29\.[A-Za-z0-9_-]+` | `GOOGLE_OAUTH_TOKEN` | -| `sbp_[A-Za-z0-9]{40,}` | `SUPABASE_KEY` | -| `sk_live_[A-Za-z0-9]{24,}` | `STRIPE_LIVE_KEY` | -| `rk_live_[A-Za-z0-9]{24,}` | `STRIPE_LIVE_RESTRICTED` | -| `v1\.0-[A-Za-z0-9_-]{30,}` | `CLOUDFLARE_API_TOKEN` | -| `eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}` | `JWT` | -| `-----BEGIN (RSA|EC|DSA|OPENSSH|PRIVATE) KEY-----` + body + `-----END ...-----` | `PEM_PRIVATE_KEY` | -| `^[A-Z][A-Z0-9_]+=.+$` inside a block that looks like `.env` (≥3 matching lines in a row) | `ENV_LINE` | - -### the operator-specific PII - -- `operator@example.com` stays as-is in plugin code but is redacted from any note body that would land in a public-sync branch. -- Named collaborators identified as `internal_only: true` in the private aliases registry MUST be redacted from READMEs, release notes, migration docs, or any commit subject. (Memory rule: never reference internal-only collaborators by name in any public repo artifact.) -- Client names flagged `visibility: private` in the same allowlist are redacted the same way. Public mentions are fine only when the allowlist marks them `visibility: public`. - -Scrub failure closed: if the regex engine errors (malformed pattern, OOM on huge paste), the write is refused rather than proceeding with partial scrub. - -## 7. Git conventions - -The vault is a git repo; the mogging plugin ships commits from skills and agents alike. the operator's `obsidian-tasks-sync` infra uses commit prefixes to distinguish human commits from bot commits for n8n W1 filtering. - -### Branch naming - -- `wiki-add/YYYY-MM-DD-slug` — new concept, new MOC, or net-new folder scaffolding. -- `wiki-heal/YYYY-MM-DD` — audit fixes: dead links, missing frontmatter, orphan repair. -- `backfill/YYYY-MM-DD` — `/save --backfill` historical transcript ingestion. - -Date format is ISO (`YYYY-MM-DD`). Slugs are lowercase, hyphenated, ≤40 chars. - -### Commit prefixes (MUST appear as first token in the subject line) - -| Prefix | Used by | Purpose | -|---|---|---| -| `[bot:save]` | `save` (all non-backfill branches) | Skip n8n W1 re-fire; flag for human audit. | -| `[bot:save --backfill]` | `save --backfill` | Same as above but trivially filterable in `git log`. | -| `[bot:wiki-add]` | `wiki add`, `connect`, `tether` (new-note paths) | New concept/MOC/link scaffolding. | -| `[bot:wiki-heal]` | `wiki heal`, `nightly audit` fixups | Link repair, frontmatter backfill, orphan dressing. | -| `[bot:backfill]` | `backfill` skill (non-save entry) | Historical content ingestion outside `save`. | - -All five prefixes MUST be listed in the n8n W1 filter or the bot will get stuck in a self-retrigger loop. The filter is kept in `01-Projects/<ORG-A>/obsidian-tasks-sync/config/bot-prefixes.yaml` in the live vault. - -### Rules - -- **No force-push.** Ever. If a branch is broken, create a new one. -- **No interactive rebase via skill.** `git rebase -i` requires a human at the keyboard. -- **Direct-to-main is allowed** on the vault repo per the operator's fidgetcoding convention — skills SHOULD still push to a short-lived branch and fast-forward merge so the branch name carries the session context, but they MUST NOT fail if the remote configuration blocks branching (degraded mode: commit to main directly). -- **Never `git commit --no-verify`** or `--no-gpg-sign`. Hooks exist to protect the repo; bypassing them erases their value. - -## 8. Forbidden paths (all skills) - -Every skill refuses to read, write, or list these paths. Path allowlist check runs BEFORE every `Write`/`Edit`/`Bash`: - -``` -.obsidian/** -.git/** -node_modules/** -**/.env* -**/credentials* -**/*.key -**/*.pem -**/*.p12 -**/.ssh/** -``` - -Additional per-skill forbidden paths: - -- **`/wiki` and `/autoresearch`** are additionally forbidden from writing anywhere under `05-Tasks/**`. Task management is human-sovereign plus `/save`-only. -- **`/save` is the sole exception** for `05-Tasks/` — and even then only edit-safe with strict UUID preservation (§5). -- **No skill writes** to `CLAUDE.md` in the vault root wholesale — only append a dated block to the "Updated rules" section if one exists. - -Refusal output format (required): - -``` -REFUSED: <absolute path> is in the forbidden list (<rule name>). -Suggestion: <sibling legal path if obvious, else "no safe alternative — clarify intent">. -``` - -## 9. 50/50 wikilink rule (ambiguous classification) - -When alias scoring produces two top candidates within 10% of each other, the content gets double-filed — primary at the higher-confidence target, stub at the secondary — with explicit breadcrumbs. - -**Primary file** (higher confidence): - -- Full content body is written here. -- Frontmatter includes the normal per-type fields plus `ambiguous_with: "[[secondary-basename]]"`. -- Tag `#ambiguous-routing` is appended to `tags`. -- Commit message calls out the ambiguity. - -**Stub file** (secondary): - -- Body is a single `> See [[primary-basename]] — classification was 50/50 between this project and that one. Resolved to primary on YYYY-MM-DD.` -- Frontmatter includes `stub_of: "[[primary-basename]]"` plus the same `#ambiguous-routing` tag. -- No further content. No auto-promotion. Stub stays stub until a human upgrades it with `/save` branch 2 + explicit destination. - -Both files are surfaced in the dry-run preview table so the user can override with `edit` before writing. If the secondary candidate scores below 30% confidence, the 50/50 rule does NOT fire — instead, the skill routes to `02-Sources/` with a TODO (the pre-mogging `00-Inbox/` was killed on 2026-04-16). Stubbing random weak candidates adds noise, not signal. - -End of `wiki-schema.md`. Any skill contradicting this file is the bug; fix the skill. diff --git a/tests/fixtures/sample-vault/01-Projects/.gitkeep b/tests/fixtures/sample-vault/01-Conversations/.gitkeep similarity index 100% rename from tests/fixtures/sample-vault/01-Projects/.gitkeep rename to tests/fixtures/sample-vault/01-Conversations/.gitkeep diff --git a/tests/fixtures/sample-vault/05-Tasks/.gitkeep b/tests/fixtures/sample-vault/05-Projects/.gitkeep similarity index 100% rename from tests/fixtures/sample-vault/05-Tasks/.gitkeep rename to tests/fixtures/sample-vault/05-Projects/.gitkeep diff --git a/tests/fixtures/sample-vault/06-Tasks/.gitkeep b/tests/fixtures/sample-vault/06-Tasks/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_aliases_bootstrap.sh b/tests/test_aliases_bootstrap.sh index 0dadbbc..98b1bb8 100644 --- a/tests/test_aliases_bootstrap.sh +++ b/tests/test_aliases_bootstrap.sh @@ -71,8 +71,8 @@ fi # Case 2: existing customized file is preserved verbatim. # --------------------------------------------------------------------------- CUSTOM_CONTENT='aliases: - operator: ["the operator", "operator"] - <ORG-A>: ["<ORG-A>", "<ORG-A>"] + nate: ["Nate", "nate"] + lorecraft: ["Lorecraft LLC", "lorecraft-io"] # user-custom-marker-do-not-remove ' printf '%s' "$CUSTOM_CONTENT" > "$ALIASES_YAML" @@ -86,7 +86,7 @@ assert_eq "$AFTER_MD5" "$BEFORE_MD5" \ assert_contains "$ALIASES_YAML" "user-custom-marker-do-not-remove" \ "user comment preserved in aliases.yaml" -assert_contains "$ALIASES_YAML" "<ORG-A>:" \ +assert_contains "$ALIASES_YAML" "lorecraft:" \ "user-defined alias entry preserved" assert_report diff --git a/tests/test_onboarding.sh b/tests/test_onboarding.sh index bd558c6..8a5aae3 100644 --- a/tests/test_onboarding.sh +++ b/tests/test_onboarding.sh @@ -67,7 +67,6 @@ run_install() { # would attempt a real `brew install --cask obsidian` (slow + flaky in CI). # The other --no-* flags isolate the install to the temp HOME. HOME="$FAKE_HOME" \ - CLAUDE_HOME="$FAKE_HOME/.claude" \ VAULT_DIR="$FAKE_VAULT" \ bash "$INSTALL_SH" --vault "$FAKE_VAULT" --apply \ --no-launchd --no-obsidian-app --no-obsidian-mcp \ @@ -169,15 +168,13 @@ SETTINGS="$FAKE_HOME/.claude/settings.json" assert_file "$SETTINGS" "settings.json still present" assert_json_valid "$SETTINGS" "settings.json still valid JSON after merge" -# Count Stop hooks that wrap our hooks/stop-save.sh. Fingerprint on the script -# name, not the repo dir name — checkouts are often lowercase, and a user's -# unrelated pre-existing hooks may mention "2ndbrain". +# Count Stop hooks that reference '2ndbrain'. COUNT_2B_STOP=0 if command -v jq >/dev/null 2>&1; then COUNT_2B_STOP=$(jq ' [ .hooks.Stop[]? | .hooks[]? - | select(.command | test("hooks/stop-save\\.sh"; "i")) + | select(.command | test("2ndbrain"; "i")) ] | length ' "$SETTINGS" 2>/dev/null || echo 0) fi @@ -224,7 +221,7 @@ if command -v jq >/dev/null 2>&1; then COUNT_2B_STOP2=$(jq ' [ .hooks.Stop[]? | .hooks[]? - | select(.command | test("hooks/stop-save\\.sh"; "i")) + | select(.command | test("2ndbrain"; "i")) ] | length ' "$SETTINGS" 2>/dev/null || echo 0) fi diff --git a/tests/test_preflight.sh b/tests/test_preflight.sh index e984e21..5a9f17e 100755 --- a/tests/test_preflight.sh +++ b/tests/test_preflight.sh @@ -175,7 +175,7 @@ fi # --------------------------------------------------------------------------- # Case 5: --vault points at a non-existent path → installer auto-creates it. # -# <ORG-D> install-call (2026-04-22, item 5) intentionally changed this behavior: +# WAGMI install-call (2026-04-22, item 5) intentionally changed this behavior: # teammates were getting bounced when their freshly-installed Obsidian had not # yet created the vault folder, so install.sh now `mkdir -p`s the path inside # validate_vault and continues. The earlier exit-21 contract is dead. We pin diff --git a/why-not-agricidaniel-pure.md b/why-not-agricidaniel-pure.md index f5372c1..b7a69b9 100644 --- a/why-not-agricidaniel-pure.md +++ b/why-not-agricidaniel-pure.md @@ -26,7 +26,7 @@ I still had to rewrite a couple of its core primitives to match my operational r **`/aliases`.** Manage `Claude-Memory/aliases.yaml` — add a new alias, split an overloaded one, rename, audit for overlap. The file is the single point of truth for classification, so it needs a dedicated editing skill, not just hand-editing YAML. Not in his pack. -**`/tether`.** Audit project-index bidirectional links, MOC membership, GITHUB/<ORG-A> hub wiring, and sub-project back-references. Report orphans. Fix them (with dry-run default). The graph-tethering rules in my vault are load-bearing; when they break, my graph view becomes useless. `/tether` keeps them intact. Not in his pack. +**`/tether`.** Audit project-index bidirectional links, MOC membership, GITHUB/LORECRAFT-HQ hub wiring, and sub-project back-references. Report orphans. Fix them (with dry-run default). The graph-tethering rules in my vault are load-bearing; when they break, my graph view becomes useless. `/tether` keeps them intact. Not in his pack. ## When AgriciDaniel's pack is still better diff --git a/why-not-karpathy-pure.md b/why-not-karpathy-pure.md index f74c95d..00ea671 100644 --- a/why-not-karpathy-pure.md +++ b/why-not-karpathy-pure.md @@ -1,6 +1,6 @@ # Why not Karpathy's gist directly -Andrej Karpathy's [LLM Wiki gist](https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f) is the seed idea for every project in this space, including this one. If you only need what it provides, use it — it is shorter, simpler, and does one thing cleanly. You do not need this pack. +Andrej Karpathy's [LLM Wiki gist](https://gist.github.com/karpathy/3d3797cfe72b4fd78dab7a5c35caf0f9) is the seed idea for every project in this space, including this one. If you only need what it provides, use it — it is shorter, simpler, and does one thing cleanly. You do not need this pack. ## What Karpathy's gist provides