From 741c156b5e56d986147db32a2f3dc99343c20aee Mon Sep 17 00:00:00 2001 From: pashifika Date: Sat, 29 Aug 2026 01:23:38 +0900 Subject: [PATCH 1/5] docs: write the operator and authority documentation `CLAUDE.md` becomes the authority for repository guidance and now carries each rule with the mechanism that makes it one: the branch rule with real examples, the merge-only restriction with the dependent-pull-request cost a squash imposes, the CI contract, where a new test belongs, and the standing prohibitions. Two prohibitions changed rather than moved. The `AGENTS.md`/`RULES.md` entry now states that it scopes to an operator's runtime agent directory and explicitly not to this repository's own root files, which are a different thing and read as a contradiction without that sentence. The `.omp/` entry is rewritten because the old wording -- never delete a directory this package or its verification did not create -- permitted deleting one the verification *did* create, which is exactly how the operator's project-local `config.yml` and skills root were lost. The incident is recorded with it. `CONTRIBUTING.md` is new and holds only credentialed procedures: the release path in order, and the ruleset import. It links the authority for every rule rather than restating one. `README.md` is rewritten through the `readme-creator` skill, classified as a CLI tool by how operators consume it, scored 27/27 on its checklist. Three documented facts were wrong and are corrected: the marketplace source format took `owner/repo` and not a `github:` spec, the marketplace install cannot resolve until v0.1.0 is tagged, and CBM 0.10.8 reports 43 client surfaces rather than 44 -- a count that moves each release, so it is gone. `watcher_enabled` was documented as a measured CBM default and no such key exists. --- CLAUDE.md | 274 ++++++++++++++++++--------- CONTRIBUTING.md | 72 +++++++ README.md | 487 ++++++++++++++++++++++++++---------------------- 3 files changed, 530 insertions(+), 303 deletions(-) create mode 100644 CONTRIBUTING.md diff --git a/CLAUDE.md b/CLAUDE.md index 66a1641..923d06b 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,51 +1,22 @@ # Repository Guidelines -## Authority +## Authority and scope + +`omp-codebase-memory` distributes `codebase-memory-mcp` (CBM) as an installable +OMP extension: it owns the executable's lifecycle, wires one MCP server entry, +and ships context artifacts harvested from that executable. It is TypeScript on +Bun, has no npm runtime dependencies, and commits its bundled entry points at +`dist/index.js` and `dist/augment.js`. `README.md` states what the package does +for an operator; this file does not restate it. `rasen/specs/` contains the accepted capability specifications and outranks change proposals. `rasen/changes/` records design decisions and their rationale; -do not duplicate that rationale here. - -When implementation changes a normative decision, update the affected -specification in the same change. +do not duplicate that rationale here. When implementation changes a normative +decision, update the affected specification in the same change. -## Project boundaries - -`omp-codebase-memory` distributes `codebase-memory-mcp` (CBM) as an installable -OMP extension. It is TypeScript on Bun, has no npm runtime dependencies, and -commits its bundled entry points at `dist/index.js` and `dist/augment.js`. - -The following boundaries are fixed: - -- Consume CBM release artifacts; contributing changes to - `DeusData/codebase-memory-mcp` is out of scope. -- Adopt an existing `codebase-memory-mcp` on `PATH` and never replace it. Put a - package-managed copy under a package-owned root outside the plugin tree. Never - write `~/.local/bin` or modify an executable this package did not install. -- Own exactly the `codebase-memory-mcp` key under `mcpServers` in the active OMP - agent directory's `mcp.json`. Upsert it idempotently, fail closed on an - unparseable file or foreign `command`, and remove it only while it still - matches the package-owned entry. -- Never create or modify an operator's OMP agent-directory `AGENTS.md` or - `RULES.md`. -- Never register a `tool_call` handler. Augment successful output through - `tool_result`, append rather than replace prior content, and fail open. -- Never use platform timer globals. Use the handler context's managed timers - through `src/scheduler.ts`. -- Never set an account-wide CBM configuration key for the operator. -- Never duplicate an action already exposed through CBM's MCP tools, including - indexing. -- Never hand-edit generated context artifacts; regenerate them from the CBM - executable. -- Never place verification scratch inside a directory the operator owns, and - never delete a directory this package or its verification did not create. A - project-local plugin root belongs in a temporary directory, not under the - repository's `.omp/`, which holds the operator's own project-local skills and - configuration. - -This package owns only the executable it downloaded and its MCP entry. CBM owns -the graph, indexing, watcher, cache root, and updates to a system installation. -Windows and changes to any other operator file are out of scope. +This file is the authority for repository guidance. `AGENTS.md` is a tracked +symbolic link to it, so both agent tool families read one text; do not create a +second copy of these rules anywhere. ## Repository layout @@ -60,65 +31,202 @@ The working tree contains two independent Git repositories: ## Git workflow -`main` and release tags are protected by the committed rulesets under -`.github/rulesets/`. Before implementation, create a short-lived topic branch -named `/`. - -Use Conventional Commits and land changes through pull requests. The ruleset -permits merge commits only; do not squash. Unresolved review threads block the -merge. - -Treat the committed rulesets as authoritative. Change and reimport those files -rather than editing protection through the web interface. +Never commit implementation to the default branch. Cut a short-lived topic +branch from it before implementation begins, and name it `/` +using the Conventional Commits type that dominates the change. Branches already +landed this way: `feat/graph-context-and-agents`, +`docs/repository-guidelines`, `chore/commit-ruleset-payloads`. + +The default branch and release tags are protected by the rulesets committed +under `.github/rulesets/`. Those files are the authority for every parameter; +read them rather than trusting a value repeated in prose. Their shape: + +- The default branch rejects deletion and non-fast-forward pushes. +- Landing a change requires a pull request whose review threads are resolved. +- The merge commit is the only permitted merge method. +- Exactly one status check, named `ci`, is required, under a strict policy — so + a branch must be current with the default branch before it can merge. +- Release tags matching the ruleset's pattern reject deletion and + non-fast-forward pushes. + +Change protection by editing those files and reimporting them, never through the +web interface. A rule changed in the browser is invisible to review and is +overwritten by the next import. + +The merge-only restriction is pinned rather than preferred. A squash rewrites +the commits a dependent pull request still carries, so every downstream diff +re-inflates with changes that already landed and each dependent branch needs a +rebase per merge. Preserving the commits is what makes a dependent pull-request +chain cheap here: a branch stacked on another stays mergeable while its parent +lands. + +Commit messages follow Conventional Commits. Choose commit boundaries for +coherence — one reviewable decision per commit — rather than by file count or +by when the work happened. ## CI and release Branch protection requires one status check named `ci`. It is the gate job in -`.github/workflows/ci.yml`, runs under `if: always()`, fails when it aggregates -no jobs, and accepts only successful dependencies. - -- Update the gate's `needs` whenever a required runtime job changes. Do not add - runtime job names to the ruleset. -- Keep `install-check` outside the gate because it cannot install a pull - request's merge ref. -- Pin every external `uses:` to a full 40-character commit SHA followed by a - version comment. -- Default to `permissions: contents: read`, use - `persist-credentials: false`, and grant `contents: write` only to the release - publish job. -- Do not apply `paths` filters to jobs required by the gate. +`.github/workflows/ci.yml`: it runs under `if: always()`, fails when it +aggregates no jobs, and accepts only successful dependencies. `always()` is +load-bearing, because a skipped required check blocks a pull request instead of +failing it. + +- Runtime job names never appear in a ruleset. Adding, removing, or + restructuring a runtime job means editing the gate's `needs` and nothing else. + Renaming the gate job silently blocks every merge, with no failing job to + point at. +- Keep `install-check` outside the gate because it installs by ref and a pull + request's merge ref does not exist on the remote as an installable ref. +- Every `uses:` reference is pinned to a full 40-hex commit SHA followed by a + trailing version comment. The `hygiene` job enforces both halves and fails + when it finds no references to check. +- Default to `permissions: contents: read`, use `persist-credentials: false`, + and grant `contents: write` only to the release publish job. +- Do not apply `paths` filters to jobs the gate requires. - Pin Bun and its matching `@types/bun` version exactly. Install with `--frozen-lockfile`. - Run checks through package scripts and print toolchain versions with results. - Do not add a Node job; Node is not a supported runtime. -`dist/index.js` and the feature entry `dist/augment.js` are committed. CI must -read the bundle list from `package.json`'s extension entries, build from -source, and compare each result byte-for-byte with its tracked bundle. +`dist/index.js` and the feature entry `dist/augment.js` are committed. CI reads +the bundle list from `package.json`'s extension entries, builds from source, and +compares each result byte-for-byte with its tracked bundle. -A release tag must match `package.json`'s version and both the version and source -ref in `.omp-plugin/marketplace.json`. Create releases only from verified tags. +A release tag must match `package.json`'s version and both the version and +source ref in `.omp-plugin/marketplace.json`. Create releases only from verified +tags. `CONTRIBUTING.md` holds the procedure. ## Testing and verification -Add deterministic tests for changed behavior. Cover the package boundaries -affected by the change: release selection and checksums, archive validation, -executable resolution, MCP-entry ownership, transport security, scheduler -behavior, and handler fail-open paths. +Add deterministic tests for changed behavior. Cover the package boundaries the +change touches: release selection and checksums, archive validation, executable +resolution, MCP-entry ownership, transport security, scheduler behavior, and +handler fail-open paths. + +Where a new test belongs: -`test/unit` must not require a CBM executable or network access. Use recorded -fixtures under `test/fixtures` and helpers in `test/support`. `test/packaging` -may build and load the bundle and touch the filesystem. Checks that require a -real executable or network access belong in a separate job. +- `test/unit` by default. It must not require a CBM executable or network + access. Use recorded fixtures under `test/fixtures` and helpers in + `test/support`. +- `test/packaging` when the test needs a build or a real load of the bundle. It + may touch the filesystem. +- A CI job of its own when the check needs a real executable or the network, as + `harvest` and `install-check` do. Neither suite may acquire either. Report the commands and revision used for verification. State which relevant checks were not run and why; never claim an unexecuted check passed. +## Prohibitions + +Each entry carries the mechanism that makes it a rule. A prohibition whose +reason reduces to "it breaks things" is removed by the next contributor who +finds it inconvenient. + +**Never replace an executable this package did not install.** Adopt an existing +`codebase-memory-mcp` from `PATH` or `~/.local/bin` as it is. Place a managed +copy only under this package's own root, `~/.omp/codebase-memory/bin//` +(`src/paths.ts`), which is outside both the plugin tree and the agent directory +— OMP replaces version-qualified plugin directories on reinstall, so an +executable stored inside one is discarded and re-downloaded by a routine plugin +upgrade. System installations win because CBM resolves one canonical per-account +cache root and refuses to run when a process is configured against a different +root while any CBM session is active: two executables of different versions +sharing that root produce mismatched index generations. `~/.local/bin` is CBM's +own installer's directory and CBM's `update` owns the file there. + +**Own exactly the `codebase-memory-mcp` key under `mcpServers` in the active +agent directory's `mcp.json`, and nothing else in that file.** Upsert it +idempotently, and remove it only while it still matches the package-owned entry. +OMP's own `/mcp add` writes the same file with no lock shared with this package, +so the write is a read-modify-write against observed content that fails closed on +a shape it does not recognise: a lost update degrades to a missing entry the next +session start rewrites, rather than a corrupted file. A `command` under that key +that this package did not write means another installer owns the name, so the +file is left untouched and both paths are reported. + +**Never create or modify an operator's OMP agent-directory `AGENTS.md` or +`RULES.md`.** Both are single-slot: the reader takes one file per slot, so +writing either does not add to the operator's instructions, it silently +suppresses them. In the agent directory `AGENTS.md` is the one surviving +user-level context file, and `RULES.md` occupies the single slot reserved for the +operator's sticky rules. This scopes to the operator's runtime directory. It is +explicitly not about this repository's own root `CLAUDE.md` and `AGENTS.md`, +which are project context discovered from a checkout and claim neither slot — a +reader who conflates the two will read the rule as contradicting the file it is +written in. + +**Never delete `.omp/`, at either location.** `.omp/` is an OMP directory that +belongs to the operator: `~/.omp/` holds their account configuration, and this +repository's own `/.omp/` holds their project-local `config.yml` and +skills root. Neither may be deleted, and neither becomes deletable because a +verification step is what materialized it. Cleaning up verification scratch +removes exactly the paths that step created, named one by one — never a +containing directory. The loss is silent by mechanism: a global ignore excludes +`/.omp/`, so the directory is untracked, `git status` never reports it missing, +and nothing fails until a later session reads what is no longer there. + +The incident behind that entry: verifying an install with `enabledFeatures: []` +needs a plugin root carrying that selection, and one was created under +`/.omp/plugins/`. Cleaning it up took the operator's `config.yml` and +project-local skills root with it, and the loss surfaced a session later as a +skill registry advertising roughly sixty skills while resolving five. The +placement that avoids it is a temporary directory — `mktemp -d`, which is what +CI already uses for a scratch `HOME` — never a path under `/.omp/` or +`~/.omp/`. + +**Never register a `tool_call` handler.** OMP treats a handler that throws or +blocks there as a refusal of the tool call, so one slow graph query would deny +the operator's `grep`. Augment successful output through `tool_result`, where a +failure is caught and the run continues; append rather than replace prior +content, and fail open. + +**Never call the platform timer globals.** Use the handler context's managed +timers through `src/scheduler.ts`. A raw `setTimeout` callback that throws +escapes handler dispatch entirely and surfaces as a process-level +`uncaughtException`, which OMP's postmortem handler treats as fatal and tears +down the whole session. The context's timers run the callback with handler +isolation, are `unref`'d, and are cleared on `session_shutdown`. + +**Never set an account-wide CBM configuration key for the operator.** That +configuration is per-account and shared with every other CBM client on the +machine, so a key written here changes behaviour for tools this package does not +own and cannot restore. + +**Never duplicate an action CBM's MCP tools already expose, indexing included.** +The model already holds `index_repository`, and a second path through this +package would take its own arguments and defaults — the two diverge, and the +operator cannot tell which one ran. + +**Never hand-edit a generated context artifact.** Regenerate with +`bun run harvest`. The source of these artifacts is embedded in the CBM +executable and changes with it, so a hand edit is a second, diverging statement +of the same contract until the next regeneration overwrites it. A unit test +re-runs every build guard against the committed files, and the `harvest` CI job +regenerates and diffs them. + +Contributing changes to `DeusData/codebase-memory-mcp` is out of scope; this +package consumes CBM release artifacts. This package owns only the executable it +downloaded and its MCP entry. CBM owns the graph, indexing, the watcher, the +cache root, and updates to a system installation. Windows and changes to any +other operator file are out of scope. + ## Documentation `README.md` is operator-facing and must be created or rewritten through the -`readme-creator` skill and its quality checklist. If that skill is unavailable, -stop rather than editing the README by hand. - -This file is the authority for repository guidance. `AGENTS.md` must remain a -tracked symbolic link to `CLAUDE.md`; do not create another copy of these rules. +`readme-creator` skill, following its phases and scored against its quality +checklist. If that skill cannot be resolved by name, stop; do not edit the README +by hand. `CONTRIBUTING.md` holds only procedures that need maintainer +credentials and links here for every rule. + +`AGENTS.md` must remain a tracked symbolic link to `CLAUDE.md`, with `CLAUDE.md` +as the regular file. Both names are needed and neither reader finds the other's +file: Claude Code reads the root `CLAUDE.md`, while OMP's `claude` provider +reads `.claude/CLAUDE.md` and discovers a root `AGENTS.md` through its +standalone provider. Two regular files would satisfy both readers and diverge on +the first one-sided edit. + +Do not add `.omp/AGENTS.md`. This repository's `.omp/` is non-empty, so a native +project context file there would win the depth-0 scope and shadow the root file +that both readers already find — replacing one text with a second that only OMP +sees, for no gain. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..74879fe --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,72 @@ +# Contributing + +This file holds only the procedures that cannot be performed without credentials +or permissions a contributor does not have: publishing a release, and changing +branch protection. + +[`CLAUDE.md`](CLAUDE.md) is the authority for everything else — branch naming, +Conventional Commits, the CI contract, the action-pinning rules, where a test +belongs, and the standing prohibitions. That file is the authority and this one +does not restate it, because two copies of a rule are two rules. + +No Developer Certificate of Origin or `Signed-off-by` trailer is required. This +document is scoped to credentialed procedures, and a sign-off clause would be +the one contributor-facing rule in a document that holds none. + +## Publishing a release + +A tag is a claim about four things: the tag itself, the package manifest +version, the catalog plugin version, and the catalog's source ref. An operator +installing from the marketplace resolves the last one, so a catalog that lags +the tag installs the previous release under the new version's name. + +1. **Make the version locations agree, on the default branch.** Three fields + must name one version before the tag exists: `version` in `package.json`, + `plugins[0].version` in `.omp-plugin/marketplace.json`, and + `plugins[0].source.ref` in the same file, which carries the `v` prefix and + must equal the tag. Land that through the usual pull request. + +2. **Push the tag from the merge commit that carries those versions.** + + ```bash + git tag v0.1.0 + git push origin v0.1.0 + ``` + + A `v*` tag cannot be moved or deleted once pushed, so a tag at the wrong + commit is not recoverable — publish the next patch version instead. + +3. **The version gate checks all four names.** `version-gate` in + `.github/workflows/release.yml` strips the tag's `v`, then compares it against + the manifest version, the catalog plugin version, and the catalog source ref. + Each mismatch is reported as its own annotation and the job fails; nothing is + published. + +4. **The same gate a pull request passes runs against the tag.** `release.yml` + calls `ci.yml` through `workflow_call` rather than copying its jobs, so the + tagged tree passes the identical checks. `install-check` also runs on a tag + push — it is skipped on pull requests, so this is where the documented + `omp plugin install github:pashifika/omp-codebase-memory#` command is + verified against the exact ref an operator can install. + +5. **The publish job creates the GitHub release.** It runs only after both the + version gate and the reused checks succeed. It is the one job that elevates to + `contents: write`, and it runs: + + ```bash + gh release create "$GITHUB_REF_NAME" --generate-notes --verify-tag + ``` + + `--verify-tag` refuses to create a release for a tag that does not exist on + the remote, so a release can only ever name a verified ref. + +A failed gate leaves the tag in place with no release attached. Fix the +mismatch, land it, and tag the next version; do not attempt to reuse the tag. + +## Changing branch protection + +Protection is defined by the ruleset files under `.github/rulesets/`, and +[`CLAUDE.md`](CLAUDE.md) states how a change to them is made. The credentialed +half is the last step: importing the edited file through the repository's rules +settings needs admin permission, and until that import runs the landed file and +the enforced rule disagree. diff --git a/README.md b/README.md index b5e0513..3841b13 100644 --- a/README.md +++ b/README.md @@ -1,248 +1,296 @@ # omp-codebase-memory -An [OMP](https://github.com/can1357/oh-my-pi) extension that owns the -[`codebase-memory-mcp`](https://github.com/DeusData/codebase-memory-mcp) (CBM) -executable's lifecycle and wires exactly one MCP server entry into OMP's native -user configuration. - -CBM indexes a repository into a persistent code knowledge graph and exposes it -over MCP. Its own installer configures 44 client surfaces, and OMP is not one of -them: OMP only sees CBM indirectly, by discovering a Claude, Codex, or Gemini -config that some *other* client's installation happened to leave behind. An -OMP-only machine gets nothing. - -This package is the missing path. `omp plugin install` is the whole setup step. - -It also does the part that being reachable does not cover: a fresh session is -told the graph exists, delegated work gets CBM's three read-only agent tiers, -and a `grep` that missed a structural answer gets it appended anyway. - -## What it does - -- **Resolves the executable, system installation first.** An existing - `codebase-memory-mcp` is adopted as-is and never replaced. A managed copy is - downloaded only when none is found. -- **Verifies a download the way upstream's installer does.** Release tag from - the `releases/latest` redirect, `checksums.txt` digest match for the exact - archive name, HTTPS on every redirect hop, a closed four-member archive - namespace, regular-file-not-symlink extraction, the Linux `-portable` build, - macOS quarantine removal and ad-hoc signing, and a `--version` smoke run - before anything is adopted. -- **Owns one key in `~/.omp/agent/mcp.json`.** `codebase-memory-mcp`, written - with the resolved absolute path, corrected when that path changes, removed on - uninstall. No other user file is touched. -- **Tracks versions without fighting CBM's own updater.** A managed copy is - updated by this package. An adopted system copy is only reported on. -- **Ships a skill, a rulebook rule, and three agents.** All five files are - derived from the CBM executable rather than written by hand, so the guidance a - session gets is the guidance that release actually documents. -- **Appends graph context to searches and reads.** Matching symbols on a `grep` - or `glob`, index-coverage gaps on a `read`. Optional, bounded, and it can only - ever add. +Installs and updates [`codebase-memory-mcp`](https://github.com/DeusData/codebase-memory-mcp) +for [OMP](https://github.com/can1357/oh-my-pi), and wires it into the MCP +configuration your sessions already read. + +`codebase-memory-mcp` (CBM) indexes a repository into a persistent code +knowledge graph and serves it over MCP. Its own installer configures dozens of +editor and CLI clients, and OMP is not one of them. On an OMP-only machine, CBM +is reachable only if some *other* client's installation happened to leave a +Claude, Codex, or Gemini config behind for OMP to discover. This extension +supplies that route: one `omp plugin install`, and the graph is reachable, kept +in step, and described to the session that uses it. + +## Features + +- **System-first resolution:** adopts an existing `codebase-memory-mcp` as it is + and never replaces it. Downloads a managed copy only when nothing resolves. +- **Verified downloads:** the release tag comes from the `releases/latest` + redirect, the archive must match its digest in the release's own + `checksums.txt`, every redirect hop must be HTTPS, the archive's member list + must be exactly the four expected regular files, and the candidate runs + `--version` before anything adopts it. +- **One MCP key, kept correct:** `codebase-memory-mcp` is written into the + active agent directory's `mcp.json` with the resolved absolute path, rewritten + when that path changes, and removed on uninstall. No other file of yours is + touched. +- **Versions you control:** update a managed copy from here, pin one to hold it, + and get a report rather than a surprise when an adopted system copy falls + behind. +- **Context your session can use:** a skill, a rulebook rule, and three + read-only agents, all generated from the executable rather than written by + hand, plus optional graph symbols appended to `grep`, `glob`, and `read` + results. + +## Contents + +- [Install](#install) +- [Commands](#commands) +- [Configuration](#configuration) +- [Why a system installation always wins](#why-a-system-installation-always-wins) +- [Graph context in a session](#graph-context-in-a-session) +- [Where things live](#where-things-live) +- [What this package will not touch](#what-this-package-will-not-touch) +- [Staying in step with CBM](#staying-in-step-with-cbm) +- [Known limits](#known-limits) +- [Requirements](#requirements) +- [Development](#development) +- [License](#license) ## Install -### Git spec (primary) +Install from the git spec. This is the supported primary route and delivers +every shipped surface: -```sh +```bash omp plugin install github:pashifika/omp-codebase-memory ``` -CI runs this command, through OMP's own installer, on pushes to `main`, on -release tag pushes, and on manual dispatch — as -`github:pashifika/omp-codebase-memory#`, into a home directory with no -prior plugin state. `omp plugin install` validates what it installed by loading -the declared extension entry, so a ref that installs green also registers green. +Nothing else is needed. The extension resolves an executable, wires the MCP +entry at the next session start, and tells you what it did. + +To install without the optional result augmentation, name an empty feature +selection: + +```bash +omp plugin install 'github:pashifika/omp-codebase-memory[]' +``` ### Marketplace -```sh -omp plugin marketplace add github:pashifika/omp-codebase-memory -omp plugin install omp-codebase-memory@omp-codebase-memory +The catalog at `.omp-plugin/marketplace.json` makes this repository its own +marketplace, which also enables `omp plugin discover` and `omp plugin upgrade`: + +```bash +omp plugin marketplace add pashifika/omp-codebase-memory +omp plugin discover ``` -The catalog lives at `.omp-plugin/marketplace.json`. Marketplace installs are -discovered through a different provider than git installs, so this is an -additional entry point rather than a replacement. +Two things differ on this route: -That provider contributes skills and agents, and it is not a rules provider, so -a marketplace install does not receive the rule. Since the rule is a rulebook -entry rather than an always-apply injection, what it costs a session either way -is one listed name and description, and the skill carries the same guidance in -full. The skill, the three agents, the MCP entry, and the augmentation all work -on both routes. +1. **Installing needs a published release.** The catalog names the tag to + install, so `omp plugin install omp-codebase-memory@omp-codebase-memory` + fails with `Remote branch not found` until that release exists. No + release is published yet; use the git spec. +2. **It does not deliver the rulebook rule.** Marketplace plugins are discovered + through a provider that contributes skills and agents but is not a rules + provider. A rulebook rule is one OMP reads on demand and lists by name rather + than injecting into every turn, so what it costs a session either way is one + listed name and description — and the skill carries the same guidance in + full. The skill, the three agents, the MCP entry, and the augmentation work on + both routes. -### Development +### From a checkout -```sh +```bash git clone https://github.com/pashifika/omp-codebase-memory cd omp-codebase-memory bun install omp plugin link . ``` -`omp.extensions` names `./dist/index.js` and the augmentation feature names -`./dist/augment.js`. Both are committed, so a fresh clone loads without a build -step. Run `bun run build` after changing anything under `src/`; CI fails if -either committed bundle is not byte-identical to one built from the current -source. +Both bundles — `dist/index.js` and the feature's `dist/augment.js` — are +committed, so a fresh clone loads with no build step. + +### Uninstall + +Run `/cbm uninstall` in a session first. It removes the managed copy, this +package's state, and the owned MCP entry. Then remove the plugin: + +```bash +omp plugin uninstall omp-codebase-memory +``` -CI links its own checkout with this command, so the development install is -verified to be discovered. That the committed bundle then *loads* through OMP's -loader is `test/packaging/bundle.test.ts` — `omp plugin link` registers a -checkout without loading it. +Neither touches an adopted system executable, CBM's cache, or any other client's +configuration. ## Commands +Everything is one command with subcommands. `/cbm` on its own reports status. + | Command | What it does | |---|---| -| `/cbm status` | Resolved source, absolute path, local version, last known upstream version, pin state, resolved agent directory, whether the MCP entry is present and current, and which indexed project covers this directory | +| `/cbm status` | Reports the resolved executable and where it came from, its version, any managed copy on disk, the last known upstream version, the pin, the resolved agent directory, whether the owned MCP entry is present and current, and which indexed project covers this directory | | `/cbm install [version]` | Downloads, verifies, and adopts a managed copy. Asks for confirmation first when a system executable already resolves | | `/cbm update` | Updates a managed copy. For an adopted system copy, reports the newer version and points at CBM's own `update` | | `/cbm pin ` | Holds a version: update checks report but never adopt | | `/cbm unpin` | Releases the pin | | `/cbm uninstall` | Removes the managed copy, this package's state, and the owned MCP entry. Leaves an adopted system executable alone | -No command needs an interactive terminal. In a session with no UI, `/cbm -install` fails with the reason rather than waiting for a confirmation that -cannot arrive. +A status report reads as one labelled line per fact, so a stale MCP entry or an +unindexed directory is visible without running anything else. -There is no index command. CBM's own guidance, which this package ships, tells -the model to confirm the project with `list_projects` or `index_status` at -session start, and `index_repository` is already in the model's tool surface. Ask -the agent to index a repository; a second path through `/cbm` would duplicate -one that already works. - -## Graph context - -Three surfaces across five committed files, all derived from the CBM executable -by `bun run harvest`: - -| Surface | Path | What it gives a session | -|---|---|---| -| Skill | `skills/codebase-memory/SKILL.md` | The tool matrix, the exploration and tracing workflows, the Cypher examples, and the gotchas. Read on demand as `skill://codebase-memory` | -| Rule | `rules/codebase-memory.md` | The priority order and the evidence tiers. Listed in the rulebook by name and description, and read on demand as `rule://codebase-memory` | -| Agents | `agents/codebase-memory{,-scout,-auditor}.md` | CBM's Scout, Verify, and Auditor tiers, as read-only subagents that verify supplied evidence against exact source | +No command needs an interactive terminal. In a session with no UI, `/cbm +install` reports the reason and stops rather than waiting for a confirmation +that cannot arrive. -The agents declare `tools: read, grep, glob` and name no MCP tool. Their prompt -bodies tell the child that the parent must supply the graph evidence and that -the child must not claim MCP access, which is the situation an OMP subagent is -in. Every name carries the `codebase-memory-` prefix, so none of them can -shadow one of OMP's own bundled agents. +### Indexing is the agent's work -### The augmentation feature +There is no index command here, and that is deliberate. `index_repository` is +already in your model's tool surface, and CBM's own guidance — which this +package ships as the skill and the rule — tells the model to confirm the project +with `list_projects` or `index_status` at session start. So ask the agent to +index the repository. A second path through `/cbm` would duplicate one that +already works, with its own arguments and defaults to drift apart. -`graph-augmentation` is a manifest feature, enabled by default. When it is -active, a `grep` or `glob` result gains the graph symbols whose names hold one of -the identifiers the search used, and a `read` gains the index's coverage findings -for that file — but only when coverage reports a gap, so a fully indexed file -reads exactly as it did before. +## Configuration -Each appended symbol carries its qualified name, label, file, line range, and the -graph's degree, written `11 in / 14 out`. The degree is the part worth the -tokens: a file and line range for a symbol your search already matched is mostly -a restatement, and `lsp` gives it more precisely where a language server exists, -but how many edges reach a symbol is not something `grep`, `glob`, or -`lsp references` can tell you. It is CBM's selected degree over CALLS, USAGE, -CALL_REFERENCE, INHERITS, and IMPLEMENTS — not a caller count. Use `trace_path` -for callers; it is also the only tool here that answers transitively. +This package has one setting, the optional augmentation feature, and it is on by +default: -Install without it, or turn it off later: - -```sh -omp plugin install 'github:pashifika/omp-codebase-memory[]' +```bash omp plugin features omp-codebase-memory --disable graph-augmentation omp plugin features omp-codebase-memory --enable graph-augmentation ``` -The feature owns one extension entry and nothing else. Turning it off leaves the -skill, the rule, the agents, and the MCP entry exactly as they were. +The MCP entry is written to the active OMP agent directory, resolved the way OMP +resolves it: -Four properties hold whether or not it is on: +| Setting | Effect | +|---|---| +| `PI_CODING_AGENT_DIR` | Used directly when set. Inside a session this is already OMP's own answer | +| `OMP_PROFILE`, `PI_PROFILE` | Select `~/.omp/profiles//agent`. `OMP_PROFILE` wins; `PI_PROFILE` is read only when it is unset | +| Neither | `~/.omp/agent` | +| `PI_CONFIG_DIR` | Replaces the `.omp` directory name every path above hangs off | -1. It only ever appends. Every chunk the tool produced reaches the model - unchanged, including content another extension added first. -2. It never runs on `tool_call`. OMP treats a throwing or blocking handler there - as a refusal of the tool call, so a slow graph query could deny your `grep`. - The handler is on `tool_result`, where a failure is caught and the run - continues. -3. Every query has a deadline in the low hundreds of milliseconds and a bound on - how much it may append. A query that misses the deadline appends nothing. -4. An errored tool result is left alone. +A profile-scoped setup therefore gets the entry in the active profile only — +writing every profile would configure profiles you never asked about — and +`/cbm status` names the directory it resolved, so the scope is visible. + +CBM's own behaviour is CBM's configuration, not this package's. Three of its +defaults decide what you see on a new machine, measured from +`codebase-memory-mcp config list` at 0.10.8: -It holds one CBM process for the session, opened in the background at session -start and closed at shutdown, at about 2.6 MB resident. +| Key | Default | What it means | +|---|---|---| +| `auto_index` | `false` | A project is not indexed just because a session connected. The first index is something you or the agent asks for | +| `auto_index_limit` | `50000` | The file ceiling for an automatic index of a new project, when `auto_index` is on | +| `auto_watch` | `true` | Once a project is indexed, a background git watcher is registered on connect, so ongoing freshness needs no action | -That opening is not instant, and it is why the first seconds of a session are -different. A CBM process needs roughly 2.9 s to answer its first request when a -CBM daemon is already warm, and about 8.5 s when it has to start the daemon -itself. A search will not wait for that — the deadline above is the whole point — -so a search issued before the session is ready appends nothing and is otherwise -untouched. In practice you type a prompt first and the session is long ready; in -a scripted `omp -p` run the first one or two searches often are not. Nothing is -lost either way, and `~/.omp/logs` records one line per session saying when the -session became ready and which project it resolved. +The practical shape: the first index is explicit, and staying current after that +is not. Change these through CBM's own `config set`; this package never writes a +CBM configuration key for you. -## The system-first policy, and why it is not negotiable +## Why a system installation always wins Resolution order is **pin, `PATH`, `~/.local/bin`, managed copy** — system -before managed. +before managed, and the reason is the index rather than tidiness. -CBM resolves one canonical per-account cache root, and refuses to run when a -process is configured with a different root while any CBM session or command is -active. Two executables of *different versions* sharing that root produce -mismatched index generations. Giving a managed copy its own private cache root -would avoid the conflict by re-indexing every repository a second time, which -for a large tree is hours of work and gigabytes to hold the same answers twice. +CBM resolves one canonical cache root per account, and refuses to run when a +process is configured against a different root while any CBM session or command +is active. Two executables of different versions sharing that root produce +mismatched index generations. Giving a managed copy a private cache root would +trade the conflict for re-indexing every repository a second time — hours of +work on a large tree, and gigabytes to hold the same answers twice. -So the operator's existing installation wins. The cost is that this package -cannot guarantee a version, and that cost is made visible rather than hidden: -`/cbm status` names the source, and an out-of-date system copy produces a -pointer to CBM's own `update` rather than an attempt to perform it. +So your existing installation wins. The cost is that this package cannot +guarantee a version, and that cost is visible rather than hidden: `/cbm status` +names the source, and an out-of-date system copy produces a pointer to CBM's own +`update` instead of an attempt to perform it. `/cbm install` while a system copy resolves is still possible — it is your -machine — but it explains the shared-cache-root consequence and requires +machine — but it explains the shared-cache-root consequence and requires an explicit confirmation first. +## Graph context in a session + +Five committed files, all generated from the CBM executable by +`bun run harvest`: + +| Surface | Path | What a session gets | +|---|---|---| +| Skill | `skills/codebase-memory/SKILL.md` | The tool matrix, the exploration and tracing workflows, the Cypher examples, and the gotchas. Read on demand as `skill://codebase-memory` | +| Rule | `rules/codebase-memory.md` | The priority order and the evidence tiers. Listed in the rulebook by name, read on demand as `rule://codebase-memory` | +| Agents | `agents/codebase-memory{,-scout,-auditor}.md` | CBM's Scout, Verify, and Auditor tiers as read-only subagents | + +The agents declare `tools: read, grep, glob` and name no MCP tool, because an +OMP subagent does not inherit one. Their prompts tell the child that the parent +supplies the graph evidence and that the child must verify it against exact +source. Every name carries the `codebase-memory-` prefix, so none of them can +shadow one of OMP's own agents. + +### The augmentation feature + +With `graph-augmentation` enabled, a `grep` or `glob` result gains the graph +symbols whose names hold one of the identifiers the search used, and a `read` +gains the index's coverage findings for that file — but only when coverage +reports a gap, so a fully indexed file reads exactly as it did before. + +Each appended symbol carries its qualified name, label, file, line range, and +the graph's degree, written `11 in / 14 out`. The degree is the part worth the +tokens: how many edges reach a symbol is not something `grep`, `glob`, or +`lsp references` can tell you. It is CBM's selected degree over `CALLS`, +`USAGE`, `CALL_REFERENCE`, `INHERITS`, and `IMPLEMENTS`, not a caller count — +use `trace_path` for callers, which is also the only tool here that answers +transitively. + +Four guarantees hold whenever the feature is active: + +1. It only ever appends. Every chunk the tool produced reaches the model + unchanged, including content another extension added first. +2. It never runs on `tool_call`. OMP treats a handler that throws or blocks + there as a refusal of the tool call, so a slow query could deny your `grep`. + This one runs on `tool_result`, where a failure is caught and the run + continues. +3. Every query has a deadline in the low hundreds of milliseconds and a bound on + how much it may append. A query that misses the deadline appends nothing. +4. An errored tool result is left alone. + +It holds one CBM process for the session at about 2.6 MB resident, opened in the +background at session start. Opening it is not instant — roughly 3 seconds +against a warm CBM daemon, about 9 when it has to start the daemon — and a +search never waits for it. Searches issued before the session is ready append +nothing and are otherwise untouched. `~/.omp/logs` records one line per session +saying whether the session became ready and which project it resolved. + ## Where things live | Path | Owner | Notes | |---|---|---| | `~/.omp/codebase-memory/bin//` | this package | Managed executables, one directory per version | | `~/.omp/codebase-memory/state.json` | this package | Version pointer, digest, pin, last check time | -| `/mcp.json` | the operator | This package owns the single `codebase-memory-mcp` key and nothing else | +| `/mcp.json` | you | This package owns the single `codebase-memory-mcp` key and nothing else in the file | | `~/.local/bin/codebase-memory-mcp` | CBM's installer | Read during resolution, **never** written | -| `/skills`, `rules`, `agents` | this package | The harvested context surfaces, discovered by OMP's own plugin scan. Removed with the plugin | +| `/skills`, `rules`, `agents` | this package | The generated context surfaces, found by OMP's plugin scan and removed with the plugin | | CBM's cache root and its graph | CBM | Shared with every other client on the account. Nothing here indexes, deletes, or overrides it | -`` is resolved the way OMP resolves it: `PI_CODING_AGENT_DIR` when -set, otherwise `~/.omp/profiles//agent` under `OMP_PROFILE`/`PI_PROFILE`, -otherwise `~/.omp/agent`. A profile-scoped operator therefore gets the entry -only in the active profile — writing every profile would configure profiles you -never asked about — and `/cbm status` names the directory it resolved so the -scope is visible. - The managed copy lives outside the plugin tree on purpose. OMP caches plugins in version-qualified directories and replaces them on reinstall, so an executable -stored inside would be discarded by a routine plugin upgrade and re-downloaded -every time. - -## Rollback - -Two steps, in either order: - -```sh -/cbm uninstall # managed copy, state, and the owned MCP entry -omp plugin uninstall omp-codebase-memory -``` - -Neither touches an adopted system executable, CBM's cache, or any other client's -configuration. +stored inside one would be discarded by a routine plugin upgrade and downloaded +again every time. + +## What this package will not touch + +- **Any executable it did not install.** An installation found on `PATH` or in + `~/.local/bin` is adopted as it is; `~/.local/bin` belongs to CBM's own + installer and CBM's `update` owns the file there. +- **Anything in `mcp.json` but its own key.** If that key already names a + `command` this package did not write, the file is left alone and both paths + are reported. +- **Your OMP instruction files.** It never creates or edits `AGENTS.md` or + `RULES.md` in your agent directory. Each is a single slot, so writing one + would not add to your instructions, it would replace them. +- **CBM's configuration.** No account-wide CBM key is ever set for you. +- **CBM's graph, index, watcher, and cache root.** All CBM's, shared with every + other client on the account. +- **Your tool calls.** The augmentation registers no `tool_call` handler, so it + can never refuse or delay a call — only add to a result. ## Staying in step with CBM -The shipped skill, rule, and agents belong to a specific CBM release. -`harvest.json` records which one, in these three fields: +The shipped skill, rule, and agents belong to one CBM release. `harvest.json` +records which, and lists every path the pipeline owns: ```json { @@ -252,62 +300,55 @@ The shipped skill, rule, and agents belong to a specific CBM release. } ``` -A fourth field, `generated`, lists every path the pipeline owns, so the file -also states what a regeneration is allowed to overwrite. - If you run a newer CBM than that, two detectors tell you, in this order. -**Primary: your own session.** About twenty seconds after a session starts, the +**Your own session, first.** About twenty seconds after a session starts, the package asks your resolved executable for its MCP tool list and compares it against the tool names the shipped skill enumerates. A renamed or removed tool -produces one notice naming the tool and your executable's version, and nothing -else — no per-call output, and no second notice. This detector runs on your -machine against the binary you actually have, so it is unaffected by anything -that happens or fails to happen in this repository. +produces one notice naming the tool and your executable's version — once, not +per call. This runs on your machine against the binary you actually have, so +nothing that happens or fails to happen in this repository affects it. -**Secondary: the `harvest` CI job.** It acquires the newest CBM release, +**The scheduled CI job, second.** It acquires the newest CBM release, regenerates every artifact, and fails when a committed copy differs. It runs on -pushes, on pull requests, and weekly on a schedule — the schedule because a new -upstream release produces no activity here, so a push-only gate would stay green -while the shipped content went stale. +pushes, on pull requests, and weekly. -That schedule has a blind spot nobody can close from inside the repository: +The schedule has a blind spot that cannot be closed from inside the repository: GitHub disables scheduled workflows after prolonged repository inactivity, and does so silently. A dormant-but-installed package is exactly that state. So the -per-session check is the authoritative one, and the scheduled job is a net +per-session check is the authoritative one and the scheduled job is a net underneath it. Either way the remedy is the same: update the plugin. The notice reports; it -does not regenerate anything on your machine. - -## Requirements - -- **Bun**, which is OMP's runtime. No npm runtime dependencies. -- **`tar`** for archive extraction. -- **`xattr` and `codesign`** on macOS. Both ship with a default install; their - absence is reported as a named prerequisite rather than a mysterious failure. -- macOS and Linux. Windows is deferred, not refused: it needs zip extraction, a - different executable suffix, and its own path handling, and is currently one - explicit unsupported-platform error rather than a half-implemented branch. +regenerates nothing on your machine. ## Known limits - **MCP does not pick up a changed `command` without a reload.** A managed - update changes the resolved path mid-session; the entry is corrected + update changes the resolved path mid-session. The entry is corrected immediately and you are told the session needs `/mcp reload`. -- **A foreign entry of the same name is left alone.** If `mcp.json` already - defines `codebase-memory-mcp` with a `command` this package did not write, the - file is not modified and both paths are reported. CBM's own installer, another - tool, or a hand edit may already own that name. -- **`~/.omp/agent/mcp.json` has two possible writers.** OMP's own `/mcp add` and - this package have no shared lock. The write is a read-modify-write against the - observed content and fails closed on a shape it does not recognise, so a lost - update degrades to "the entry is missing and the next session start rewrites - it" rather than a corrupted file. +- **A foreign entry of the same name is left alone.** CBM's own installer, + another tool, or a hand edit may already own the `codebase-memory-mcp` key. +- **`mcp.json` has two possible writers.** OMP's `/mcp add` and this package + share no lock. The write is a read-modify-write against observed content and + fails closed on a shape it does not recognise, so a lost update degrades to a + missing entry that the next session start rewrites, never a corrupted file. +- **Windows is unsupported.** It needs zip extraction, a different executable + suffix, and its own path handling. It is one explicit + unsupported-platform error rather than a half-implemented branch. + +## Requirements + +- **Bun.** OMP's own runtime, so you already have it. CI pins 1.3.14, tracked by + `@types/bun` in `package.json`. No npm runtime dependencies. +- **`tar`**, for archive extraction. +- **`xattr` and `codesign`** on macOS, both from a default install. A missing + one is reported as a named prerequisite rather than a mysterious failure. +- **macOS or Linux.** ## Development -```sh +```bash bun install # --frozen-lockfile in CI bun run typecheck bun run test:unit # no CBM executable, no network @@ -315,34 +356,40 @@ bun run test:packaging # rebuilds both bundles, then loads them bun run build # commit the result ``` +Run `bun run build` after changing anything under `src/`. CI rejects a committed +bundle that is not byte-identical to one built from the current source. + Tests are written as case tables: one row per case, named by a `scenario` field, so a failure names the case without anyone reading the table. -### Regenerating the context surfaces +Regenerate the context surfaces when the CI `harvest` job reports a difference, +or when you deliberately move to a newer CBM: -```sh +```bash bun run harvest ``` -Run it when the CI `harvest` job reports a difference, or when you deliberately -move to a newer CBM. Never edit `skills/`, `rules/`, `agents/`, or `harvest.json` -by hand: a unit test re-runs every build guard against the committed files, and -CI regenerates and diffs them. +`skills/`, `rules/`, `agents/`, and `harvest.json` are generated; see +[`CLAUDE.md`](CLAUDE.md) for why they are never edited by hand. The harvest refuses while a CBM daemon is running, because `install` is CBM's activation path and drains active CBM sessions before it configures anything — regenerating documentation should not close your editor's MCP connection. Close those sessions, or accept the consequence explicitly: -```sh +```bash bun run harvest --stop-sessions ``` -It needs a CBM executable and therefore a network. The unit suite does not: every -transformation is tested against recorded output under +That command needs a CBM executable and therefore a network. The unit suite does +not: every transformation is tested against recorded output under `test/fixtures/harvest/`, so a contributor with no CBM installed can still run and extend the whole suite. -## Licence +[`CLAUDE.md`](CLAUDE.md) holds the repository's conventions and standing rules. +[`CONTRIBUTING.md`](CONTRIBUTING.md) holds the procedures that need maintainer +credentials. + +## License -MIT. See [LICENSE](./LICENSE). +MIT. See [LICENSE](LICENSE). From dc9f51febb935e3c0290d461079f9ba11074a0f1 Mon Sep 17 00:00:00 2001 From: pashifika Date: Sat, 29 Aug 2026 01:28:34 +0900 Subject: [PATCH 2/5] docs: correct LICENSE to the MIT text the manifests declare `LICENSE` held the unmodified Apache License 2.0 template while `package.json`, `.omp-plugin/marketplace.json`, and `README.md` all declared MIT. Two contradictory statements of the distribution terms is a defect, not a style question. MIT is the side that gets kept. Three metadata fields already said so, both sibling repositories in this account carry the identical 1066-byte MIT text, and the Apache file's own appendix still read `Copyright [yyyy] [name of copyright owner]` -- it was never customized, which is what a boilerplate drop looks like rather than a decision. No release has been tagged, so nothing was ever distributed under the conflicting pair. The file is now byte-identical to `omp-toolgate`'s. --- LICENSE | 222 ++++++-------------------------------------------------- 1 file changed, 21 insertions(+), 201 deletions(-) diff --git a/LICENSE b/LICENSE index 261eeb9..9a61e51 100644 --- a/LICENSE +++ b/LICENSE @@ -1,201 +1,21 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. +MIT License + +Copyright (c) 2026 pashifika + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From 851e3a859368f21e65a61c91f30832d49d69e527 Mon Sep 17 00:00:00 2001 From: pashifika Date: Sat, 29 Aug 2026 02:10:32 +0900 Subject: [PATCH 3/5] docs: correct the marketplace claim and de-duplicate the mechanisms Review pass 1 measured what the README asserted and one claim did not survive. `README.md` said a marketplace install does not deliver the rulebook rule, on the reasoning that the marketplace provider contributes skills and agents but is not a rules provider. Both halves are false against the OMP version `package.json` pins: `discovery/claude-plugins.ts:637-643` registers a `Rule` provider whose `loadRules` reads `/rules` for every allowed root, and the agents come from `task/discovery.ts` instead. A marketplace install is recorded in `~/.omp/plugins/installed_plugins.json`, and `listClaudePluginRoots` turns each entry there into exactly such a root -- reproduced against a scratch `HOME`. One route difference is real: the catalog resolves a ref, so the route cannot install until a release exists. The same section also carried three mechanisms already stated in `CLAUDE.md` -- the `tool_call` dispatch semantics, CBM's cache-root refusal, and the `mcp.json` read-modify-write degradation -- in a third wording each. The README now keeps what an operator observes and `CLAUDE.md` keeps the prohibition with its mechanism, which is what the authority split claims. Smaller corrections: the CBM defaults are attributed to `config --help`, which prints defaults, rather than `config list`, which prints this operator's effective values; the `harvest.json` block carries the `generated` array the sentence promises; `PI_CONFIG_DIR` no longer claims to affect a path `PI_CODING_AGENT_DIR` supplied whole; the version gate's `v`-stripping is described as it is written; the account-wide CBM key prohibition names the tool and the six keys rather than gesturing at consequences. --- CLAUDE.md | 26 ++++++++++++------ CONTRIBUTING.md | 16 ++++++----- README.md | 71 +++++++++++++++++++++++-------------------------- 3 files changed, 61 insertions(+), 52 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 923d06b..9b52157 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -38,16 +38,22 @@ landed this way: `feat/graph-context-and-agents`, `docs/repository-guidelines`, `chore/commit-ruleset-payloads`. The default branch and release tags are protected by the rulesets committed -under `.github/rulesets/`. Those files are the authority for every parameter; -read them rather than trusting a value repeated in prose. Their shape: +under `.github/rulesets/`. This section states two things and no more. First, +the shape of that protection: the facts whose change would change how work lands +here. Second, the two literals another file in this repository must match — the +required check name `ci`, which is the gate job's own name in `ci.yml`, and the +tag pattern `v*`, which a pushed tag and the catalog's `source.ref` must +satisfy. Everything else those files configure is theirs to state: approval +counts, the review and bypass booleans, the actor lists, and every other +parameter. Read a value there rather than trusting one repeated in prose. The +shape: - The default branch rejects deletion and non-fast-forward pushes. - Landing a change requires a pull request whose review threads are resolved. - The merge commit is the only permitted merge method. - Exactly one status check, named `ci`, is required, under a strict policy — so a branch must be current with the default branch before it can merge. -- Release tags matching the ruleset's pattern reject deletion and - non-fast-forward pushes. +- Release tags matching `v*` reject deletion and non-fast-forward pushes. Change protection by editing those files and reimporting them, never through the web interface. A rule changed in the browser is invisible to review and is @@ -188,10 +194,14 @@ escapes handler dispatch entirely and surfaces as a process-level down the whole session. The context's timers run the callback with handler isolation, are `unref`'d, and are cleared on `session_shutdown`. -**Never set an account-wide CBM configuration key for the operator.** That -configuration is per-account and shared with every other CBM client on the -machine, so a key written here changes behaviour for tools this package does not -own and cannot restore. +**Never set an account-wide CBM configuration key for the operator.** CBM 0.10.8 +exposes six keys through `codebase-memory-mcp config set` — `auto_index`, +`auto_index_limit`, `auto_watch`, `ui-lang`, `ui_enabled`, `ui_port` — and every +one is account-wide; none is scoped to a project or to a client. That store is +shared with every CBM client on the machine, so a key written here silently +changes what another editor's CBM session does. A read-before-write does not +make it reversible: nothing records that this package wrote the key, and another +client may set the same key meanwhile, so the value to put back is not knowable. **Never duplicate an action CBM's MCP tools already expose, indexing included.** The model already holds `index_repository`, and a second path through this diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 74879fe..7557580 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -33,21 +33,23 @@ the tag installs the previous release under the new version's name. git push origin v0.1.0 ``` - A `v*` tag cannot be moved or deleted once pushed, so a tag at the wrong - commit is not recoverable — publish the next patch version instead. + A tag at the wrong commit is not recoverable under the tag ruleset — publish + the next patch version instead. 3. **The version gate checks all four names.** `version-gate` in - `.github/workflows/release.yml` strips the tag's `v`, then compares it against - the manifest version, the catalog plugin version, and the catalog source ref. + `.github/workflows/release.yml` strips the tag's `v` and compares the result + against the manifest version and the catalog plugin version, then compares + the tag itself, `v` prefix included, against the catalog source ref. Each mismatch is reported as its own annotation and the job fails; nothing is published. 4. **The same gate a pull request passes runs against the tag.** `release.yml` calls `ci.yml` through `workflow_call` rather than copying its jobs, so the tagged tree passes the identical checks. `install-check` also runs on a tag - push — it is skipped on pull requests, so this is where the documented - `omp plugin install github:pashifika/omp-codebase-memory#` command is - verified against the exact ref an operator can install. + push — it is skipped on pull requests. So this is where the documented + install command is verified against the exact ref an operator can install: + the job builds the ref-qualified form of it, + `github:pashifika/omp-codebase-memory#`, from the pushed tag. 5. **The publish job creates the GitHub release.** It runs only after both the version gate and the reused checks succeed. It is the one job that elevates to diff --git a/README.md b/README.md index 3841b13..6ebb114 100644 --- a/README.md +++ b/README.md @@ -50,8 +50,7 @@ in step, and described to the session that uses it. ## Install -Install from the git spec. This is the supported primary route and delivers -every shipped surface: +Install from the git spec. This is the supported primary route: ```bash omp plugin install github:pashifika/omp-codebase-memory @@ -77,19 +76,12 @@ omp plugin marketplace add pashifika/omp-codebase-memory omp plugin discover ``` -Two things differ on this route: - -1. **Installing needs a published release.** The catalog names the tag to - install, so `omp plugin install omp-codebase-memory@omp-codebase-memory` - fails with `Remote branch not found` until that release exists. No - release is published yet; use the git spec. -2. **It does not deliver the rulebook rule.** Marketplace plugins are discovered - through a provider that contributes skills and agents but is not a rules - provider. A rulebook rule is one OMP reads on demand and lists by name rather - than injecting into every turn, so what it costs a session either way is one - listed name and description — and the skill carries the same guidance in - full. The skill, the three agents, the MCP entry, and the augmentation work on - both routes. +One thing differs on this route. Installing resolves the tag the catalog names, +so `omp plugin install omp-codebase-memory@omp-codebase-memory` fails with +`Remote branch not found` until that release is published. None is +published yet, so install from the git spec for now. Once a release exists, +every shipped surface loads here exactly as it does on the git spec: the skill, +the rulebook rule, the three agents, the MCP entry, and the augmentation. ### From a checkout @@ -162,15 +154,16 @@ resolves it: | `PI_CODING_AGENT_DIR` | Used directly when set. Inside a session this is already OMP's own answer | | `OMP_PROFILE`, `PI_PROFILE` | Select `~/.omp/profiles//agent`. `OMP_PROFILE` wins; `PI_PROFILE` is read only when it is unset | | Neither | `~/.omp/agent` | -| `PI_CONFIG_DIR` | Replaces the `.omp` directory name every path above hangs off | +| `PI_CONFIG_DIR` | Replaces the `.omp` directory name in the two rows above. A directory named by `PI_CODING_AGENT_DIR` is used as given and is unaffected | A profile-scoped setup therefore gets the entry in the active profile only — writing every profile would configure profiles you never asked about — and `/cbm status` names the directory it resolved, so the scope is visible. CBM's own behaviour is CBM's configuration, not this package's. Three of its -defaults decide what you see on a new machine, measured from -`codebase-memory-mcp config list` at 0.10.8: +defaults decide what you see on a new machine, as +`codebase-memory-mcp config --help` prints them at 0.10.8 — that command reports +the default beside each key, where `config list` reports your effective values: | Key | Default | What it means | |---|---|---| @@ -187,11 +180,9 @@ CBM configuration key for you. Resolution order is **pin, `PATH`, `~/.local/bin`, managed copy** — system before managed, and the reason is the index rather than tidiness. -CBM resolves one canonical cache root per account, and refuses to run when a -process is configured against a different root while any CBM session or command -is active. Two executables of different versions sharing that root produce -mismatched index generations. Giving a managed copy a private cache root would -trade the conflict for re-indexing every repository a second time — hours of +CBM keeps one cache root per account, holding one graph, and two executables of +different versions do not share it safely. Giving a managed copy a root of its +own would trade that for re-indexing every repository a second time — hours of work on a large tree, and gigabytes to hold the same answers twice. So your existing installation wins. The cost is that this package cannot @@ -217,8 +208,8 @@ Five committed files, all generated from the CBM executable by The agents declare `tools: read, grep, glob` and name no MCP tool, because an OMP subagent does not inherit one. Their prompts tell the child that the parent supplies the graph evidence and that the child must verify it against exact -source. Every name carries the `codebase-memory-` prefix, so none of them can -shadow one of OMP's own agents. +source. Every name begins `codebase-memory`, so none of them can shadow one of +OMP's own agents. ### The augmentation feature @@ -239,10 +230,9 @@ Four guarantees hold whenever the feature is active: 1. It only ever appends. Every chunk the tool produced reaches the model unchanged, including content another extension added first. -2. It never runs on `tool_call`. OMP treats a handler that throws or blocks - there as a refusal of the tool call, so a slow query could deny your `grep`. - This one runs on `tool_result`, where a failure is caught and the run - continues. +2. It never runs on `tool_call`, so it can never refuse or delay a call. It runs + on `tool_result` instead, and a failure of its own is caught there rather + than reaching your run. 3. Every query has a deadline in the low hundreds of milliseconds and a bound on how much it may append. A query that misses the deadline appends nothing. 4. An errored tool result is left alone. @@ -284,8 +274,8 @@ again every time. - **CBM's configuration.** No account-wide CBM key is ever set for you. - **CBM's graph, index, watcher, and cache root.** All CBM's, shared with every other client on the account. -- **Your tool calls.** The augmentation registers no `tool_call` handler, so it - can never refuse or delay a call — only add to a result. +- **Your tool calls.** The augmentation registers no `tool_call` handler; it + only ever sees a result the tool already produced. ## Staying in step with CBM @@ -296,7 +286,15 @@ records which, and lists every path the pipeline owns: { "cbmVersion": "0.10.8", "reportedVersion": "codebase-memory-mcp 0.10.8", - "sourceClients": ["claude", "augment"] + "sourceClients": ["claude", "augment"], + "generated": [ + "agents/codebase-memory-auditor.md", + "agents/codebase-memory-scout.md", + "agents/codebase-memory.md", + "rules/codebase-memory.md", + "skills/codebase-memory/SKILL.md", + "harvest.json" + ] } ``` @@ -311,7 +309,7 @@ nothing that happens or fails to happen in this repository affects it. **The scheduled CI job, second.** It acquires the newest CBM release, regenerates every artifact, and fails when a committed copy differs. It runs on -pushes, on pull requests, and weekly. +pushes to the default branch, on pull requests, and weekly. The schedule has a blind spot that cannot be closed from inside the repository: GitHub disables scheduled workflows after prolonged repository inactivity, and @@ -329,10 +327,9 @@ regenerates nothing on your machine. immediately and you are told the session needs `/mcp reload`. - **A foreign entry of the same name is left alone.** CBM's own installer, another tool, or a hand edit may already own the `codebase-memory-mcp` key. -- **`mcp.json` has two possible writers.** OMP's `/mcp add` and this package - share no lock. The write is a read-modify-write against observed content and - fails closed on a shape it does not recognise, so a lost update degrades to a - missing entry that the next session start rewrites, never a corrupted file. +- **`mcp.json` has two possible writers.** OMP's `/mcp add` and this package can + both write it. The worst outcome is a lost entry that the next session start + rewrites — never a corrupted file. - **Windows is unsupported.** It needs zip extraction, a different executable suffix, and its own path handling. It is one explicit unsupported-platform error rather than a half-implemented branch. From 6c647323512a41dd29d9ca546032db51d99c572d Mon Sep 17 00:00:00 2001 From: pashifika Date: Sat, 29 Aug 2026 02:55:12 +0900 Subject: [PATCH 4/5] docs: close the round-2 review findings The ruleset paragraph disclaimed a category of parameter its own shape list then stated, so a contributor applying it literally would have deleted three correct bullets. It now states the test instead of a category list: a fact belongs here when changing it changes how work lands, and stays in the rulesets when it can move without changing the procedure. The system-first section had been compressed past the truth. A managed copy with its own cache root is not a cost trade -- a second CBM pointed at a different root will not start while yours is live, which is what the operator actually sees. Restoring that also gives `/cbm install`'s "cache-root hazard" a referent the document names. --- CLAUDE.md | 23 +++++++++++++---------- README.md | 26 +++++++++++++++----------- 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 9b52157..e1faa76 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -26,7 +26,8 @@ The working tree contains two independent Git repositories: `test/`, `dist/`, `package.json`, and `.omp-plugin/`. - `rasen/` tracks planning artifacts in its own repository and remote. -`rasen/` is ignored by the outer repository. Commit its work with +`rasen/` is ignored by the outer repository, so `git status` at the root never +reports its state and it has to be inspected on its own. Commit its work with `git -C rasen`; never stage planning and implementation in the same repository. ## Git workflow @@ -38,15 +39,17 @@ landed this way: `feat/graph-context-and-agents`, `docs/repository-guidelines`, `chore/commit-ruleset-payloads`. The default branch and release tags are protected by the rulesets committed -under `.github/rulesets/`. This section states two things and no more. First, -the shape of that protection: the facts whose change would change how work lands -here. Second, the two literals another file in this repository must match — the -required check name `ci`, which is the gate job's own name in `ci.yml`, and the -tag pattern `v*`, which a pushed tag and the catalog's `source.ref` must -satisfy. Everything else those files configure is theirs to state: approval -counts, the review and bypass booleans, the actor lists, and every other -parameter. Read a value there rather than trusting one repeated in prose. The -shape: +under `.github/rulesets/`. This paragraph and the list below it state two things +and no more. First, the shape of that protection: the facts whose change would +change how work lands here — what a contributor must do, which button merges, +whether a branch must be current first. Second, the two literals another file in +this repository must match: the required check name `ci`, which is the gate +job's own name in `ci.yml`, and the tag pattern `v*`, which a pushed tag and +`.omp-plugin/marketplace.json`'s `source.ref` must satisfy. Nothing verifies +either agreement mechanically, which is why those two are stated here at all. +Everything that can move without changing the procedure stays in the rulesets — +approval counts, the actor and bypass lists, the exemptions — so read a value +there rather than trusting one repeated in prose. The shape: - The default branch rejects deletion and non-fast-forward pushes. - Landing a change requires a pull request whose review threads are resolved. diff --git a/README.md b/README.md index 6ebb114..33dec68 100644 --- a/README.md +++ b/README.md @@ -180,10 +180,13 @@ CBM configuration key for you. Resolution order is **pin, `PATH`, `~/.local/bin`, managed copy** — system before managed, and the reason is the index rather than tidiness. -CBM keeps one cache root per account, holding one graph, and two executables of -different versions do not share it safely. Giving a managed copy a root of its -own would trade that for re-indexing every repository a second time — hours of -work on a large tree, and gigabytes to hold the same answers twice. +CBM keeps one cache root per account, holding one graph. A second CBM pointed at +a root of its own will not start while yours is live: it reports that the active +account daemon is using a different cache directory, and tells you to close +every CBM session and command before retrying. So a managed copy with a root of +its own would buy nothing — it could not run while your installation does, and +filling that root would mean re-indexing every repository a second time: hours +of work on a large tree, and gigabytes to hold the same answers twice. So your existing installation wins. The cost is that this package cannot guarantee a version, and that cost is visible rather than hidden: `/cbm status` @@ -191,8 +194,8 @@ names the source, and an out-of-date system copy produces a pointer to CBM's own `update` instead of an attempt to perform it. `/cbm install` while a system copy resolves is still possible — it is your -machine — but it explains the shared-cache-root consequence and requires an -explicit confirmation first. +machine — but it explains the cache-root hazard above and requires an explicit +confirmation first. ## Graph context in a session @@ -274,8 +277,9 @@ again every time. - **CBM's configuration.** No account-wide CBM key is ever set for you. - **CBM's graph, index, watcher, and cache root.** All CBM's, shared with every other client on the account. -- **Your tool calls.** The augmentation registers no `tool_call` handler; it - only ever sees a result the tool already produced. +- **Your tool calls.** The augmentation registers no `tool_call` handler, so it + can never refuse or delay one; it only adds to a result the tool already + produced. ## Staying in step with CBM @@ -327,9 +331,9 @@ regenerates nothing on your machine. immediately and you are told the session needs `/mcp reload`. - **A foreign entry of the same name is left alone.** CBM's own installer, another tool, or a hand edit may already own the `codebase-memory-mcp` key. -- **`mcp.json` has two possible writers.** OMP's `/mcp add` and this package can - both write it. The worst outcome is a lost entry that the next session start - rewrites — never a corrupted file. +- **`mcp.json` has two possible writers.** OMP's `/mcp add` and this package + write the same file and share no lock. The worst outcome is a lost entry that + the next session start rewrites — never a corrupted file. - **Windows is unsupported.** It needs zip extraction, a different executable suffix, and its own path handling. It is one explicit unsupported-platform error rather than a half-implemented branch. From 03a364d7c2db5c6ef174b805d88e2bbe0d60ce47 Mon Sep 17 00:00:00 2001 From: pashifika Date: Sat, 29 Aug 2026 03:21:34 +0900 Subject: [PATCH 5/5] docs: name the ruleset agreements that are actually unchecked The paragraph said nothing mechanically verifies either literal it states. True of `ci` and of `v*`, and false of the third pairing it named: the release version gate compares `.omp-plugin/marketplace.json`'s `source.ref` against the pushed tag and fails on a mismatch. The exception that licenses stating a literal at all rested on the one file that is checked. The two genuinely unchecked agreements are between a ruleset and a workflow -- `main.json`'s `ci` against the gate job's name, and `tags.json`'s `v*` against `release.yml`'s trigger -- and nothing in this repository reads either ruleset file. The `source.ref` pairing moves to `CONTRIBUTING.md`, where its gate already is. The shape test also disclaimed approval counts as a parameter while its own criterion made them shape: moving the count off zero adds a step. The criterion is now the sequence of steps rather than any precondition, and the count's current value is stated as the reason no approval step is described. --- CLAUDE.md | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index e1faa76..db12128 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -41,15 +41,23 @@ landed this way: `feat/graph-context-and-agents`, The default branch and release tags are protected by the rulesets committed under `.github/rulesets/`. This paragraph and the list below it state two things and no more. First, the shape of that protection: the facts whose change would -change how work lands here — what a contributor must do, which button merges, -whether a branch must be current first. Second, the two literals another file in -this repository must match: the required check name `ci`, which is the gate -job's own name in `ci.yml`, and the tag pattern `v*`, which a pushed tag and -`.omp-plugin/marketplace.json`'s `source.ref` must satisfy. Nothing verifies -either agreement mechanically, which is why those two are stated here at all. -Everything that can move without changing the procedure stays in the rulesets — -approval counts, the actor and bypass lists, the exemptions — so read a value -there rather than trusting one repeated in prose. The shape: +change the sequence of steps by which work lands here — what a contributor must +do, which button merges, whether a branch must be current first. Second, the two +literals a ruleset shares with a workflow: the required check name `ci`, which +`main.json` requires and which is the gate job's own name in `ci.yml`, and the +tag pattern `v*`, which `tags.json` protects and which `release.yml` triggers +on. Nothing reads either ruleset file, so neither agreement is checked anywhere; +that is why those two are stated here at all. (The third pairing, between a +pushed tag and `.omp-plugin/marketplace.json`'s `source.ref`, is checked — the +release version gate fails on a mismatch — so it lives in `CONTRIBUTING.md` +with the procedure, not here.) + +A value that only tunes a threshold inside a step that stays the same is a +parameter and stays in the rulesets: the actor and bypass lists, the +review-dismissal and code-owner switches, the exemptions. Read those there +rather than trusting a value repeated in prose. The approval count is zero +today, so there is no approval step to describe; were it to change, the list +below would gain one. The shape: - The default branch rejects deletion and non-fast-forward pushes. - Landing a change requires a pull request whose review threads are resolved.