---
name: codepremise
description: Maintain the .codepremise/ business-logic map of this repo. Use whenever you create, edit, or delete code — the map must always describe the code truthfully, in the same run as the change.
---

# codepremise — capture business logic while you code

This repo keeps a map of its business logic in `.codepremise/nodes/` — one JSON file
per claim, written by coding agents (you) at the moment the code is written.
Humans review pull requests by reading these claims instead of raw diffs, and
future agents read them before editing to avoid reintroducing old bugs.

## The golden rules

1. **Query the blast radius before you edit.** Once you've located the code
   you plan to change (via grep/reading), ask the graph what that change can
   affect BEFORE editing:

   ```bash
   node .codepremise/validate.mjs . --impact src/checkout/discount.ts:12-24
   ```

   It returns every claim at risk and how: claims pointing at those lines,
   their general rules and corner cases, flows they are steps of, claims
   sharing the same lines, and dependents (claims that declare `depends-on`
   you, transitively). Read each claim's `why` — they are constraints from
   past bugs, audits, and business decisions. Never delete or weaken code a
   claim explains without amending the claim. If the query returns nothing
   and your change is behavioral, you are about to create unclaimed logic —
   add a claim for it.

2. **Write claims in the same run as the code.** When you add or change
   behavior, add or amend the matching node(s) **in the same session**, while
   you still know the why. Never leave this for later; never write claims for
   code you didn't reason about.

3. **Amend vs re-affirm.**
   - Behavior changed → update the node's `what`/`why` AND its pointers.
   - Pure refactor (behavior identical) → update ONLY the pointers
     (`start_line`, `end_line`, `hash`); leave every text field untouched.
     This is a formal statement that the change is behavior-preserving.

4. **Not everything needs a claim.** Plumbing, glue, config: no claim. Only
   real business behavior. Junk claims ("initializes the logger") are worse
   than no claims. Frontend code counts the same as backend: "the submit
   button is disabled until every field validates" is a business rule that
   happens to live in a component; layout and styling are plumbing. The
   tell: if a product decision could change it, it is behavior — claim it.

5. **Capture the why, not just the what.** The `why` is the part that cannot
   be reconstructed later: which bug this guards against, which audit demanded
   it, which campaign asked for it. Reference tickets/incidents when you know
   them.

## Node file format

One file per claim: `.codepremise/nodes/<id>.json`, where `<id>` is a kebab-case slug.

```json
{
  "id": "returning-customer-discount",
  "type": "rule",
  "title": "Returning customers get a 10% discount",
  "what": "When a customer who has bought before checks out, we take 10% off the total before tax.",
  "why": "Marketing campaign Q3-2026. Must apply BEFORE tax — applying after tax broke tax reporting (bug #482).",
  "code": [
    { "file": "src/checkout/discount.ts", "start_line": 12, "end_line": 24, "hash": "a3f9c1d20e77" }
  ],
  "tests": [
    { "file": "tests/discount.test.ts", "name": "returning customer gets 10% off before tax" }
  ],
  "links": [
    { "type": "refines", "node": "checkout-pricing" },
    { "type": "depends-on", "node": "cart-validation", "note": "assumes cart already validated" }
  ]
}
```

- `type`: `"rule"` (one behavior), `"sequence"` (an ordered flow), or
  `"corner-case"` (an exception to its parent rule).
- `links`: EVERY relation between claims is an entry here —
  `{ "type": "...", "node": "<id>", "note"?: "..." }`. Defined types:
  - `"refines"` — the target is this claim's parent (general → specific).
    At most one per node; corner cases always have one.
  - `"step"` — only on sequences: the target is a step of this flow, and the
    array order of the step links IS the step order. Steps always point at
    claims; a step too trivial to deserve its own claim belongs in the
    sequence's own `what` and `code` instead.
  - `"depends-on"` — this claim's correctness rests on the target's behavior
    (e.g. tax-on-discounted-total depends on the discount rule). This powers
    impact analysis: when the target changes, this claim is flagged for
    revisiting, transitively.
  - `"related"` — generic cross-reference. Unknown types are allowed and
    treated as `related` by all tooling.
- `tests`: optional but valuable — a claim with a test is verifiable.
- A node may point at code in many files; a code range may belong to many nodes.

## Writing style — claims are contracts

A claim is the contract the human reviews INSTEAD of the code: they judge
whether the stated behavior is the right behavior, and trust that the code
matches — a trust enforced by the pointers, hashes and tests, not assumed.
That is why every word carries weight. The test for every `what`: after
reading it, a human understands the behavior without opening the code, an
ambiguous term is a defect, and nothing in it goes stale when the code is
refactored without behavior change, so never use ambiguous terms.

- **Write in the reader's vocabulary, never yours.** Name actions the way a
  user of the system would: "posting a comment or submitting a review", not
  "the first write"; "opening a private repository", not "an unreadable
  ref". If a term only makes sense to someone who already read the code or
  designed the system, replace it.
- **Behavior-level how: yes. Code-level how: no.** "Change requests are
  collected locally and submitted as one review" is behavior — it tells the
  reader what to expect, keep it. "We split the body on markers and iterate
  the parts" is code structure — the pointer shows that, cut it.
- `title`: the behavior in one line, ≤ 80 chars.
- `what`: 1–3 sentences, self-sufficient, exact about boundaries ("before
  tax", "at most once", "only same-site paths"). One idea per node — an
  "and also…" is a second claim or a corner case.
- `why`: 1–2 sentences — the BUSINESS reason this one behavior exists, and
  its source (bug #, audit, decision). One why per claim: if your why is
  explaining several decisions ("X exists because…; also Y prevents…; and
  Z must never…"), you have several claims — split them. Security
  rationales belong on their own corner case, not mixed into the parent's
  why.

## Pointers — a claim references EVERY site that implements it

This is the core of the method. If a behavior is implemented in three
places, the claim lists three code pointers — the entry point alone is not
enough. An agent asking "what does editing this affect?" must find the claim
from ANY of its implementation sites; a missing pointer is an invisible
blast radius and will break the behavior silently.

Before writing a claim, ask: where else does this behavior live? Redirects
and their triggers. A gate and the code that routes to it. A format written
in one file and parsed in another. List them all. If two sites belong to
different claims, connect the claims with a link instead.

**Mandatory final check — reconcile text against pointers.** After drafting
a claim, re-read its `what` sentence by sentence and, for each one, name
which pointer's lines implement it. This is not optional and not skippable
when you feel sure: the sentences you are most confident about are the most
likely to be unbound, because you wrote them from memory of code you did
not just touch — your pointers cover your recent edit; your text covers
everything you know. Any sentence with no implementing pointer gets one of
two treatments: add the pointer, or delete the sentence. Never leave a true
but unbound sentence in a claim.

## Computing the hash

`hash` = first 12 hex chars of the SHA-256 of the exact text of the pointed
lines (1-indexed, inclusive, joined with `\n`, no trailing newline).

```bash
sed -n '12,24p' src/checkout/discount.ts | perl -0pe 'chomp' | shasum -a 256 | cut -c1-12
```

Or in any language: split the file on newlines, slice `[start-1, end]`, join
with `\n`, sha256, take 12 hex chars.

After ANY edit to a file, every node pointing at that file must have pointers
that match reality again (correct line numbers, correct hash). Pure line
shifts (edits above a range moved it; the code itself is unchanged) are
mechanical — do not renumber by hand:

```bash
node .codepremise/validate.mjs . --fix
```

It finds the claimed code at its new location and rewrites the pointers.
Only real content changes need your judgment (amend vs re-affirm).

## Sequences and structure

- When one flow has ordered steps, model it as a `sequence` node with `step`
  links to the step claims **in the order your own `what` text mentions
  them** — the order is meaningful and preserved in review.
- Corner cases go in their own `corner-case` node with a `refines` link to
  the general rule — they are the highest-value claims, because they are what
  future agents would otherwise "clean up" and break.

## Validate before you finish

The map has a JSON Schema (`codepremise-node.schema.json`, served next to this
skill) and a strict validator. If the repo has `.codepremise/validate.mjs`, run it
as the last step of any session that touched code or the map:

```bash
node .codepremise/validate.mjs
```

It checks schema shape, id/filename identity, referential integrity
(refines/links/steps targets exist, no cycles), and — most importantly — that
every pointer's hash matches the real code. A non-zero exit means the map
lies about the code: fix it before you finish. Never edit a hash to silence
the validator without re-reading the claim — a hash mismatch is the signal
that a claim needs amending or re-affirming, not a formatting problem.

## When you remove behavior

Delete the node file in the same commit. A removed claim is the most
suspicious thing a reviewer sees — make the commit message and PR description
say why the behavior went away.
