Commands
review.py
Everything you do to rules by hand: read them, add them, approve or reject them, edit them, pin them, say whether a repository is yours, preview what the agent is sent, and export them to Copilot files.
Synopsis
python3 review.py --name PROJECT COMMAND [options]
--name is required and comes before the command. Rule ids are the eight-character ids shown by list.
| Command | Does |
|---|---|
list | Show rules. |
add | Write a new rule. |
approve / unapprove | Activate pending rules, or move them back. |
reject | Delete rules. |
edit | Change a rule's text or scope. |
pin / unpin | Send a rule with every request, or stop. |
trust / untrust | Say whether rules may be activated here without you. |
resolve | Preview what the agent would be sent. |
usage | See which approved rules the agent actually receives. |
sync | Export active rules as Copilot instruction files. |
list
python3 review.py --name myapp list
python3 review.py --name myapp list --status pending
python3 review.py --name myapp list --details # where each rule came from, its tags and links
python3 review.py --name myapp list --auto # only what Lore activated by itself
Options: --status {active,pending}, --details, --auto. Each line shows the id, status, scope and text, then flags:
[pinned]- The rule is
alwayssent. [auto-activated 2026-10-18]- Lore activated it; no person approved it.
[!! looks risky: …]- The text matches an attack pattern.
approve --allwill skip it. [!! N hidden character(s) …]- The stored text hides characters, shown as
<U+XXXX>. It is never served and cannot be approved.
--details adds the source, when it was created and edited, how often it was re-proposed, the evidence, up to five links, and its tags. Notes on stderr tell you how many approved rules still have no tags.
b8371d86 active section:src/api Use the repository layer for database access
source: standards.md created: 2026-10-18T00:48:59
8fa4eac1 active section:src/api Return errors as problem+json
source: standards.md created: 2026-10-18T00:48:59
-- 2 rule(s)
add
python3 review.py --name myapp add "Wrap SDK calls in an adapter" --scope section:src/api
python3 review.py --name myapp add "Never commit secrets" --pin
python3 review.py --name myapp add "Prefer small functions" --pending
Options: --scope (default global), --pending (store as pending instead of active), --pin (send with every request). Prints added: <id>, or duplicate / promoted when a near-identical rule exists. A rule that reverses a similar one is added with a warning on stderr.
approve
python3 review.py --name myapp approve 1a2b3c4d 5e6f7a8b
python3 review.py --name myapp approve --all
python3 review.py --name myapp approve --all --yes
Options: ids, --all, -y/--yes.
--allasks first. It lists every pending rule it will approve, with its scope and source, and asks[y/N]. No answer (empty or closed input) counts as "no".--yesskips the question.- Risky rules are never bulk-approved. Rules that match an attack pattern, or hide characters, are skipped with a warning and need
approve <id>on their own. - Explicit ids confirm risky rules. If an id you name looks risky, the reasons and the rule are shown and you are asked "Approve it anyway?". Rules with hidden characters cannot be approved at all until you edit or reject them.
- Approving clears a rule's automatic mark.
About to approve 1 pending rule(s). Once approved, the agent is told to follow them:
eb159b38 global Prefer small functions
from: AGENTS.md
approved 1 rule(s)
unapprove
python3 review.py --name myapp unapprove <id>… moves active rules back to pending, so they stop being served but are kept.
reject
python3 review.py --name myapp reject <id>… deletes the rules and forgets their usage counters. This is also how you undo anything Lore activated by itself. A rule you rejected from learn.py stays rejected, because its review comments are remembered.
edit
python3 review.py --name myapp edit 1a2b3c4d --text "Wrap SDK calls in an adapter module"
python3 review.py --name myapp edit 1a2b3c4d --scope section:src/api
Changes the text and/or scope; the id and status are kept. Give at least one. The new text goes through the same hygiene checks, and an edit that would duplicate another rule in the same scope is refused.
pin and unpin
python3 review.py --name myapp pin <id>… marks rules always: they are sent with every request that touches a file in their scope, whatever the task. unpin reverses it, including for rules the agent marked. Most people never need this, because the agent decides; use it to override the agent. See tagging.
trust, untrust
python3 review.py --name myapp trust # always treat this repository as yours
python3 review.py --name myapp untrust # never activate rules here by themselves
python3 review.py --name myapp trust --reset # let the automatic check decide again
Lore normally decides itself (no remote, or a GitHub repository you can push to). Your decision is permanent until you reset it. Prints the result, for example myapp: trusted (set by you with review.py trust). See trust.
resolve
python3 review.py --name myapp resolve src/api/orders.py
python3 review.py --name myapp resolve src/api/orders.py src/api/users.py --task "add pagination"
python3 review.py --name myapp resolve src/api/orders.py --max-tokens 300
Shows exactly what the agent would be sent for these files. Paths may be absolute or relative to the project. With --task it applies the same selection as get_rules (and says how many rules were left out); without it, every eligible rule is shown. --max-tokens is an optional cap. Previews never count as "served".
Rules for project `myapp` (follow before writing code; sections: src/api)
- [section] Use the repository layer for database access
- [section] Return errors as problem+json
- [global] Prefer small functions
- [global] Keep functions small and focused
usage
Lists approved rules least-used first: never served, then longest since last served. The counters come from the MCP server and live in usage.json.
served last served id scope rule
never - eb159b38 global Prefer small functions
12 2026-10-17T16:02:11 b8371d86 section:src/api Use the repository layer for database access
-- 4 approved rule(s); 1 never served
Read it with care: "never served" only means no file the agent worked on matched that rule yet. Give a rule weeks of real use before deleting it.
sync
Writes active rules to <project>/.github/instructions/lore-*.instructions.md, grouped by scope, with matching applyTo globs. Copilot (VS Code and CLI) loads these natively, so it is the fallback for clients without MCP.
---
applyTo: "src/api/**"
---
<!-- generated by lore; edit rules with review.py, not this file -->
- Use the repository layer for database access
- Return errors as problem+json
- Files are marked as generated, rewritten on every sync, pruned when stale, and never imported back as rules.
- Rules with hidden characters are not exported. A target that is a symlink, or an output folder that resolves outside the project, is refused.
- Section-scoped rules need the section in the map; otherwise they are skipped with a warning (re-run
memorize.py). - This writes into your repository, and there is no per-task selection, so it costs more tokens than MCP. See the static fallback.
Exit status
0 on success; 2 with error: … on stderr for an unknown project, a bad scope, a refused approval, or a missing id on edit. Unknown ids on approve, reject, pin and unapprove produce a warning and still exit 0.