Authoring .argmap maps

This file is meant to be sufficient on its own: syntax, numbers, the idiom catalog, nesting discipline, the workflow, and the checks. Open the full tutorial only for depth: the rationale behind each rule, the reading chapter, and a complete worked example with its solver readout (AUTHORING_TUTORIAL.md Appendix A). Pointers below read tut 7.4 (= that tutorial’s section 7.4). examples/README.md indexes the example corpus by idiom, and is the place to read a whole real file. MATH.md is the model underneath the numbers. Read it when a why question about solved values or tension comes up; nothing here needs it.

Outside this repo: the canonical copies live in the argmap repo checkout: .claude/skills/argmap-author/SKILL.md and AUTHORING_TUTORIAL.md at its root; the user-level pointer skill in ~/.claude/skills/ carries the local path to it. For machines without the checkout, the deployed webapp serves the tutorial at p1graph.org/AUTHORING_TUTORIAL.md and this skill card from p1graph.org/authoring-tutorial.html (the “download SKILL.md” link: the host renders raw .md with front matter to HTML, so the page hands over the exact bytes as a download instead).

Reading only

Maps render at p1graph.org (text / outline / graph panes; solved values, “implied” in the UI, are on by default and the “Show what the map implies” Controls toggle turns them off, authored -> implied). Headless query, from experiments/solver-prototypes/ (needs python3 + numpy + scipy + node): python3 solve_map.py FILE @node '$edge' or --top 10.

Three things a reader sees since D161 (2026-09-08; tut 2.2, 4.6):

  1. Every number has a firmness, shown beside it in coin flips on a claim (from the width the author left open: 0.7/0.1 about 8, a point 198, the cap) and as the kind word on a line (the # kind: key: formal hard, deductive 1000, mechanism 64, empirical and testimony 16, analogy and hope 4, no key 16).
  2. The tint means conflict. A readout colours only where the implied value has left what the author wrote (below a line’s strength, outside an interval, off a point) by more than 0.01; the solve filling an interval the author left open is shown uncoloured. On the flagship as authored one check badge sits past 0.10, the headline’s: 0.603 against its check 0.75..0.95, 0.147 short (0.617 from the two inverses on the title claim that took out the reference fill that had read 0.708, D168, to the objection rewiring of D170); the next widest gap is @mis-ext’s, 0.795 against 0.85..0.95, then @fragile’s, 0.796 (measured 2026-09-28). The headline’s check was re-read on 2026-09-25 from the book’s unconditional sentences, with five other checks the dock audit found reading another quantity, and two lines read just under their strength (measured 2026-09-25).
  3. What-if mode is revision. The reader’s number replaces the author’s on that claim as a point at the cap and the map re-solves. On a root the map follows forward (nothing bends, nothing colours); on a conclusion the author’s case retreats where it is softest: unnumbered premises first, then hopes and analogies, judgments and records, flat assertions, mechanisms, deductive claims, and a formal step never. Where the map cannot meet the reader’s number, the adjustment row says by how much (on the confusions map’s Socrates syllogism, a “not mortal” at 0 reads “reached 32%”): the refused residual. The other reading, conditioning (“suppose it turned out that way”), is the bench’s solve_map.py --condition.

Syntax crib

The block below is a complete, lint-clean file (given argmap-version: 0.3 in the frontmatter, which the last two lines need):

@prem1 [First premise] 0.9?: gloss; a deeper-indented prose line folds in [^src]
@prem2 [Second premise] 0.8?:
@ground [The objection's ground] 0.5?:
@root [A root fact] 0.9?:
@concl [The claim, as a proposition]: derived, so check not pin  # check: 0.8
$id [headline warrant, <=56 chars] 0.8? @concl | @prem1 AND @prem2: depth here  # kind: mechanism
$rebut 0.3? ~@concl | @ground:            # rebuttal: attacks the claim
$uc 0.6? ~@concl | @ground AND $id:       # undercut: attacks the inference $id
$fact 0.9? @concl:                        # premise-less constraint factor
$step 0.7? @concl | @root: coarse summary; the indented block replaces it unfolded
  @mid [Intermediate claim] 0.8?:
  $fine 0.8? @concl | @root AND @mid:
::topic [A named box]: v0.3 declared group; its block is MEMBERSHIP, not refinement
  @side [An unrelated topic in the same file] 0.4?: a claim of its own
    #[note: an annotation comment - free per file in the parity check]
    > a verbatim span from the source, attached to @side [^src]
[^src]: Author, "Title," venue, year, URL.

Rules: spaces-only indent (a tab is a parse error); IDs document-global, forward refs legal, one namespace across @/$/::; AND linked / OR convergent, parens to mix; ~$id is banned (error E3), so write an undercut instead; ? = estimated; labels crop at 56 chars on evidences (and group boxes), with W5 firing at 57 exactly.

AND/OR take any number of operands and any operand may be negated, so a three-conjunct linked premise containing a ~ (@a AND @b AND ~@c) is ordinary and idiomatic; the neither-alone-suffices test scales unchanged. A premise-less evidence ($fact 0.9? @concl:) is an unconditional floor on its conclusion (no slab, nothing to be in force against), and it accumulates with the other lines concluding there under the same independence assumption as any convergent sibling.

Indentation is sigil-keyed (D58/D59): it always means “belongs to the line above”; the PARENT’s sigil says how. Under @/$ = refinement. Under :: = membership in a declared group. Sigil-less prose folds into the gloss; a > child is a quote line (below).

Optional YAML frontmatter carries title, author, date, description, source, scope (which part of the source the map claims to cover; state it, it is review checklist item 6), focus: [id, id] (D57; declare only when topology misreads intent, e.g. a goal guard), and argmap-version. Unknown keys are preserved, which makes frontmatter the extension point for provenance notes. The version gate covers pairs and quote lines: 0.3 is required if the file writes slash pairs (0.9/0.2, E5/W10) or > quote lines (W19). Declared groups are not gated, though a ::-using file conventionally declares 0.3.

Two-sided pairs (v0.3, D52/D53): $e 0.9/0.2 @c | @a adds an opposed floor in the same slab; @s 0.8/0.1 bounds P(s) to [0.8, 0.9] instead of pinning a point. No whitespace around the slash, ? binds per member, an omitted second member is 0 (= the v0.2 reading). Ignore pairs until you need “this cuts both ways” or an interval-shaped residual.

Declared groups (::, v0.3/D58)

::id [Label]: gloss names a box drawn around the nodes indented under it. Display only, by construction: no credence (a number on a :: line is an error), never referenceable (::id in any expression is a parse error), and transparent: deleting every :: line leaves the graph, the roles and the solve identical.

Use it for a topic, where a wrapper evidence would be a lie: two arguments sharing a file but no premise, or a shelf of background facts. Before ::, that could only be a # ==== comment no tool could see. The workhorse case in practice is the objection battery inside a box: several answered attacks on the box’s claim, grouped so they read (and fold) as one unit. Keep the family’s lines contiguous; put a ground inside only if nothing outside the family consumes it. Head a box of ONE kind of objection with the members’ shared thesis in the objector’s voice, every member an instance of it ([A halt cannot be made to stick]; rule of 2026-09-09, AUTHORING_TUTORIAL 3.11 item 4), its gloss opening on the member list; the rule binds a kind card nested under an objection shelf, and a document-level shelf keeps its short reader question (decided 2026-09-09). Every group folds to a summarizing card (non-closed ones bundle their boundary edges into dashed summaries, D124), and a group nested in a refinement starts folded.

Lint checks the authored box against the derived block (connected component). Silent: a group equal to one block, or spanning several whole blocks. Warns: W12 a group covering only PART of a connected block (edges cross the boundary; its fold bundles them into summary edges), W13 one block split across two groups (usually an accidental shared premise merged two topics while your headings still claim they are separate, which is the mistake worth catching), W14 an empty group. Only document-level groups are checked; nested ones subdivide their parent. Membership does NOT suppress the isolate note I1. I2 lists the derived blocks for any multi-block file. Read it to confirm the split you intended.

Source quotes (>, v0.3/D59)

> verbatim text [^locator] under a node carries a verbatim span of source material plus its footnote locator (tut 3.12). The gloss goes back to being a claim a reader can parse cold; the quotes sit beneath it as its evidence. Replaces the retired ~"…" in-gloss convention, which no tool could see.

@no-honor [Honor is a contingent evolved hack an AI won't carry] 0.9?: an
  evolutionarily contingent shortcut, not a convergent feature of minds
  #[de: ein seltsamer Hack, auf den die Menschheit gestossen ist]
  > a specific weird hack that humanity stumbled into [^supp-ch5]
  > quite skeptical that gradient descent will stumble across the same shortcut [^supp-ch5]

Rules: verbatim, never paraphrased; a budget (tut 5.4: at most one sentence per line, normally one per node, low hundreds of words from any one work and proportionally less from a short source, a tenth of which is already far too much; quote the fragment a strength or a ruling rests on and retell the rest in the gloss); always give a locator (W15: chapter, supplement page, or transcript timestamp, whatever the source allows); only a trailing [^id] is the locator, anything else on the line is verbatim text including a mid-line [^…] (W16); no trailing # comment, the one line kind without one, because source text cannot be reworded to dodge the splitter (W17 flags a ` # ` inside a quote); no wrapping, one line however long; placement is positional: a quote attaches to the node above and must sit in that node’s annotation block, the span before its first child, so a > at top level or after a child node is E9, never a re-attachment outward; gloss first, then quotes (W18, since the serializer rewrites to that order anyway); declare argmap-version: 0.3 (W19).

Which spans become > lines: the three-way test. Is this the node’s own wording, or support for it?

  1. Supporting quote (most of them), evidence for the claim: lift to a > line.
  2. Load-bearing inline fragment, a verbatim phrase that is a grammatical constituent of the gloss sentence (Kelvin's "infinitely beyond…" fell to DNA): keep it in the gloss in plain quotation marks, the node’s own phrasing borrowing the source’s words. Add an echo (a > line with the full verbatim sentence + locator, gloss fragment unchanged) when provenance matters.
  3. Quote-is-the-claim (the gloss is nothing but the quote): the degenerate case of 2, with plain marks in the gloss and a > echo underneath.

Quotes are never translated. In a multilingual set the whole > line is byte-identical across languages (translation-parity.py enforces it); a translated “verbatim” quote is false and breaks the tie to the source. The echo pattern is what makes case 2 honest across languages: the translated gloss quotes ordinary prose, the > line stays in the source language.

Annotation comments. Per-quote side data goes on a full-line #[key: …] comment (no space between # and [) above the quote, at its indent. An ordinary comment to the parser; free per file in the parity check (every other comment must match byte-for-byte); and the reserved surface for real attributes in a later version, so the convention promotes without a rewrite. Current tenant: #[de: …], parking a quote’s translation until quotes get a real translation field.

Labels and glosses

Three slots, three different jobs (tut 6):

  1. Statement label = the claim itself, a proposition, may be a full sentence. Not length-linted.
  2. Evidence label = the step, in one plain clause, premise to conclusion, naming its subject: “a tiny target and imprecise training make alignment hard” (tut 6 item 2, sharpened 2026-09-25: the layout shows a line before its premises, so the label is read first and cold). Never the warrant alone as a fragment, never a bare “it”, never a figure unless it is the source’s own image and the gloss unpacks it, never a premise’s label said again. Every strengthed line gets one (an unlabelled line shows its gloss’s first sentence, written as depth). Objection lines in the objector’s voice, responses in the answer’s, a battery’s voice marker kept (“the hope: …”). Crops at ~56 chars in the graph (W5) and must fit its plate at its size tier (label-crop.test.ts): where a plain clause cannot fit, keep the subject and the verb and let the gloss carry the rest.
  3. Gloss = the depth tier: full reasoning, qualifications, source voice, quotes. Never length-linted.

The three-job test for gloss text: content is either (a) a role tag (“undercut of …”), derivable from topology, so delete it; (b) the warrant, which belongs in the label; or (c) format-meta commentary, which belongs in a # comment. What survives is the genuine depth tier. Put the substantive point first even inside a gloss: displays crop from the end.

Three conventions worth keeping: plain-first, technical-nested (write the gloss plainly, move a technical restatement to a folded continuation line starting “technical reading: …”); rubric provenance is not reader content (elicitation citations like “R-STEP S2: …” go in a trailing # comment, not the gloss, while reader-valuable quotes and footnote refs stay); and in multi-speaker maps prefix evidence labels with a speaker tag (“A:”, “L:”), because IDs are invisible at graph junctions.

Numbers (D36, five rules)

  1. Elicit strength as: assume the premises; how likely is the conclusion? It is a property of the rule; premise truth lives elsewhere. Do not discount a strength because you doubt the premises. The given bar is directional. Contraposition is a different claim, so preserve the direction the source asserts.
  2. ? on every rubric-derived value; bare numbers only where the source states a number. Fix the verbal->probability rubric BEFORE assigning; never move a number after the first solve. The table follows the SOURCE’s register, not the speaker’s: a transcript takes the spoken table (R-SPOKEN), a written column the written one (D39), even when one speaker has both on one map, and the notes entry says per line which table was used (a column reads uniformly flat: expect every line at the unhedged class).
  3. Residual rule: frontier roots keep authored values; derived statements get # check: p trailing comments, never pins, because authoring both the support and the conclusion double-counts. Never both on one line: a pin + check pair on a concluded-into statement fights your own counter-evidence and contradicts itself, and the lint flags a head line carrying a bare point and a check as W23, and a bare point beside any strengthed incoming line as W25. An explicit residual pair beside a check (0.6?/0? with # check: 0.9) is the intended shape and draws nothing. This holds inside refinements too: a hinge with internal incoming lines takes a check; if the source also asserts it directly, add a premise-less attributed evidence at that register (the direct-assertion pattern), not a pin. The keeper sentence: a statement’s own indented block explicates its number; sibling lines concluding into it replace it. Syntax of the check comment: it must sit on the node’s head line. On a folded continuation line it is silently ignored, with no diagnostic and a — where the readout would show it. It may carry ? and be followed by prose (# check: 0.95? (A2: restated)); the reader stops at the number. In a source-faithful map the ? belongs there, because the check is the source’s register, not your belief. A check may be an interval, # check: 0.85..0.95: the range the register licenses, at the residual pairs’ widths; the badge is the distance from the computed value to it, zero inside, and a bare point is the zero-width interval. Malformed tokens (reversed, past 1, one dot) draw W26.
  4. No authored 0/1 marginals: since D161 a point is held at the cap (198 flips, no firmer than 0.97 is), so a 0 or 1 no longer deletes worlds, but it still claims a certainty the source rarely states; write 0.97 or a pair. Strength 1 is fine for deduction, strength 0 means “drop the number” (W11).
  5. Unstrengthed lines are legal structure-only sketches; commit numbers later.

Kinds (tut 3.7, 4.1; D161, the table as of 2026-09-08). Every strengthed evidence line carries a # kind: <word> trailing-comment key naming what sort of step it is, read off the source’s own words: formal (logic, definition, arithmetic, a checked derivation, a universal instantiation; hard, or simply write the step at 1), deductive (the source’s own claim that the conclusion follows: “by definition”, “necessarily”, “it follows”; 1000 flips, five times the point cap’s 198, firmer than any statement a point can be and softer than a formal step, because the authors can be wrong about their own logic), mechanism (a causal or structural reason that would operate whenever the premises hold: “because”, “the process”, “would tend to”; 64), empirical (a frequency or record: “historically”, a named count, a study; 16, or a larger stated sample kind: empirical n=200, which raises the count and never lowers it), testimony (a stated judgment: “we think”, “experts”; 16), analogy (“like”, “as with”; 4), hope (a labelled hope or guess: “perhaps”, “one might hope”; 4). The key sets how firmly the solve holds the line under a reader’s what-if, never its strength; a line without it compiles at 16, and the solve reads four counted tiers (1000, 64, 16, 4) and the hard one, so empirical against testimony or analogy against hope moves no number. Boundary: deductive only where the line’s own words claim necessity, definition or elimination; a reason that would fail if the world were arranged otherwise is mechanism, however confidently stated. An undercut takes the kind of its own step, not of the line it attacks. The key may share a comment with other keys (# check: 0.9?; kind: mechanism) and ports 1:1 into translations (TRANSLATION_NOTES L16). Measured 2026-09-08 (tut 4.1): as authored the flagship’s 348 keys move one statement past 0.05; under a reader’s what-if (the confusions map’s c4 syllogism re-keyed deductive, “not mortal” at 0, solve_map.py --override at the default reference, re-measured 2026-09-08) a deductive step beside two point premises gives 0.06 (0.99 to 0.93) where each premise gives 0.30 (0.99 to 0.69) and the reader’s 0 is held at 0.30; as keyed (formal) the step holds at 0.99, each premise gives 0.32 and the reader’s 0 is held at 0.32.

Four consequences that trip authors (tut 4.2, 4.4, 4.5):

  1. An unpriced ground reads one half. Asserting $imp 0.8 @c | @a alone leaves solved P(@a) at 0.500 (and P(@c) at 0.700), the network’s fill for a claim nothing speaks to; a premise on the negated side, @c | ~@a, stays at 0.500 too. The checkers name such a statement I7. The 0.5 is a placeholder, so price the ground: author a value on a frontier root; give a premise the source asserts as a claim of its own an attributed premise-less line at its register (idiom 13); or fold a premise that was only ever part of the step into the line and re-elicit the line’s strength. A converse the source asserts (~@c | ~@a, idiom 7) is content about the conclusion: it fills the worlds where the premise fails, moves @c and leaves @a where it was. A premise moves on information about what follows from it, and each move is the map’s own inference, to be left standing: a confirmed consequence raises it (@c pinned 0.9 beside the lone line: @a 0.593), a refuted one lowers it, and a support and an objection on the same premise that sum past one make their shared case rarer (0.8 against 0.3: @a 0.466; 0.8 against 0.15, which fit: 0.500). Measured 2026-09-24 with solve_map.py at its default (examples/toys/a10-t2.argmap; tut 4.2). Until 2026-09-08 this item was the drift tax of the retired uniform reference (the lone line dragged @a to 0.365, the negated premise pushed it to 0.651), which the shipped solve does not have.
  2. Independence is assumed: separate lines accumulate noisy-OR, so convergent lines with overlapping grounds double-count. Three repairs in increasing order of structure: merge into one evidence; name the shared source as a statement and condition both on it; or partition with AND ~@other-route. Applies only to lines converging on the same conclusion. One statement feeding several different conclusions needs no declaration. The converse holds too: once the conclusion is known, independent reasons for it become dependent (explaining away, tut 4.4; examples/toys/f-explaining-away.argmap: with the effect observed both causes read 0.57, observe one and the other drops to 0.51, network reference, 2026-09-08). Expect it in what-if mode; nothing needs authoring around it. Opposite sides are read together (D166, since 2026-09-23; tut 4.4): a line for a statement and a line against it that apply to the same case are one draw. They never fire together, each keeps its share, and independence is what gives where the numbers do not fit. A granted objection caps the supports in its case however many there are (five 0.9 supports beside a 0.15 objection read 0.90 there, 1.00 under the evidence weighing it replaced); to move it, undercut it, lower it, or doubt its grounds. Where the strongest support and the strongest objection sum past one, the overlap is a contradiction that makes the case rarer, pressing on its grounds. If the two lines are really about different cases, name the statement that separates them.
  3. Stacking to ~0.99 is not automatically an error. Four genuinely independent 0.85 routes compound past 0.99; if the source really asserts four sufficient reasons, that is its own logic, and a lower # check: on the hub turns the difference into a visible audit finding. First check for an unnamed shared latent (repair 2), since several “distinct” failure modes of one mechanism usually have one.
  4. An undercut does NOT push its own conclusion. Its strength is “granted the grounds, how often does the target inference fail?” Do not pre-discount it because a response exists (author the response as an undercut of the undercut). But an undercut-shaped line compiles as a pure inhibitor of its target: it carries no floor of its own (SOLVER_SEMANTICS §1.2, the factored-A compile), so the negated conclusion it names gets no independent push from it. Two measured consequences (tut 4.5, the shipped solve, 2026-09-24): an undercut whose target is unstrengthed moves nothing at all (0.500 → 0.500); and an answer to an objection (an undercut of the rebuttal) reinstates the claim only toward the value it would have with the objection absent, never past it (0.823 → 0.852 against an objection-free 0.859; examples/toys/u-grounds.argmap ::guard-sup). Without a support the answer lifts the claim only back toward 0.5 (the objection alone 0.450, answered 0.488, ::guard). The authoring consequence, and it is easy to miss: when the source also asserts the fact the objection rests on, and you want that fact to bear on the conclusion, the undercut cannot carry it. Author the fact as an ordinary evidence line beside the undercut. The two do not double-count: the inhibitor acts on the inference, the plain line acts on the claim. The same holds for an answer’s ground: as its own line beside a guardless answer it brings the claim to 0.879, inside the answer’s guard 0.488 (u-grounds, ::split against ::guard). Which objections are undercuts (D170, 2026-09-28): ask what is true instead if the objection is right. “The step is unreliable” is an undercut; “claim X is false” is a line into ~X (the map’s inverse lines carry a win onward), with the answers that deny its inference kept as undercuts. Flagship: $uc-experts stays an undercut; $uc-precedented and $c12dr-obj are lines against @mis-ext (won outright, the title claim falls to 0.10; as an undercut the second left it at 0.37).
  5. Coming from probabilistic conditional logic (tut 3.6; measured on examples/toys/pcl-penguin.argmap, 2026-08-31, re-measured under the shipped solve 2026-09-24): (psi|phi)[d] with d >= 0.5 is $e d psi | phi; with d < 0.5 it is the opposed line $e (1-d) ~psi | phi, never a d-strength support (a 0.01 support is near-inert, and penguins fly at 0.95). A subclass exception is an undercut of the general rule on the subclass PLUS a rebuttal: a low conditional beside the general rule is a contradiction under the law reading (hard-infeasible once the subclass is pinned), the undercut alone leaves even odds, undercut plus rebuttal reads the textbook value. A conditional at the base rate (an independence statement) has no line form; leave it out and pin what it protects if the pull is real (W25 flags the attempt).

Epistemic delicacies (D152, compressed; tut 4.7)

The rules that keep a lint-clean map from counting one consideration twice. Each has a five-line toy behind it in examples/toys/ with its measured numbers (the toys README carries them under the shipped solve).

  1. Residual rule. A statement’s own number is evidence NOT already in the map. A frontier root (no strengthed incoming line) keeps its number whole. An interior statement may carry a number only for the unargued remainder (its tacit grounds); its total goes in the check.
  2. Three slots. Point @s 0.9? = the zero-width pair 0.9?/0.1?, held at the point cap since D161 (silent mass 0.01, 198 flips; the cap sets the firmness only, the target stays at the point). Pair @s 0.6?/0? = direct evidence, P(s) in [0.6, 1]; the map’s inference selects within it and never counts against it, and the width is the firmness (silent mass m holds 2 (1 - m) / m flips: 0.6?/0? 3, 0.7/0.1 8, 0.85?/0.05? 18). Check # check: 0.85..0.95 = the author’s total as an interval at the register’s width; never constrains; the badge is the distance from the solved value to the interval, zero inside. The toy numbers (tut 4.7.2, the shipped solve, re-measured 2026-09-24): as authored the three read alike, T1 (pin beside $sub-ev, W25) @subvert 0.900 / @resists 0.883, T2 (derived, # check: 0.9) 0.905 / 0.884 with the check met, T3 (0.6?/0? + check) 0.896 / 0.881, silent. The double count shows under the what-if (--override want=0.1): T2 follows its premise (@subvert 0.545, the badge at -0.36), T1 does not move (0.899: the pin is deaf to its own premise), T3 gives part way (0.840); T3 is right when 0.6 is the remainder, the pin again when read off the total.
  3. Derive a root = give a pinned root its first strengthed incoming line. One test: does the line carry an INFERENCE? A restatement or co-reference at a second dock (@psychosis / @c13ws-retrain) gets a comment, never a line. Source faithfulness is no part of the test (a real inference the source omits is mapped, with a comment). Never withhold a derivation for what it does downstream: completion is always licensed, and the movement is the audit working (@steering-finds-subversion 0.899 to 0.843 and @incorrigible 0.856 to 0.834 on the flagship under the shipped solve, 2026-09-24; 0.893 to 0.628 under the retired reference, tut 4.7.3). Then the obligation: the old point becomes the check at its register’s interval, and the residual stays EMPTY unless the text names a second unwired ground (floor at that ground’s register, gloss naming the passage) or says the grounds are a subset (“to name a few”: remainder 0.2?/0?, quote in the gloss). Grep the map for the root’s id first; the reason it was left unwired is usually in a comment that now has to be rewritten.
  4. Register to pair table (AUTHORING_NOTES 2026-08-23). Centred: midpoint = the rubric point, width fixed per register (0.05 strongest categorical, 0.10 flat assertion, 0.20 “by default” / “best guess”, 0.30 “we expect” / “could well”, 0.40 weakest hedge, 0.80 refusal). Rows: C1 0.97 0.95?/0?; N1/N3 0.93 0.9?/0? (one-sided: the midpoint above the point is the balancing prior’s reading); C2 0.93 0.88?/0.02?; C7 / P-FACT 0.90 0.85?/0.05?; C3 0.85 0.75?/0.05?; 0.80 0.7?/0.1?; C4 / P-GRANT 0.75 0.6?/0.1?; C5 0.70 0.55?/0.15?; RS6 0.60 0.4?/0.2?; role defaults 0.8/0.7/0.6 0.65?/0.05? / 0.55?/0.15? / 0.45?/0.25?; COIN (explicit refusal) 0.1?/0.1? + a gloss sentence (“the page calls the question open; the wide pair carries that, and its midpoint is nobody’s belief”); P-CONTEST = the MIRROR of the denied class’s pair (0.05?/0.85? for a flat denial), never 0/p. Per-node asymmetric pairs only where the passage states both directions, written from the text with the rationale in the trailing comment. ? on every member, zeros included; a gloss sentence whenever total width > 0.30; the class token in the trailing comment. Proviso, stated: a register read is a posterior, and reading it as direct evidence lets modus tollens run twice; known, small (<= 0.043 per statement), compensated by showing the interval and the band. Since D161 the width is also the count (Walley, s = 2): width 0.05 is 38 flips, 0.10 is 18, 0.20 is 8, 0.30 is 4.7, 0.40 is 3, the refusal’s 0.80 is 0.5, a point 198; the flagship’s median pin is 18, below a mechanism line’s 64, so under a reader’s what-if the authors’ assertions give before their mechanisms.
  5. Shared considerations. Lines combine as independent; the ONLY way to say two lines co-vary is a shared statement both cite. Name the overlap as a statement and condition both lines on it. Fingerprint: the AND consumer RISES and the OR consumer FALLS when premises share a cause (T8b vs T8: @both 0.799 to 0.818, @either 0.935 to 0.915; T5 vs T5b: @danger 0.866 to 0.876; the shipped solve, re-measured 2026-09-24; tut 4.7.5 keeps the retired reference’s figures beside them). argmap-query shared-cause lists the rows. Never AND a statement with its own derivative ($wst-race, @race-dynamics AND @one-cavalier-suffices where $ocs-ev derives the second from the first): drop the duplicate premise or re-elicit conditionally. Trace each premise’s ancestry before writing an AND.
  6. Definitional vs substantive. A node bundling a definition with a claim is two variables in one slot: split it, or derive from both halves (one line per ground). A definition that does inferential work is a p = 1 evidence line (a biconditional is two, spelled as the converse pair 1 @want | @a AND @b plus 1 ~@want | ~@a OR ~@b, T6: @want 0.763 = P(steers AND routes), lint-silent; the forward/backward spelling draws W2, W25 and now E11 for nothing), never a p = 1 statement: @asi-def [..] 1 conjoined into a premise draws an edge into every junction it joins and says nothing a gloss would not (T7: under the shipped solve it holds at 1.000 and @dies reads 0.859 with it and without it, so the rule stands on the clutter alone; the 1/w tax it once carried, 0.849 against 0.854, was the retired reference’s; re-measured 2026-09-24). Terminology goes in a gloss.

Structural idioms

The patterns that carry the flagship map (experiments/llm-extraction/iabied-comprehensive-en.argmap; each entry names an anchor to grep for). Full prose in tut 7; whole readable files in examples/ (see its README).

  1. Objection/response triple (tut 7.1, anchor @c11-readthoughts). The workhorse; FAQ-shaped sources map one row each. An objection statement, an objection evidence concluding against the target, and a response undercutting that evidence: @hope 0.15?: / $hope-obj 0.2? ~@target | @hope: / $hope-resp [why the hope fails] 0.85? @target | @ground AND $hope-obj:. The -obj/-resp suffixes are a mnemonic convention, not syntax. Each line takes its own kind: the objection’s is usually hope or testimony, the response’s mechanism, deductive or analogy; an undercut never inherits the kind of the line it attacks.
  2. Undercut ladder (tut 7.2, anchor $uc-counting): rebuttal, undercut, response and undercut-of-undercut are one schema applied repeatedly. $uc-uc q @claim | @grounds AND $uc reinstates @claim exactly to the extent the rescue in $uc fails.
  3. Linked vs convergent, side by side (tut 7.3, anchor $fragile-ev). Write $a 0.9? @hub | @x AND @y AND @z beside $b 0.7? @hub | @w. Test for linked: neither conjunct alone suffices (“neither end alone shows disagreement; together they are the spread”).
  4. Convergent siblings instead of a false AND (tut 7.4, anchor $adv-speed-ev). When the source says “any one of these suffices”, write separate evidences on the same conclusion, never one conjunction. The flagship had this wrong as a four-way AND; the repair note is still in the file.
  5. Coarse summary + refinement (tut 7.5, anchor $link , grepped with the trailing space): one coarse line whose indented block holds the whole sub-argument. The coarse strength is not a solver input (the refinement replaces it); it is the evidence-side check. Author it as your holistic judgment before trusting the steps, and the comparison is a free audit. Special case, the coarse hull: when a region’s linking evidence mixes one cross-region premise with region-local hubs, write the coarse line conditioning on just the cross-region premise ($takeover-ev @takeover-doom | @unaligned-asi in the He map) and put the fine conjunction plus the local clusters in the refinement: the spine edge survives folding, because a refinement folds to its visible coarse line where a statement block folds to nothing (spine test). Pick the coarse strength at or below the weakest step you are about to write under it. The folded line reads the composition of its block, and required steps multiply: four steps at 0.9 show about 0.65 on the fold, and the refinement pays again for every interior ground the coarse line does not carry. A chain can never come out above its weakest step, whatever you believe about how the steps hang together, so a summary firmer than any step belongs in a # check: on the conclusion with the line’s strength at or below the weakest step. If the source gives several grounds and you wired them as one chain, write them convergent instead (idiom 4) and the fold saturates. The mirror case: a family of parallel objections that all fail for one reason should take that reason as a premise in every member (idiom 9), or the family ORs upward, and judge that repair by the conclusion’s own value, since a conjunct repeating the coarse line’s own premise cannot move the fold. Check with argmap-query fold-audit, which lists every folded line with its weakest required step and flags the ones above it (advisory).
  6. Complementary partition, “even if” (tut 7.6, anchor $mwb-time). Make two overlapping routes disjoint by conjoining the negation of the other: $r2 0.9? @c | @route2-ground AND ~@route1-ground. That ~ conjunct is the source’s own “even if X were false”.
  7. Balancing evidence (tut 7.7, anchor $no-doom-otherwise): a conditional says nothing outside its slab. If the source asserts the converse, name it: $conv 0.9? ~@c | ~@a. It fills the worlds where the premise fails, so it moves the conclusion and leaves the premise alone, and it keeps a contested claim on the map instead of hiding it in a prior. Close the set on a spine line (D168): each premise of a conjunctive line into a claim the map leads with gets its inverse where one holds, by the meaning of the two claims (formal, 0.99, e.g. ~@c | @p1 AND ~@p2, the @p1 conjunct keeping it strictly by meaning) or in the source’s own words (its rubric row and kind); where neither holds, invent none and let the band show the fill. The reader’s likeliest drag finds the shape: zero a premise, and a conclusion near 0.5 is the fill (the flagship’s title claim read 0.427 under the misalignment drag and 0.708 at rest before its two inverses, 0.044 and 0.617 after; 2026-09-27; 0.603 at rest since 2026-09-28, D170).
  8. Conditioning on an inference (tut 7.8, anchor $shutdown-ev), a policy that hangs on an implication, not on a fact: $policy 0.93? @should-act | $link. Conditioning on the implication’s conclusion would be subtly wrong (unconditional doom would justify no ban). The rare positive evidence-as-premise; lint fires W1 by design, so say so in a comment.
  9. Shared latent conjunct (tut 7.9, anchor $hope-care; the latent is ~@no-right-care). When k objections express one underlying doubt, name the doubt as a statement and conjoin it into every member, eliciting its prior once, family-holistically. Prefer as the latent the statement the support side already denies, so attack and support quantify over the same worlds. The only structure of six probed that stayed stable as hopes were added.
  10. Epistemic-fact reification (tut 7.10, anchor @risk-unbounded; wrong shapes in examples/edge-cases/e15-reified-chance.argmap): the solver cannot represent facts about credences, so reify the evidence-state as a first-order statement, state the norm as its own statement, and combine near-deductively:
    # fragment - not standalone
    @risk-unbounded [No one can bound the risk below the threshold]: about what has been demonstrated, not about anyone's opinion
    @no-gamble [Running an unbounded risk is impermissible] 0.93?: the norm, stated where it can be attacked
    $fine 0.9? @policy | @risk-unbounded AND @no-gamble:
    $escape 0.9? ~@policy | ~@risk-unbounded:
    

    $escape is the author naming the condition under which their own conclusion lapses, which is honest and persuasive.

  11. Rebuttal guards (tut 7.11, comment anchor risk-conditional rebuttal guards). Ask of every response: which epistemic state does this defeat presuppose? If it only works while X is undemonstrated, conjoin the statement saying so, and the defeat lapses (objection revives) in the worlds where X is demonstrated. Structure only, no new numbers. Seven flagship responses carry it.
  12. Exclusive alternatives + authored abduction (tut 7.12, examples/09-exclusive-causes.argmap): $who 1.0 @alice OR @bob | @cake: (the abductive step, stated as a contestable rule) plus $notboth 1.0 ~@alice OR ~@bob: (premise-less constraint). Abduction is authored, not free: pinning the effect gives the causes no diagnostic lift by itself.
  13. Direct assertion (tut 7.13, experiments/llm-extraction/debate-tang-shapira.argmap). A flat spoken claim with no stated grounds becomes an attributed premise-less evidence: $a-blur [A: attention is a blur] 0.9? @opaque: "…" [^t005008]. Sixteen of these carried the debate map. A refusal to give a number needs no syntax: leave the marginal blank, and if the refusal is itself argued, map that as an undercut cluster against assignability. How several premise-less lines on one statement combine is decided (D166 item 4: a line with no premise is a line whose premise is every case, so same-side lines stack where nothing opposes them) and applied after the release; until then the solve pools them, and the lint’s I4 note on each says so. A line reporting one source names the source as a premise instead.
  14. The parable at zero depth (tut 7.14, anchor a parable): narrative goes in folded gloss continuation lines, not in nodes. A whole illustrative story attaches under one statement, costs no graph structure, and folds away. Use it for the source’s most persuasive prose, which is usually exactly what does not decompose into premises.

Nesting and large maps

First drafts come out flat, and the clusters are usually already visible as # section-heading comments. Section headings are nesting debt: a divider organizes the text file, only indentation organizes the reader’s view. Three tests turn debt into structure (tut 8):

  1. Fold-unit test: would a reader want this sub-debate collapsed to one line? Give it a wrapper evidence whose refinement holds the cluster (idiom 5), and author the wrapper’s coarse strength as your holistic judgment of the cluster’s net force.
  2. Burial test. Anything referenced from outside the cluster moves up out of it. A shared ground homed inside one cluster renders as a cross-reference burial and, worst case, a stranded node (W6, validator-only). Home shared nodes above every cluster that uses them, and annotate each reuse site with a comment naming its home region.
  3. Spine test. The collapsed view must already show the argument’s shape: a folded evidence contributes no edges, so a buried spine disappears from it (W21, which names the linking evidences to lift). But do not over-correct into lifting every sub-conclusion: that trades a wall of disconnected cards for a crowded one. Pick the top TIER deliberately and keep it coarse: headline, sinks, route hubs, and the shared grounds the burial test already forces up (~15-30 cards on a large map); every single-region statement hub lives one fold down. “Nest clusters under their target” covers a cluster’s INTERNAL traffic (grounds, caveats, objection pairs). The mechanics rest on a folding asymmetry: a STATEMENT block folds to nothing, an EVIDENCE refinement folds to a visible coarse line, edges intact. So an edge between two top-level statements never sinks into a statement block; it stays a top-level evidence (all premises top-level), or becomes a coarse hull (idiom 5) conditioning on just its cross-region premise, fine conjunction and local clusters in the refinement, solve on the fine line (D38). Quick checks: grep -c '^\$' = 0 on a multi-statement map means no spine at all (W21); a top rank past ~40 cards means the tier is set too fine. If the source draws its own overview (a section-2 diagram, an abstract’s roadmap), the flat projection should BE that overview; a free-standing exhibit node or two beside a visible spine is fine (W21 stays silent then).

When all three fail and the heading is still real, the section is a topic, not a fold unit, and that is a declared group (::), not debt.

For maps past ~150 nodes: width, not depth (every new objection cluster is a sibling under its target, never a deeper chain; when a sub-debate wants an eighth level, promote the deep node to a shared top-level node, so node count can triple while max depth stays flat; width is for distinct considerations: a sibling line that restates one the map already carries is a second dock and counts it twice, so give its passage a second > quote on the existing line, checklist item 18); a manifest comment block at the top with the coarse spine in ASCII, every shared node listed with its home region and consumers, and the region-prefix scheme stated (@c5-trade, $c5-trade-obj, $c5-trade-resp); build in dependency order and lint after every region. Smell figure: the flagship holds 431 nodes at depth 5. A hundred-node map at depth 1 is under-nested even if every line is well-formed. Its reader meets a wall of top-level nodes and the fold control does nothing.

Workflow

  1. Skeleton: structure only, no numbers - three sub-passes (tut 5.1), because the directions fail differently (top-down invents hubs the source never asserted, which solve near-tautologous; bottom-up buries the spine, W21, and double-counts shared grounds, gotcha 2): (a) SPINE top-down, transcribed from the source’s own overview (a section-2 diagram, an abstract, a title conditional): top tier, focus:, region list + prefix scheme, the manifest comment. Genre flip: a debate asserts no overview up front - go bottom-up first and write the spine after the meta-shape emerges (the wrap-up); never fake a spine the source did not assert. (b) REGIONS bottom-up, in source order, each step citing its sentence: statement granularity (a label must be a proposition; meta-principles and framing stay glosses, not conjuncts), linked vs convergent (test in idiom 3), and per objection: which inference does this grant, and which does it deny? (undercut vs rebuttal, the most common first-pass error). Nest a cluster’s internal traffic under its target. (c) RECONCILE: promote shared grounds discovered in (b) to the home the burial test picks (the nearest container covering every consumer, not blindly the document top); merge or partition overlapping lines; set the tier by the source’s own disclosure order
    • headline, sinks, route hubs and burial-forced shared grounds on top, single-region hubs one fold down, cross-tier edges as top-level evidences or coarse hulls, never sunk in a statement block (spine test, W21). Then lint, and nest-audit for missed fold candidates.
  2. Elicit blind by rubric. Fix the rubric before assigning anything: keep two tables, one for statement registers and one for inference-step language, plus role defaults for where the source is silent (an unhedged asserted step, an objection raised to deflect, …). You will need them. Convention: the rubric lives in a comment block immediately after the frontmatter. When hedges stack the outermost governs; when two readings are defensible author the weaker and log both, and likewise when the source asserts one proposition at two registers. A stated rate (“one accident per twenty million hours”) is not a stated credence. Keep it in the gloss and derive from the assertion’s register. In a source-faithful map a # check: carries the source’s own register for that conclusion, ? and all.
  3. Review checklist: provenance traced; undercut targets typed; overlaps merged / shared-source factored / partitioned (AND ~@other-route) or declared independent in a comment; no dangling sub-conclusions (every non-headline statement feeds some evidence, though the headline itself is the one sink and is exempt); nesting present AND the spine surfaced at a coarse tier (top-level evidences exist, W21 silent, top rank not a crowd; see the spine test’s bounds); full-source coverage (summarizing from memory under-extracts); defeat presuppositions guarded (idiom 11); multi-voice overlaps deduplicated (full concurrence = one line at the weaker register; a subset relation = shared span plus a residual increment; an instance supports the shared ground, not the downstream conclusion; a joint line QUOTES both speakers saying the sentence, so if its gloss has to argue that one of them concurs, he has not, and a grant is joint only when the granted sentence is also the other speaker’s own words; read a quote to its full stop before it carries anything); on a multi-voice map, a speaker’s SPOKEN refusal to price a claim is a > quote line of theirs on that statement plus the claim under their key in the frontmatter’s declines: block (a: everyone-dies [^t012346], D164), so their view shows the refusal where a number would stand. Never use it for a claim merely left unpriced: without the quote the entry is rejected. A later DATED source for a speaker already on the map (a column after a transcript) is a new speaker key that updates: the old one in the frontmatter (updates: then ` s: a; the September view keeps the January lines), its lines and quotes prefixed with the new key's letter; a proposition asserted at both dates is ONE factor (a restatement is a prefixed quote line under the existing line, a new joint proposition a `-keyed line, never a second factor), and absence in the later source is not retraction (AUTHORING_NOTES 2026-09-18). After the skeleton and after any restructuring pass, run `argmap-query nest-audit` (add `--rank` for the fold-as-detail vs coarse-hull call): it sizes the top tier against its genre (the ~40 bound is per group on an atlas map, per tier on a spine map), names the boxes whose opened view is a wide and deep wall, and lists cones ready to fold with the edges that block them, counting each cone by what still stands at the statement's own tier. Advice, not a check; declining a proposed fold is a normal outcome.
  4. Mechanical smoke: lint, parse (editor), solve (below).

Quoting discipline: verbatim spans of at most one sentence (~25 words), normally one per node; never alter a quote silently; never reproduce a self-contained creative unit (a parable, a poem) whole, but retell and compress. Whole-map budget from one work: low hundreds of words, and proportionally less for a short source. Where the span goes is the three-way test above: supporting quotes become > lines with a [^locator]; a fragment that is grammatically part of the gloss sentence stays inline in plain double quotes, optionally echoed by a > line. The budget counts both.

Gotchas

  1. Undercut schema is exactly $u q ~C | grounds AND $target; dropping the AND $target silently makes it a rebuttal.
  2. Convergent lines must not share grounds (independence is assumed); merge, name the shared source, or partition.
  3. AND only if no conjunct alone suffices; overdetermined routes are separate convergent lines.
  4. A sigil forgotten on a node line silently becomes gloss text, so heed lint W3. The inverse has no diagnostic and cannot get one: a gloss continuation line that begins @, $, #, :: or > is consumed as that construct, because dispatch is a first-character switch and by then the parser has built a node with no idea prose was meant. Never start a continuation line with a sigil character. Begin with a word. (Quote lines cannot wrap, which is what keeps the exposure small.) A whitespace-preceded # inside a gloss starts a comment, and the split is silent: …memory cell #2 is protected parses as gloss …memory cell plus trailing comment 2 is protected, losing the rest of the sentence from the display with no diagnostic. The escape is to delete the space: cell#2 stays in the gloss whole. Reword or close the gap; never leave ` #` inside prose you meant to keep.
  5. A premise no line concludes and no value prices reads one half, the network’s placeholder, left for its consumers to settle (I7): price it (a value on a root, an attributed floor line) or fold it into the line that uses it. It is not dragged anywhere; the drift tax that used to sit here was the retired reference’s (consequence 1).
  6. A near-tautology premise (e.g. the OR of four of five partition members) is harmless: the shipped solve holds a line’s rate once, on its own coin (a 0.8 line on a premise pinned 0.98 reads 0.800, no tension). The spurious tension this gotcha used to warn of was the retired reference’s row on the nearly empty side (0.079 off; tut 4.1 item 5, measured 2026-09-24).
  7. # section-heading comments are nesting debt (see above); the exception is a topic, which is a declared group.

Pitfalls checklist (adversarial audit; tut 10.4)

Work it against the finished map. Per item: what / how to see it / fix. Lint = python3 tools/argmap-lint.py FILE; audits = node mvp/packages/parser/bin/argmap-query.mjs FILE <audit> (advisory).

  1. Pin beside mapped support (T1) / W25 / derive: number to # check: at its register’s interval, or the remainder as a pair.
  2. Pin + check on one head line / W23 / drop the point (interior) or the check (root), or write the remainder as a pair beside the check.
  3. Pinned root homed in a box it does not feed / isolate-audit / derive from the container (inference test), re-home, or say why.
  4. Restatement wired as inference (@psychosis shape) / restate-audit
    • the reading “does the passage make this step?” / delete the line, cross-reference in a comment, or merge the docks.
  5. Two lines sharing a premise into one conclusion / shared-cause / the deliberate shared conjunct (comment it), or factor out, or merge.
  6. A statement AND-ed with its own derivative ($wst-race) / the reading: trace each AND premise two hops up (neighbors ID --hops 2); covariance_probe.py at scale / drop the duplicate premise or re-elicit on the derivative alone.
  7. A floor elicited from the total (T3’s hazard) / the reading: a pair beside a check is lint-silent, so a floor that would close the badge alone, or one with no passage in the gloss, is the total / empty the residual unless the text names a second unwired ground or a remainder (0.2?/0?).
  8. A posterior elicited as direct evidence / the reading: a root hedged because of a conclusion the map derives from it / no exact fix; keep the widths, note it in the trailing comment, show interval and band.
  9. A definition as a p = 1 statement (T7, 1/w per junction) / grep ` 1: and 1?:`, lint silent / gloss or glossary; definitional claims as p = 1 lines, the converse pair (T6).
  10. Malformed check interval / W26 / a point in [0, 1] or lo..hi.
  11. Unstrengthed line left as structure / I3 / commit a strength by rubric or delete the line.
  12. Label whose pronoun has no antecedent (@before-after-gap, “It must hold …”) / read every label cold and out of order / put the subject in the label.
  13. Bundled label (“X and Y”, “X, so dismiss Y”) / grep labels for ` and , so , therefore`; could the halves be true separately? / one proposition per statement, or derive the fused claim from its halves.
  14. A refusal written as a number / a pair wider than 0.30 with no gloss sentence, or a 0.5 with none / 0.1?/0.1? + the gloss sentence, or a blank marginal.
  15. A pair whose shape contradicts its register / compare with the table (item 4 above) and the class token; a pin with no token is unaudited / the table’s row, or a per-node pair from the text with rationale.
  16. A restatement under two labels, and the wrong door (the flagship’s @asi-soon -> @if-built until 2026-09-25: one event, two labels, the source’s reason in the gloss and not the premises, so a what-if on the premise left the conclusion at the 50% fill; and @int-power reaching the title only through that line) / restate-audit only where docks share a locator; otherwise the drag: zero each hub’s premise (solve_map.py --override), a landing near 0.5 is the shape; consumers for the single-consumer orphan; inverse-audit --all for the check-priced hubs with no inverse / one proposition per label, the source’s reason as the premises, the orphan wired where the source uses it, the analytic inverse where one holds by meaning (~@if-built | ~@asi-soon, deductive). AUTHORING_NOTES 2026-09-25.
  17. An evidence label that is not the step (no label; a warrant fragment; a figure the gloss does not unpack; the premise’s label said again) / read every strengthed line’s label sorted, away from its premises: grep -oE '^\s*\$[A-Za-z0-9_-]+ (\[[^]]*\] )?[0-9.]+\??' FILE | sed -E 's/^\s+//' | sort -t'[' -k2 (bare rows sort first); does each name its subject and say which conclusion the premises give? / one plain clause, premise to conclusion, the objector’s voice on an objection line. Parallel lines into one claim need different words, or cook-audit’s label overlap (0.75 and up) flags them as duplicates. AUTHORING_NOTES 2026-09-25, the label pass.
  18. One consideration at two docks ($ext-core beside $ext-incidental into @mis-ext, a rule beside its instance, one answer given in two paragraphs, a premise restating its conclusion; the flagship until 2026-09-25): same-side lines stack where nothing opposes them, so the second dock counts it twice / the reading, triggered by every shared-cause row (read the pair against the source: one answer?); disjoint-premise pairs show on no instrument, so read each multi-line conclusion’s lines side by side / one consideration, one dock: a second passage becomes a second > quote on the same line, never a second line; a rule feeding an instance becomes one statement with its own box; one answer at two docks becomes one line (AND, or OR where either suffices); a line at the wrong door is re-aimed; never nest the fix inside an evidence. AUTHORING_NOTES 2026-09-25, the cleanup.

Order: lint, the five audits (isolate-audit, restate-audit, shared-cause, cook-audit, pinned-roots) plus inverse-audit --all, then the reading half over the pinned-roots rows (items 3, 7, 8, 14, 15 live there), the drag over the hubs (item 16), the sorted label listing (item 17) and every multi-line conclusion read side by side, from the shared-cause rows first (item 18).

Limitations

Known dead ends, with the standing workaround; none block parsing or display, they bound what a solve can mean (tut 9):

  1. Scope conditionals (“aligned now, degrades at superhuman scale”) have no first-class form; nesting is a partial workaround, statement granularity is your burden.
  2. Undercut fan-out: an undercut names one target, so class-level objections (“this is all unfalsifiable”) are under-stated. Give the family a shared gate premise and rebut that once, or make the objection a shared ground feeding several undercuts.
  3. No statement re-opening (D33): refinement is physical indentation, so declare nodes at their refinement site and forward-reference them (IDs are document-global).
  4. Binary statements only: categorical or continuous claims enter through threshold-gate statements (“X exceeds T”).
  5. Credal links are second-order: nothing computes “if P(X) > t then Y”, so use idiom 10 plus a # gate: q($e) >= t => @c comment audit.
  6. Statement-level provenance has no in-format home beyond footnotes and ID prefixes; scope policing in multi-source maps is manual.
  7. Independence is assumed and dependence must be authored; there is no correlation annotation. The one dependence the solve creates by itself is explaining away (gotcha 2 above).
  8. Solver cost grows with treewidth (the corpus solves in seconds at treewidth ~7–9); width-not-depth authoring also keeps treewidth down.
  9. Comment-layer slots are conventions: # check: (a point or a lo..hi interval) and # gate: are invisible to tools other than the solver readouts and the lint.
  10. Cross-map ID reuse is unchecked, so verify the propositions match before treating two maps’ same-named nodes as the same claim.

Verify

python3 tools/argmap-lint.py FILE          # repo; in a bundle: python3 argmap-lint.py FILE
cd experiments/solver-prototypes && python3 solve_map.py FILE --top 10   # bundle: cd solver/
python3 solve_map.py FILE @headline

Errors must be zero. Warnings need explanations, not suppression: the discipline is not “zero warnings”, it is “every warning has an explanation you could put in a comment” (the flagship ships two deliberate W1s).

Code Meaning Author action
E1 duplicate ID (one namespace) rename
E2 dangling reference fix the ID
E3 ~$id rewrite as an undercut
E4 probability outside [0,1] fix
E5 v0.3 pair without argmap-version: 0.3 declare the version
E6 malformed pair (0.9/, /0.2) write both members
E7 ::id used in an expression a group takes no part in inference; reference a member instead
E8 a probability on a :: line groups have no credence slot; delete the number
E9 > outside an annotation block move it under its node, before that node’s first child
E10 > with no quote text write the quote or delete the line
W1 evidence-in-premise, not undercut-shaped usually a polarity slip; legitimate only for idiom 8, then comment it
W2 directed cycle usually fine (mutual rebuttal); check it is not a zero-negation support cycle
W3 prose line resembling a node you lost a sigil
W4 footnote used/defined mismatch fix
W5 evidence label past 56 chars an exact threshold, not a guideline: it fires at 57. Distill the warrant; depth to the gloss
W6 stranded node (validator only) re-home it with its consumer
W7 pair sums > 1 declared two-sided conflict or infeasible residual; confirm intended
W8 pair 0/0 drop it
W9 pair entangled with undercut shape check what the opposed side asserts
W10 pair syntax under a declared version < 0.3 (validator only) declare argmap-version: 0.3
W11 authored 0 strength you probably mean an unstrengthed line
W12/W13/W14 group vs block mismatch see the groups section
W15 quote line with no [^locator] add it; provenance is the point
W16 leftover [^ inside quote text only a trailing ref is the locator; fix the stray/doubled one
W17 ` # ` inside quote text quote lines have no trailing comment; move the note to #[…]
W18 quotes before the end of the gloss prose reorder: gloss first, then quotes
W19 > under a declared version < 0.3 declare argmap-version: 0.3
W20 retired ~"…" still in a gloss migrate it (> line / plain marks / echo)
W21 buried spine (top-level statements unconnected in the flat projection) lift the linking evidences it names (spine test)
W22 zero-node file the parse went wrong; read the counts
W23 bare point + # check: on one head line drop one, or the remainder as a pair beside the check
W24 @id/$id token in prose resolving to nothing fix the typo or drop the sigil
W25 bare point beside mapped support derive: number to # check:, or the remainder as a pair
W26 malformed # check: token a point in [0, 1] or lo..hi, lo <= hi
I1 isolated statements connect or delete
I2 block inventory read it; confirm the split you intended
I3 unstrengthed-line inventory commit a strength by rubric, or delete the line
I4 premise-less strengthed line: the reading note the solve pools it with its conclusion’s other numbers for now; the stacking reading is decided (D166 item 4) and lands in a later release; a line reporting one source names the source as a premise
I5 parallel leaves: sibling lines sharing one conclusion and one premise set (settled, D166) they are same-side shares of one population, independent where nothing opposes them; merge one argument written twice
I6 coinciding pairs from different premise sets into one statement (settled, D166) where their premises hold together they are one draw and the strongest share on each side holds, so agreeing lines read as either one alone

Three caveats. W6 and W10 live only in the TypeScript validator (visible in the editor), not in this lint. On expression-valued conclusions (@a OR @b left of the given bar) the lint skips the undercut-shape family (W1/W9) by design, because the editor validator covers those. And “zero errors” is a weaker gate than it sounds: the lint reports ok on a file it finds no nodes in, so a truncated or mangled file passes cleanly and then fails in the solver with a raw traceback rather than a diagnostic. Read the reported counts, not just the exit code: 0 statements, 0 evidences on a file you know has nodes means the parse went wrong. Without the editor, a successful solve_map.py run doubles as the parse gate: it loads the file through the real parser.

Reading the solve: statement gaps (authored/check vs solved) mean the mapped argument does not deliver the stated belief; evidence tensions mean the map holds the line below the strength its author wrote (under D161 only that direction tints; carried above it is the fill; look for an overlooked conflict with neighbouring lines); composition gaps mean a refinement’s own steps compose to something different from the coarse strength on the folded line, which is the number the editor shows there (decide which side is wrong, since both happen; the spectator gap beside it in solve_map.py is the bench’s whole-network conditional, not a verdict, S21 open). Investigate any tension above ~0.15 before touching numbers, then fix structure or add named evidence, never tune silently. Numbers never move to make badges disappear; a badge that stays is a finding. That ~0.15 is a rule of thumb for evidence tensions only; there is no ratified threshold for statement or spectator gaps, so judge those by whether the gap would change a reader’s reading, and say in the log what you concluded.

The readout’s own vocabulary: the header NAME: 15+14 vars, width=4 | 0.1s, conv=True, reference=g, cell-draw=chain reports the statements plus the compile’s other variables (the lines’ coins and its auxiliaries), the junction-tree treewidth (cost grows with it), whether the solve converged, and the reading it ran (the shipped one: the network reference and the one draw). conv=False invalidates the numbers below it, so re-check before reading anything. Each strengthed line yields one row, $id:P(E0)=p n=<flips>, with q its solved in-force rate and |d| its distance from the strength (the tint counts only a fall below it); the rate is held once, on the line’s own coin. (--reference d36 prints the retired reference’s two rows per line, P(E|phi) and P(E|~phi), one on each side of the premise; gotcha 6 is what that cost.) --reference d36 --band (a bench instrument of the retired uniform reference; its numbers do not describe the shipped solve) adds the forced interval for a named statement: how far the constraints actually pin it, as against where max-entropy settled inside that freedom. A wide band is not an error; it says the exact point value is not load-bearing, so do not build an argument on its third decimal. An EMPTY band is the real signal: the constraint set is infeasible at that node.

For translated maps, python3 tools/translation-parity.py BASE TR verifies the translation touches only free-text spans.