# Explicit Formula - The Loop (Obsidian plugin) Brain-dump what you want. See exactly what the AI heard. **Lock the lines it got right — it redoes only the rest.** When it finally reads like your own thought, copy the finished prompt into any AI, insert it into your note, or answer it right in the panel. Locked lines can never quietly change: they are enforced verbatim by a mechanical check that runs **twice** — on the server and again inside this plugin (`src/api.ts`). If anything upstream misbehaves, your locked lines are put back and the panel tells you so. ## ⚠️ Network use (read this) This plugin sends **the text you type into the loop panel** (your dump, and the lines being re-derived) to the Explicit Formula service (`https://www.explicitformula.com` by default, configurable in settings) to run the interpretation. No telemetry is collected. **Vault context is OFF by default.** If — and only if — you list folders in Settings → "Folders the loop may read", the plugin selects up to 6 small snippets (≤2400 characters total) from those folders to ground the interpretation, chosen locally by a deterministic scorer (your words × your own note links × recency; nothing ships on link- or recency-proximity alone). **Every round shows exactly what left your machine** — each note name with its character count, inline above the lines. Empty the folder list and vault reads stop entirely. ## Publishing to the community directory (maintainer) This package is the canonical source, but the Obsidian directory reads `manifest.json`, `README.md`, and `LICENSE` from the **root** of the plugin's repository and pulls `main.js` / `manifest.json` / `styles.css` from a GitHub release whose tag equals the manifest version — rules a monorepo package cannot meet. So the plugin is published from a dedicated mirror repo, **travisbergen2/explicit-formula-loop**, regenerated from here: ``` npm run mirror --workspace=packages/obsidian # → dist/explicit-formula-loop (root files, src/, vendor/rpcs1-core) cd dist/explicit-formula-loop && node esbuild.config.mjs production # → main.js (minified) ``` Then push the mirror, create a release tagged exactly `manifest.version` with `main.js`, `manifest.json`, `styles.css` attached, and (first time only) add the plugin at community.obsidian.md → *Add plugin* with the mirror repo. Updates flow from new releases automatically. `tests/listing.test.ts` pins the directory's manifest/name/description rules and the repo-file requirements; `vendor/rpcs1-core` in the mirror is a snapshot of `packages/core/src` (MIT) because the bundle ships the engine and a plugin cannot resolve workspace packages at runtime. Never edit the mirror by hand. ## Install (manual) 1. Build: `npm run build --workspace=packages/obsidian` (from the repo root) 2. Copy `manifest.json` and `main.js` into `/.obsidian/plugins/explicit-formula-loop/` 3. Enable "Explicit Formula - The Loop" in Settings → Community plugins Works on desktop and mobile (`isDesktopOnly: false`). ## Use - Ribbon icon or command **"Open the Loop panel"** - **"Start a loop from the selected text"** — your selection becomes the dump - **"Start a loop from this note"** — the whole note becomes the dump - Tap lines to lock them → **Redo the unlocked lines** → repeat → **It's right — finish it** → Copy / Insert into note / Answer it here ## Development ``` npm run test --workspace=packages/obsidian # unit tests (API client, ratchet re-verify) npm run lint --workspace=packages/obsidian # tsc --noEmit npm run build --workspace=packages/obsidian # esbuild bundle -> main.js ``` The loop engine itself lives in `@rpcs1/core` (`packages/core/src/loop.ts`) and is bundled into `main.js` at build time. A fixture vault for manual testing is in `fixture-vault/`. ## Scope (P1) and what's next ## Import my AI history (P4) Command palette → **"Import my AI history (ChatGPT / Claude)"** — a file picker, zero terminal. Hand it whatever you have: the ChatGPT export zip, Claude's `conversations-000.zip`, either vendor's `conversations.json`, or Claude's `claude_data.json` manifest (the modal shows the manifest's one-time download link to open in your own browser — this plugin never fetches it; its network use stays explicitformula.com only). The law, same as everywhere: every conversation's **full text lands in `Private/Archive//`** — keep Private off your allowlist and no connected AI can read any of it. Conversations matching research/build vocabulary get a small **index stub** in `Notes/Archive index/` (title + topic terms only, no content), plus an import report listing **possibly forgotten threads** — research topics that appear rarely across your whole history. Re-imports never overwrite: colliding names get suffixed. ## Wire the archive into topics (P5) After importing, command palette → **Wire my archive into topics (graph clusters)**. Each archive stub links to auto-generated `Notes/Topics/` hub notes, collapsing the disconnected import point-cloud into topic-centred clusters in the graph view. Hubs are regenerable; each stub is linked once. **Honest scope (pre-registered):** E-WIRE-1 tested whether this also improves *retrieval* and the frozen grammar returned **FAIL** — hubs compete with stubs for the 6-snippet search budget (reach improved when a hub surfaced, but ranking displacement failed the null). So this ships as a **graph- legibility feature, not a retrieval feature**. Making topics improve search needs a reserved hub lane in the server (the E-WIRE-2 candidate), not this wiring. ## Your graph shows the work (P3) Finish a session and hit **Save to my vault**: the session lands as an ordinary note (`Loop/ .md`) that **wikilinks every note that grounded it** — open the graph view and each conversation appears wired into the knowledge it drew from. `Loop/learnings.md` gains one line per session (rounds, locked count, sources): fewer rounds over time means the loop is starting closer to what you mean. Both write-backs have off-switches; everything written is a visible, editable, deletable file. **Copy my context pack** puts your recent loop history on the clipboard to paste before a prompt in any AI. ## Built for access (P4 — mobile + accessibility pass) The Loop is designed to work when reading dense text, fine motor control, or instant-response pressure are the obstacle — that's the point of the product, so it's the spec, not a retrofit: - **Works on phones and tablets.** The plugin runs in Obsidian Mobile (iOS and Android). On mobile, every tap target is at least 44px with spacing to prevent mis-taps. - **Voice input**: on mobile, your keyboard's mic key dictates straight into the dump box — nothing extra to install, nothing extra leaves your machine. - **Screen readers**: lock state is announced on every line (`aria-pressed`), finished rounds and "what left your machine" are announced politely without interrupting, and focus lands somewhere useful after every step instead of vanishing. - **Buttons for everything** — no gesture is ever required. - **Panel text size** (Settings): Default / Large / Larger, scoped to the Loop panel; your Obsidian and theme settings stay in charge everywhere else. Lock state is never shown by color alone (✓ prefix + border weight). - **Response pacing** (Settings): a minimum time between asking and seeing results, for anyone who needs answers to not appear instantly. Slow connections count toward it — pacing never adds delay on top. - **Reduced motion**: the panel defines no animations, and a `prefers-reduced-motion` guard covers anything added later. If an accessibility barrier still bites you, open an issue — barriers are treated as bugs, not feature requests. Powered by [rpcs1.dev](https://rpcs1.dev) — the receiver engine behind Explicit Formula. P1 = the panel only, no vault reads. Coming per the Phase B spec: context from your own notes (opt-in, folder allowlist, per-round "what left your machine" log), session write-backs that wikilink to their source notes (visible in the graph view), and a context-pack command for carrying your context into any AI.