agentsclimarketplace

Grounding rules

Skill initialneil/grounding-rules/skills/grounding-rules

Distill a system or subsystem into a short, human-readable set of GROUNDING RULES — the minimal load-bearing invariants and design decisions that let a reader gain CONFIDENCE in the system in minutes and adjudicate future design choices, instead of reading a full spec for hours. Use this whenever the user wants the "essence" / "constitution" of a module, the load-bearing rules / single-source-of-truth / key invariants of a system, a first-principles explanation of how a subsystem really works (not API-reference docs), or types /grounding-rules. Three actions: a fresh grounding pass; `update <new facts or corrections>` (re-ground an existing doc when the system changes); and `ask <question>` (answer from the real code in the grounding voice). Favors compression and the good-faith reader: only rules that matter, that can't be inferred from the others, and whose plain reading makes the right choice the obvious one. Writes to a vault path → invokes obsidian-markdown. NOT for exhaustive API reference, tutorials, change logs, or edge-case fencing.From its SKILL.md

Install
npx -y skills add initialneil/grounding-rules --skill grounding-rules

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

15.4 KB, as published. Nobody here has run it

Grounding Rules

What a grounding-rules document is

A grounding-rules document is to a system what a minimal set of axioms is to a theory: the smallest set of statements such that, if you know them, you know the system — almost everything else true about it can be derived with ordinary reasoning.

It has two jobs, and every rule serves both:

  1. Teach the system fast. A capable engineer reads the rules in a few minutes and walks away confident — the nouns, who owns what, how data flows, what can never happen.
  2. Drive decisions. A new question ("can a job have two runners?") is answered by checking it against the rules, the way you'd type-check against an invariant. A good rule settles a whole class of questions.

This is not documentation and not a spec. Docs describe every surface and rot as the API changes. A spec fences every case for a machine. Grounding rules describe only the load-bearing skeleton, for a human, and barely move — because they capture decisions, not surfaces.

The bar: a good rule makes the right choice the obvious one

This is the heart of the skill. A rule is written for a human acting in good faith, to give them confidence quickly — not to make every wrong path impossible.

  • The test is "first choice goes right," not "wrong is impossible." A rule earns its place if a developer's natural first instinct after reading it is the correct implementation. A reader who contrives a perverse reading is not your audience; don't write for them.
  • Optimize for fast confidence over completeness. The win is a reader trusting the system after a short read — not after an exhaustive one. A rule that doesn't buy confidence quickly isn't pulling its weight.
  • Rules are not a spec — if you're adding clauses to fence edge cases, stop. Completeness and edge-fencing belong in the spec, the code, and the tests. The moment a rule grows qualifiers to block a contrived misreading, it has rotted into a spec, and nobody reads a spec for confidence. Keep the rule; move the edge case elsewhere.
  • A rule fits in your head and reads the way it should be built. Short enough to hold; shaped so the obvious reading is the right implementation. If you can't restate it in your own words, it's too detailed.
  • A gap is a missing readable rule, not a missing clause. When something broke, don't bolt qualifiers onto an existing rule. Ask: what one line would have made the right choice obvious? — then write that line.

Ground every rule in the running system — never from memory

A rule is only as trustworthy as the source you verified it against. Memory, plausible inference, a stale note, and a short spec are all hypotheses.

  • Verify at the call site, not from recall. Before asserting a contract, open the code that implements it (or pull the live response) and confirm. "I'm fairly sure native uses the proxy path" is how a wrong rule gets written; the one line getSessionDetail() → ?format=signed is how it gets corrected.
  • Pull live data before fixing the shape of a rule. The wire doesn't lie; an assumed payload does. One real response often decides the whole design.
  • When one surface works and another doesn't, diff them. The delta between the working reference and the broken one usually is the rule you're missing.
  • A correction means re-checking, not editing in place. A new fact can make an old rule wrong, redundant, or duplicated — verify against code, then re-ground the whole doc (see update).

The two tests every rule must pass

Apply the code-simplifier mindset to the rule set itself: single source of truth, no rule restates another, nothing present that could be inferred.

Test 1 — Load-bearing. If this rule were violated, would the system break or the mental model be wrong? If violating it changes nothing anyone cares about, it's trivia. Cut it.

Test 2 — Non-inferable. Could a reader derive this from the rules already written plus ordinary reasoning? If yes, it's a consequence, not an axiom. Cut it, or fold the surprising part into the rule it follows from.

What survives is small — typically 8–15 rules. Thirty means you're documenting. The discipline of cutting is the whole value: a reader holds ten load-bearing rules in their head; they cannot hold thirty facts.

Corollary — say each rule once. A rule in two places (a diagram caption and a section) breaks its own single source of truth. The diagram names the entities; the rules govern them. Same fact in two spots → a merge, not two rules.

Where load-bearing rules cluster

You don't invent rules; you find them. Sweep the system through each lens:

  • Single source of truth. For each important fact or piece of state: which one place owns it? "X is the only place that knows Y" is the strongest, most common grounding rule. Two owners → a bug, or a rule explaining the relationship.
  • Boundaries — and their duals. Every line data crosses (LLM ↔ system, user ↔ user, public ↔ private, client ↔ server, store ↔ view) carries a rule about what is allowed across and who enforces it. Crucially, a boundary rule constrains traffic in one direction — so ask what crosses the dual boundary too. "Only the durable handle crosses into the model" is silent on what may cross into the renderer; the bug usually lives in the dual you assumed was covered. Name both.
  • Lifecycle & state. The legal states of the main entities and their transitions — especially the absolutes: "immutable", "append-only", "soft- deleted, never hard-deleted".
  • Named patterns. When a known pattern is in play — append-only log, immutable snapshot + moving pointer, discriminator column on a unified table, confused- deputy defense, soft delete, durable handle + resolved projection — name it. The name compresses a paragraph into a word.
  • The one diagram. The entity/relationship skeleton. One small picture usually grounds every other rule; draw it first.

Output format

Write to the path the user gives (often a Markdown note). Use this shape:

# <System> — Grounding Rules

> One sentence: what this system *is*, in plain language. The mental model in a breath.

## tl;dr
<The foundation rules as plain bullets — the handful a reader must hold to derive
everything else. Max two levels of nesting; no *why*, no anchors, no prose. If the
rest of the doc vanished, these bullets alone would still teach the system's shape.
The ultimate compression test: if you can't get the system down to ~5–10 foundation
bullets, you haven't found which rules are foundational. This REPLACES a separate
"foundations" group — everything below is just these bullets expanded.>

## The model
<The one diagram — entities and how they nest/relate, drawn first; every rule below
annotates it. NAME the nouns here (and the ownership boundary when two parts are
isolated); do not restate the rules. A reader should point at any noun used anywhere
in the doc and find it on this map.>

## Core operations
<The system's core verbs — "log", "instantiate", "recommend". Often better as a
tl;dr bullet; pull into their own section only when not obvious from the model.>

## <Group A — e.g. The nouns & their single source of truth>
**R1. <One-line declarative claim.>**
*Why:* <one or two lines — the reasoning that makes it load-bearing, and that lets
the rule drive a decision its author never foresaw.>
<optional anchor: where it lives, e.g. `models.py:Job.runner_id`>

**R2. ...**

## <Group B — Lifecycle / the ladder / boundaries / ...>
...

## Using these rules
<2–3 real design questions, each answered in one line by citing a rule. The proof
the rules are operative, not decorative.>

Writing into an Obsidian vault? When the target path is inside an Obsidian vault, invoke the obsidian-markdown skill (Skill tool) and follow it: vault frontmatter tags, callouts for the high-signal bits (a > [!info] callout for the one-line mental model, > [!tldr] for the tl;dr, > [!example] for "Using these rules"), and [[wikilinks]] only for notes that actually exist (plain text otherwise). The rules stay terse; Obsidian syntax only carries the high-signal framing. (obsidian-markdown is a soft dependency — if it isn't installed, write plain Markdown.)

Rule-writing craft

  • State the claim in one line, declarative or imperative. If you can't say it in a sentence, it's two rules — or you don't understand it yet.
  • Give the why when it isn't self-evident. A rule whose rationale a reader can't reconstruct is brittle — people route around rules they don't understand, and a bare rule can't stretch to a decision its author never foresaw. Add the why exactly when that rationale is what lets the rule travel. When a rule is self-evidently load-bearing, the terse assertion is the whole rule — don't pad.
  • Group rules by the system's own seams. Theme works (model / lifecycle / boundaries / invariants), but when two parts are isolated — no shared runtime, data, or state — let that boundary split the doc; their rules live in separate sections and never mix. The only rule allowed to span both is the one that defines the boundary. Structure that mirrors the architecture teaches it for free.
  • Anchor lightly. A file:symbol pointer per rule helps a reader verify and find the code, but the body stays prose — never paste code blocks or signatures. Anchors locate; they don't define.
  • Number them (R1, R2…) so they're citable in review ("this violates R5").

What to cut (the same energy as deleting code)

  • Anything inferable from a rule already written → a theorem, not an axiom.
  • Anything whose violation wouldn't change a mental model or a decision → trivia.
  • Exact API signatures, full column lists, request/response shapes, step-by-step how-tos → reference documentation; it rots and buries the rules.
  • Clauses that exist only to fence a contrived misreading → that's spec creep; the rule's plain reading already serves the good-faith reader.
  • Secondary mechanisms serving a primary rule (caches, denormalized columns, SSE notifications) → mention only if a reader would get the model wrong without them.

Process

  1. Get grounded in the system first. Read the code, or ask for / spawn a research pass. You cannot compress what you don't understand — and you cannot trust a rule you didn't verify. The rules are the output of understanding.
  2. Draw the one diagram — the entity skeleton. Everything hangs off it.
  3. Sweep the lenses and collect candidate rules freely — over-collect.
  4. Compress. Run every candidate through the two tests and the bar (does its plain reading make the right choice obvious?). Merge overlaps, delete consequences, name the patterns. This is where the document earns its keep.
  5. Add the why to each survivor, and write 2–3 "Using these rules" examples to prove they're operative.
  6. Read it cold. Could a smart newcomer gain confidence in the system from this alone, and settle a design argument with it? If not, a load-bearing rule is missing or buried. Iterate.

Updating an existing doc (the update action)

/grounding-rules update <new facts or corrections> re-grounds an existing doc instead of writing a fresh one. The trap: update is not append. A new fact can make an old rule wrong, redundant, or duplicated, so re-grounding means reconsidering the whole doc.

  1. Read the existing doc and treat its rules as the current axioms.
  2. Fold in the new facts. If the fact is a correction, re-check the code first — a correction usually means a rule rested on a wrong assumption.
  3. Prefer a missing rule over a new clause. When the new fact is a gap the doc didn't cover (often the dual of a boundary it already states), add the one readable rule that closes it — don't graft qualifiers onto a neighbor.
  4. Re-run both tests over the merged set. A new fact may subsume an old rule (delete), contradict it (fix it and everything that leaned on it), or duplicate it (merge). Single source of truth, maintained over time.
  5. Preserve voice and structure. Change only what the facts require; keep the grouping and terseness. The reader gets a sharper doc, not a different one.
  6. Re-read cold for orphans — a rule that only made sense because of one you just deleted.

Asking about a grounded system (the ask action)

/grounding-rules ask <question> answers a question about the system from the real code, in the grounding voice — brief, correct, load-bearing, with a small example when it helps. The read-only counterpart to writing the doc.

  1. Ground it in code first. Never answer from memory, the doc, or a prior research pass — open the code, confirm, cite file:symbol. The value of ask is that the answer is true now. If you can't verify a part, say so.
  2. Answer like a rule, not a tutorial. Lead with the one-line invariant, then a few load-bearing specifics. Name the one or two places that decide the behavior; skip the call-graph walk.
  3. Keep it brief and concrete. A tiny example — the actual shape of the thing — beats paragraphs. Quote code only when the quote is the answer.
  4. Reconcile with the doc. If the code contradicts a rule, say so and offer to update. If it confirms one, cite it ("this is C3"). If it's a new load-bearing fact the doc is missing, flag it as a candidate rule.

A good ask often surfaces the next update.

Example (excerpt — shape, not content)

R5. Job.runner_id is the sole link between a job and the worker running it. Set → claimed (and by which worker); NULL → unclaimed. Never both. Why: one nullable FK on a unified jobs table means exactly one place to ask "is this job claimed, and by whom?" — so the scheduler resolves the worker from the row it owns, and no client can claim someone else's job. (Pattern: discriminator column on a unified table.)

Notice: one-line claim; a why that explains the design (not restates the claim); a named pattern; immediately usable — "can a job have two runners?" is answered by R5 alone (no — that's a re-queue into a new job). And a developer's first instinct after reading it ("resolve the worker from the job row") is the right one.

Keep looking

Skills are one crate of 627,801. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.