Authoring .argmap maps
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):
- Every number has a firmness, shown beside it in coin flips on a
claim (from the width the author left open:
0.7/0.1about 8, a point 198, the cap) and as the kind word on a line (the# kind:key:formalhard,deductive1000,mechanism64,empiricalandtestimony16,analogyandhope4, no key 16). - 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). - 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?
- Supporting quote (most of them), evidence for the claim: lift to
a
>line. - 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. - 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):
- Statement label = the claim itself, a proposition, may be a full sentence. Not length-linted.
- 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. - 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)
- 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.
?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).- Residual rule: frontier roots keep authored values; derived statements
get
# check: ptrailing 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. - 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).
- 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):
- An unpriced ground reads one half. Asserting
$imp 0.8 @c | @aalone 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@cand leaves@awhere 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 (@cpinned 0.9 beside the lone line:@a0.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:@a0.466; 0.8 against 0.15, which fit: 0.500). Measured 2026-09-24 withsolve_map.pyat 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@ato 0.365, the negated premise pushed it to 0.651), which the shipped solve does not have. - 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. - 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. - 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,::splitagainst::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-expertsstays an undercut;$uc-precedentedand$c12dr-objare lines against@mis-ext(won outright, the title claim falls to 0.10; as an undercut the second left it at 0.37). - 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).
- 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.
- Three slots. Point
@s 0.9?= the zero-width pair0.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.18,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)@subvert0.900 /@resists0.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 (@subvert0.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. - 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-subversion0.899 to 0.843 and@incorrigible0.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”: remainder0.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. - 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.930.9?/0?(one-sided: the midpoint above the point is the balancing prior’s reading); C2 0.930.88?/0.02?; C7 / P-FACT 0.900.85?/0.05?; C3 0.850.75?/0.05?; 0.800.7?/0.1?; C4 / P-GRANT 0.750.6?/0.1?; C5 0.700.55?/0.15?; RS6 0.600.4?/0.2?; role defaults 0.8/0.7/0.60.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), never0/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 amechanismline’s 64, so under a reader’s what-if the authors’ assertions give before their mechanisms. - 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:
@both0.799 to 0.818,@either0.935 to 0.915; T5 vs T5b:@danger0.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-causelists the rows. Never AND a statement with its own derivative ($wst-race,@race-dynamics AND @one-cavalier-sufficeswhere$ocs-evderives the second from the first): drop the duplicate premise or re-elicit conditionally. Trace each premise’s ancestry before writing an AND. - 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 @bplus1 ~@want | ~@a OR ~@b, T6:@want0.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 [..] 1conjoined 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@diesreads 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).
- 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/-respsuffixes are a mnemonic convention, not syntax. Each line takes its own kind: the objection’s is usuallyhopeortestimony, the response’smechanism,deductiveoranalogy; an undercut never inherits the kind of the line it attacks. - 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 $ucreinstates@claimexactly to the extent the rescue in$ucfails. - Linked vs convergent, side by side (tut 7.3, anchor
$fragile-ev). Write$a 0.9? @hub | @x AND @y AND @zbeside$b 0.7? @hub | @w. Test for linked: neither conjunct alone suffices (“neither end alone shows disagreement; together they are the spread”). - 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. - 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-asiin 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 withargmap-query fold-audit, which lists every folded line with its weakest required step and flags the ones above it (advisory). - 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”. - 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@p1conjunct 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). - 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. - 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. - Epistemic-fact reification (tut 7.10, anchor
@risk-unbounded; wrong shapes inexamples/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:$escapeis the author naming the condition under which their own conclusion lapses, which is honest and persuasive. - 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. - 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. - 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. - 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):
- 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.
- 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.
- 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
- 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.
- 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. - 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’sdeclines: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 thatupdates: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. - 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
- Undercut schema is exactly
$u q ~C | grounds AND $target; dropping theAND $targetsilently makes it a rebuttal. - Convergent lines must not share grounds (independence is assumed); merge, name the shared source, or partition.
ANDonly if no conjunct alone suffices; overdetermined routes are separate convergent lines.- 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 protectedparses as gloss…memory cellplus trailing comment2 is protected, losing the rest of the sentence from the display with no diagnostic. The escape is to delete the space:cell#2stays in the gloss whole. Reword or close the gap; never leave ` #` inside prose you meant to keep. - 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).
- 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).
#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).
- Pin beside mapped support (T1) / W25 / derive: number to
# check:at its register’s interval, or the remainder as a pair. - 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.
- Pinned root homed in a box it does not feed /
isolate-audit/ derive from the container (inference test), re-home, or say why. - Restatement wired as inference (
@psychosisshape) /restate-audit- the reading “does the passage make this step?” / delete the line, cross-reference in a comment, or merge the docks.
- Two lines sharing a premise into one conclusion /
shared-cause/ the deliberate shared conjunct (comment it), or factor out, or merge. - 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.pyat scale / drop the duplicate premise or re-elicit on the derivative alone. - 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?). - 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.
- A definition as a p = 1 statement (T7, 1/w per junction) / grep
` 1:
and1?:`, lint silent / gloss or glossary; definitional claims as p = 1 lines, the converse pair (T6). - Malformed check interval / W26 / a point in [0, 1] or
lo..hi. - Unstrengthed line left as structure / I3 / commit a strength by rubric or delete the line.
- 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. - 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. - 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. - 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.
- A restatement under two labels, and the wrong door (the flagship’s
@asi-soon->@if-builtuntil 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-powerreaching the title only through that line) /restate-auditonly 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;consumersfor the single-consumer orphan;inverse-audit --allfor 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. - 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, orcook-audit’s label overlap (0.75 and up) flags them as duplicates. AUTHORING_NOTES 2026-09-25, the label pass. - One consideration at two docks (
$ext-corebeside$ext-incidentalinto@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 everyshared-causerow (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):
- Scope conditionals (“aligned now, degrades at superhuman scale”) have no first-class form; nesting is a partial workaround, statement granularity is your burden.
- 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.
- No statement re-opening (D33): refinement is physical indentation, so declare nodes at their refinement site and forward-reference them (IDs are document-global).
- Binary statements only: categorical or continuous claims enter through threshold-gate statements (“X exceeds T”).
- Credal links are second-order: nothing computes “if P(X) > t then
Y”, so use idiom 10 plus a
# gate: q($e) >= t => @ccomment audit. - Statement-level provenance has no in-format home beyond footnotes and ID prefixes; scope policing in multi-source maps is manual.
- 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).
- Solver cost grows with treewidth (the corpus solves in seconds at treewidth ~7–9); width-not-depth authoring also keeps treewidth down.
- Comment-layer slots are conventions:
# check:(a point or alo..hiinterval) and# gate:are invisible to tools other than the solver readouts and the lint. - 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.