# Agent rules for the `linker` repo (reddit → spotify/bandcamp) A Firefox extension + a tiny Node resolver that turn artist/band names in reddit comments into Spotify/Bandcamp links. This file is the repo-local doctrine; the work is tracked in the **towl** work-item store under project **`reddit-spotify-linker`**. ## Stack & layout - `service/` — zero-dependency Node resolver (Node 18+, built-in `fetch`/`http`). `resolver.js` = the HTTP server; `lib.js` = pure, side-effect-free logic (the artist-match precision lever) so it's unit-testable; `lib.test.js` = `node:test`. - `extension/` — Firefox **MV2** content script (`content.js` + `manifest.json` + `styles.css`). No build step. - `scripts/check.sh` — the local check gate. ## How work lands (IMPORTANT — this is NOT the towl repo) `linker` is hosted at **git.yapplesauce.com/paul/linker**, a **plain repo**: there is **no PR pipeline and no branch protection**. You **push to `main` directly** (via the user's PAT). Do **not** use `towl-orchestrate` / worktree+PR here. 1. Make a small, reversible change. 2. Run the gate: `bash scripts/check.sh` (must print `ALL CHECKS PASSED`). 3. Commit citing the towl ref (e.g. `(task/odesli-direct-links)`), push `main`. 4. Stamp the SHA on the towl item: `stamp_commit { ref, sha, repo: "linker" }`. 5. Close the towl item. **NEVER touch the `towl` or `stickball` repos from work scoped to this project.** ## Testing (zero-dep) `node --test` over `service/*.test.js` exercises `lib.js` (norm + the exact-name match + link builders). Keep pure logic in `lib.js` (not `resolver.js`, which has the server side effect) so it stays testable without opening a port. **Add/extend a test with every logic change.** The extension's in-browser behavior is **not** headlessly testable in this environment — validate `content.js` with `node --check` and a documented manual check on a real reddit thread (`about:debugging` → load temporary add-on). ## Code stewards (towl plans under objective/linker-stewardship) Standing, language-appropriate stewards (adapted from towl's SCOUT→FILE doctrine; run them like any other steward — e.g. via a `/loop`). Each files findings into towl and fixes small things directly. - **quality** (`plan/steward-linker-quality`) — correctness + regressions; **owns and maintains `scripts/check.sh` and the `node:test` suite**. - **design** (`plan/steward-linker-design`) — detection precision/recall, the injected-link UX, README accuracy, reddit-DOM drift. - **security** (`plan/steward-linker-security`) — DOM injection (build nodes via `createElement`/`textContent`, **never `innerHTML`**; http(s) hrefs only), minimal extension permissions, bounded external API calls (no SSRF), secrets never logged/committed (`.env` is gitignored). ## Standing decisions - Firefox **MV2** stays — Mozilla has no deprecation timeline; do not migrate to MV3 speculatively. - **No ML/NER** in the resolver — keep it zero-dep; improve detection with cheap heuristics + the API exact-match filter. - Detection precision lever: a candidate links **only** when a music API returns an artist whose name matches it case-insensitively.