Sharpee
Chord / Project & Files / Tooling / Claims

Claims

A claim is a test you write before the story: what the finished story can reach, and what it can never reach. Claims live in a .chord file of their own, named by your test tree's manifest, and the story never imports it, so a claim never ships with the story. The claims runner proves each claim by playing the story breadth-first through the real engine, trying every command the claim's necessary set allows, and reports each one as held, violated or unproven. A red claim is the point: the first run of a story written claims-first is mostly red, and you write toward green.

The necessary set

Brute force over a whole story does not finish. A claim narrows the walk to what is load-bearing on the way: the rooms it may enter, the things it may touch, the verbs it may type. Nothing else is tried, so a claim is proved under its set — a path that needs something outside the set is reported as unproven, never as impossible. Declaring the set is cheap: it is the walkthrough, read off as nouns and verbs.

claims
  needs rooms: the Iron Gates, the Gravel Drive, the Fountain Court, the Boiler Shed, the Entrance Hall, the Kitchen, the Greenhouse, the Folly Hill, the Folly
  needs things: Tobias, the stopcock, the primer plunger, the boiler, the garden shears, the sherry bottle, Mrs Kettle, the vine, the silver locket, the folly door, the fuse, the deed box, the deed
  needs verbs: ask, turn, push, turn on, take, give, prune, open, cut

  claim the story can be won
    the story ends in victory

  claim the deed is in hand
    the player has the deed

  claim Tobias has been asked about the folly
    Tobias was asked about "the folly"
    needs rooms: the Iron Gates, the Gravel Drive
    needs things: Tobias
    needs verbs: ask

  never the deed box leaves the Folly
    the deed box is not in the Folly
    needs rooms: the Iron Gates, the Gravel Drive, the Fountain Court, the Boiler Shed, the Greenhouse, the Folly Hill, the Folly
    needs things: Tobias, the stopcock, the primer plunger, the boiler, the folly door, the deed box
    needs verbs: ask, turn, push, turn on, open, take
end claims

The needs lines at the top are the shared set. A claim that needs less declares its own needs lines: each key it names replaces the shared key, and the rest is inherited. Claims with the same effective set share one walk.

A set that lists more than a claim needs is still sound, only slower, and the compiler says which of it is padding. For each claim it follows every rule that could change what the claim reads, and every guard those rules read, and reports the things in the set that nothing on that path ever touches, as a warning on the needs things: line with a trimmed line to paste in:

fernhill.claims.chord:9: `the story can be won` depends on 11 of the 13
things in its set — under this set nothing it depends on reads sherry
bottle, Mrs Kettle. The walk still runs the set as written; a trimmed line:
`needs things: Tobias, stopcock, primer plunger, boiler, garden shears,
vine, silver locket, folly door, fuse, deed box, deed`.

The finding is a proposal: the walk runs the set exactly as written until you edit the line. It is also conservative — a thing the compiler cannot rule out stays in — so trimming what it names never changes a verdict.

What a claim can say

Each claim or never head is followed by one indented line stating what holds. Where Chord already has a condition for it, that is the line:

  • the diary page is read — a state the thing declares, or one of the platform's words: open/closed, locked/unlocked, on/off, lit/unlit, worn/unworn, read/unread.
  • the note is in the box, the deed box is not in the Folly — where a thing is, or the room it has left.
  • the player is in the Study — the room the player reaches.
  • the player has the deed — what the player carries.
  • the story is midnight — the story's own state.

Three forms only a claim can say:

  • the story ends in victory or the story ends in defeat; the story has ended for any ending.
  • Tobias was asked about "the folly" — a person was asked a topic, quoted as in the topic table.
  • the stopcock has been turned — one of the thing's own on clauses has fired. The word is matched to the clauses the thing declares, so a thing with no on turning says so.

never heads the negative claim. It is violated by the first path that satisfies it, with that path printed as the witness, and held only when the walk has tried every state its set allows. A walk that stops at its budget first leaves the claim unproven, never held.

Selecting the file

The test tree's manifest, <story-id>.tests/manifest.json, names the fragment relative to the story file:

{
  "claims": "fernhill.claims.chord",
  "seed": 42,
  "story": "fernhill",
  "version": 3
}

Leave the key out and no claims run. Point it at a different file and the run uses different claims, with the story untouched. A claims block met inside a story, or in a fragment the story imports, is a compile error: claims are selected, never imported.

Reading the report

sharpee test runs the claims after the derived rule tests whenever the manifest names a file, at the tree's seed, and prints the report after the rooms ratio. A violated or unproven claim never changes the exit code; a claims file that is missing or does not compile does, with the reason named. Every run prints the tally first — how many claims held of how many declared — then each walk's cost, then each claim with its witness or the reason it stayed open. A positive claim held prints the first path that reached it, which is the shortest under its set. A negative claim unproven prints the budget that stopped the walk, how many things its set carried, and how many of them the claim's rules never reach: the states to exhaust double with every independent thing, so the remedy is a tighter set, not a larger budget, and the count says how much tighter it can be.

Locking a reached state

A claim can also be written after the fact. When a played line of your test tree reaches a state worth keeping, lock it: the claim is written into the fragment for you, and its needs set is proposed from the line that reached it rather than typed. In Chord Writer, every typed turn's card has a Lock… button: it lists the facts that are true after that turn and were not true at boot, you pick one, and a sheet shows the proposed name and the three lists as chips, with the things the claim cannot depend on struck through and off. Keep writes the claim and pins it on the card. From the command line the same gesture is sharpee claim:

sharpee claim weefpbmr                               # the facts true at the line's last turn
sharpee claim weefpbmr "the deed box is open" --at 22 --propose   # the proposed block, written nowhere
sharpee claim weefpbmr "the deed box is open" --at 22             # write it and pin the card

The line is a segment id of the tree (or its first typed command, when only one line starts with it), and --at is the turn as you count them. The proposed set is the rooms the line entered, the things it touched or changed, and the verbs it typed, trimmed to what the claim can depend on; --rooms, --things and --verbs write your own lists instead. A story with no fragment gets one, and its manifest the claims key. The written block is an ordinary claim: at run time nothing tells a locked claim from a hand-written one.

Two things follow from the lock. Every line of the tree is a proof for every positive claim it reaches, so a claim some line reaches is reported held, by line with the line and turn, and never walked: a story whose tree reaches its claims proves them in the time the tree takes. And the card the lock was taken on checks the claim there on every run. The fragment keeps one shape, the lock's: a hand edit that reorders or re-indents a block is refused by sharpee test, by block and line, before anything runs.

When a lock breaks

A story edit that breaks a locked claim is a failed card, in the claim's own words:

✗ opening-iron-gates — open deed box with locket: lock "the deed box is open" not held here: the deed box is closed
    The locket's catch does not fit.

The story's output on that turn prints under the cite, the line fails as any failed card fails it, and the run exits 1: this is the one place a broken claim is loud. The claims report then says where the claim stands without the lock. If another line still reaches it, HELD … by line … with the broken lock named beside it; if no line does, not reached by any line followed by the walk's verdict. Those verdicts still never change the exit code. In Chord Writer the same run fills the claims section under the derived rules, one row per claim with its verdict and the report's sentence, and a lock's line visits the card it was taken on.