remember
Declare new memory items—rules, orientations, reports, lookups, or chunks—through a write gate that refuses invalid entries with exact fixes; call lookup first to avoid near-duplicates.
Instructions
Code lane: declares a NEW item (Rule, Orientation, Report, Lookup or Chunk) through the write gate. Call lookup first so this corrects an existing item instead of storing a near-duplicate; for anything about the owner's own life use shelve, never this. On a replica this queues instead of writing ('queued for the main machine' is not an error). Refuses, with the exact reason and the fix, when a Rule/Orientation has no binding (or, if costly or irreversible, only a project name, which reaches no tool call), no falsifier, or exceeds 300 characters, when a Report/Chunk names no project scope, or when the text or falsifier carries a real secret token (never echoed back; store where it lives, never the value; no override); nothing is written on a refusal. check_kind/check_path/check_literal(s) optionally attach a machine-runnable proof alongside the falsifier - see server instructions for the six check kinds. Every Rule/Orientation is TRIED as it is written: a check that bites is stored on the rule track, a rule with no working tooth is stored as a note (no check), and a tooth THOR builds from the rule's own words that bites refuses the write, naming the exact check to hang - the reply's 'teeth:' note says which. Replies with the stored id, kind and event sequence, or the refusal text.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Caller-chosen id, kept forever. Pick something short, stable and grep-able (e.g. "no-force-push-main"), not a sentence. | |
| key | No | Required for a Lookup: the exact key a future `lookup` call names to get this item back. Meaningless for the other four kinds. | |
| kind | Yes | One of: rule, orientation, report, lookup, chunk. | |
| tags | No | ||
| text | Yes | The fact itself. A Rule/Orientation is refused past 300 characters - move reasoning into a Report instead of lengthening this. | |
| always | No | Bind this item to the pinned Always layer (served in full at every session start). Only a Rule/Orientation may set this. | |
| because | No | REQUIRED with legitimate_calls, may_change or accept_refusing, and never needed otherwise: one sentence of at least 20 characters saying WHY the named span may change, or why the call is legitimate, while the rule stays true. It is kept in this item's history and shown to the owner at the next evaluation. First try to hang a check on the literal that IS the rule's subject; dispute only an incidental span. | |
| expires | No | ISO-8601 date. Only a Report may carry this - a Rule, Orientation, Lookup or Chunk with an expiry is refused (they last until revised). | |
| moments | No | Action names this item fires on (repeatable), e.g. ["push"]. Only a Rule/Orientation may bind to a moment. The ones that actually fire are derived from a real command or file path (publish, commit, push, deploy and the rest - see intent::from_command/from_path), plus remember itself. answer and claim_done are refused on a NEW binding: nothing produces either yet, so a rule bound only to one would store cleanly and never fire. | |
| project | No | Project this item belongs to. Omit for a global, cross-project item. | |
| targets | No | Exact targets this item fires on (repeatable). Only a Rule/Orientation may bind to a target; the value must be the real path/command/etc, never a glob and never a bare role name. | |
| severity | No | One of: irreversible, costly, house_style. Meaningless (and refused as a binding target would be) on a Report/Lookup/Chunk. | |
| falsifier | No | What observation would prove this fact wrong, one sentence. Required for a Rule or Orientation - they never expire, so this is the only thing that ever names when one has gone stale. | |
| check_kind | No | One of: path_exists, contains, absent, absent_all, forbidden, requires. An optional machine-runnable check, alongside (never instead of) falsifier - only a Rule/Orientation may carry one, and only while it currently HOLDS can it block a write. Every kind except forbidden needs check_path; path_exists refuses check_literal/check_literals; contains/absent/requires need one of them; absent_all/forbidden need check_literals. requires catches something FORGOTTEN rather than written - see server instructions. Omit all four check_* fields for no check at all. | |
| check_path | No | The exact file this check inspects, relative to the checker's root - or, for contains/absent/absent_all only, a DIRECTORY: every regular file directly inside it, never one in a subdirectory. Use the directory form when one fact spans more than one file there (e.g. a setting duplicated across two config files). Required with every check_kind except forbidden, which carries no path at all and is refused if one is given. | |
| may_change | No | ONLY after a refusal said THOR derived a contains check from this rule's text and a file: the span you name as one that MAY CHANGE in that file - e.g. ["version"] for a rule that names the version line of package.json. It must be exactly the derived check's literal. Then the rule is stored as a note by dispute, which doctor lists for the owner. Needs `because`. Leave it out otherwise. | |
| check_literal | No | The exact literal a "contains" or "absent" check_kind looks for. Refused together with "path_exists", or together with check_literals; required with "contains"/"absent". | |
| check_literals | No | A SET of literals to forbid together, for check_kind absent_all (in one file) or forbidden (everywhere, no file). One rule forbidding several things at once (e.g. every banned punctuation character) is ONE item with a set here, never several near-identical items each forbidding one literal. Each literal is its own array entry, never joined into one delimited string. Refused together with check_literal, refused empty, and refused with any other check_kind except requires, which takes the trigger first - one of this item's own command bindings, or a specific literal inside the bound command such as "-p my-dev" in an ssh call - then every answer that satisfies it. | |
| accept_refusing | No | ONLY after a refusal said your check would refuse most of the real calls it reaches: one of the calls it listed, named because refusing it IS the intent - e.g. ["git push origin main"] for a "never push this repository until the owner says so" ban. The rule stays on the rule track, and doctor lists every rule kept this way. Needs `because`. Otherwise narrow the check instead. | |
| legitimate_calls | No | ONLY after a refusal said THOR built a tooth from this rule's own text and it bites: a real, whole call you name as LEGITIMATE although that tooth refuses it - e.g. ["git push --force-with-lease origin main"] for a rule whose text names `--force`. It must reach the tooth's command, be refused by it, differ from the forbidden form THOR built itself, and carry something beyond the command and the literal. Then the rule is stored as a note by dispute, which doctor lists for the owner. Needs `because`. Leave it out otherwise. | |
| new_collection_named_by_owner | No | THE OWNER JUST NAMED A NEW COLLECTION - repeat that name here exactly as he gave it, and it will be opened. The only way an unopened collection can be written to: nothing existing fit, you showed him the refusal (it lists both lanes), you asked, and he answered with a name. Never fill this in on your own judgement or to get past a refusal. Must match the project (or key) on this same call, or the write is refused anyway. |