CLAUDE.md · diff

git:20260627.ab8aa49 to git:20260928.6cec334

37 added, 39 removed. Audit A to A.

# CLAUDE.md
- Working notes for AI agents in this repo (the Python Scout engine/plugin).
+ Working notes for AI agents in the Scout monorepo.
- ## Fixtures must be anonymized — this repo and its two siblings are public
+ ## This repo holds two shipping artifacts
- Scout runs against a real person's vault, so anything lifted from it into a
- fixture or an inline test string **must be scrubbed before it lands**. All three
- Scout repos — this one, `Scout` (desktop), and `scout-iOS-app` — are public.
+ | Path | Artifact | Read next |
+ |---|---|---|
+ | `plugin/` | The Scout Claude Code plugin + Python engine (`scoutctl`) | `plugin/CLAUDE.md` |
+ | `apps/macos/` | The Scout macOS menu-bar app (SwiftUI) | `apps/macos/CLAUDE.md` |
- - **No real identifiers.** Strip company/product names, real coworker names, real
- Linear IDs, GitHub repos, and Slack workspaces/channels. Use the shared
- stand-ins so fixtures stay internally consistent:
- - People: `Alex` / `Priya` / `Sam`; comment author `alex`.
- - Linear: `PROJ-1234` (neutral prefixes like `OPS-`, `DESK-` for variety) —
- never the real team prefixes (`AI-`, `KAI-`, `ST-`, …).
- - GitHub: `example-org/<repo>`.
- - Slack: `acme-co.slack.com/archives/C0123456789/p1700000000000000`.
- - Vendors/products: a generic noun, not the brand.
- - **Anonymize content, not structure.** Keep the tokens the parser is tested on
- (synthetic `[#TAG]` prefixes, `**bold**`, `_(italic)_`, `[[wikilinks]]`,
- ` — ` separators, `` `code` ``). Only swap the words around them.
- - **Don't hardcode personal config in source.** The Linear deep-link workspace is
- read from `SCOUT_LINEAR_WORKSPACE` (default `your-workspace`), not baked in;
- keep new connector/workspace specifics config- or env-driven the same way.
- - **Preserve legitimate attribution** — NOT leaks, leave them: `pyproject` authors,
- `.claude-plugin/marketplace.json` / `plugin.json` owner, `LICENSE`, and the
- project's own `github.com/<org>/…` URLs (including the self-update URL).
+ **Work in the subtree that owns the change, and read that subtree's `CLAUDE.md`
+ first.** The two have different languages, test runners, and release flows.
- ### `parser-corpus.json` is ONE byte-identical file living in three repos
+ ## Rules that span both subtrees
- `engine/tests/fixtures/contract/parser-corpus.json` is the **canonical** copy;
- `Scout` (desktop) and `scout-iOS-app` vendor byte-identical copies, checksum-guarded
- on both the Python and Swift sides — so you cannot edit just one copy. On any change
- (anonymizing counts):
+ - **`.claude-plugin/marketplace.json` lives at the REPO ROOT**, not in `plugin/`.
+ `claude plugin marketplace add` reads it from there. `plugin.json` — the
+ canonical version — lives at `plugin/.claude-plugin/plugin.json`.
+ - **Everything the plugin needs at runtime must stay under `plugin/`.**
+ `CLAUDE_PLUGIN_ROOT` resolves to the materialized `plugin/` subtree only; a
+ plugin file that reaches outside it is broken for every installed user, and
+ nothing in this repo will tell you.
+ - **Tags are prefixed:** `plugin/vX.Y.Z`, `app/vX.Y.Z`. Never push a bare
+ `vX.Y.Z` — the two artifacts collided on `v0.5.0`–`v0.9.0` before the merge.
+ - **Contract artifacts are generated, never hand-edited.** The connector roster
+ and schedule snapshot have one canonical source under
+ `plugin/engine/scout/` and are copied into `apps/*/`. Edit the `.yaml`, then
+ regenerate — `contract.yml` fails the build if a copy drifts. See
+ `docs/superpowers/specs/2026-09-03-monorepo-consolidation-design.md` §7.
+ - **Never edit a `*.snapshot.json` by hand.** That is what broke the shipped
+ connector roster for four months.
+ - **Plugin history was absorbed with `git subtree`, SHAs preserved.** `git blame
+ plugin/<file>` crosses the merge to the original commits, but `git log --
+ plugin/<file>` stops at the merge commit — for a plugin file's earlier
+ history run `git log <subtree-merge>^2 -- <path without the plugin/ prefix>`
+ (the first subtree merge is the commit titled "absorb scout-plugin into
+ plugin/").
- 1. Edit the corpus here; keep every `expected` field consistent with the parser
- (`pytest tests/unit/test_parser_contract.py` is the judge).
- 2. Copy it byte-for-byte into the sibling checkouts (cloned alongside this repo):
- - `../Scout/ScoutTests/Fixtures/parser-corpus.json`
- - `../scout-ios/ScoutMobileTests/Fixtures/parser-corpus.json`
- 3. Update BOTH checksum guards to the new `shasum -a 256` of the file:
- - `EXPECTED_SHA256` in `engine/tests/unit/test_parser_corpus_checksum.py`
- - `canonicalSHA256` in `../Scout/ScoutTests/ActionItems/ParserContractTests.swift`
- 4. Verify all three: `pytest tests/unit/test_parser_contract.py
- tests/unit/test_parser_corpus_checksum.py`, plus each Swift repo's
- `ParserContractTests`.
+ ## Cross-cutting changes
+
+ A change touching both subtrees (a new `scoutctl` subcommand the app calls, a
+ snapshot schema change) lands as ONE commit, and `contract.yml` is the gate.
+ That is the entire reason these repos were merged — do not split such a change
+ across two PRs out of habit.