79 KiB
Comprehension history
2026-10-09T00:41:03Z, PR #19 at 859c952, against 9519606
Ruling: better
| Seat | Vote |
|---|---|
| Mid A | better |
| Inherited architect | better |
Mid A, decided by:
src/markdown/portable/task-ids.ts:7mintTaskIds: one walk, no carried set filled by the parser as a side effectsrc/markdown/parse/markdown-to-adf.ts:26Reading: plain data,codeBlockNodeno longer mutatescarriedsrc/markdown/portable/conventions.ts:8flavourClaims: one table states what each reader claims; branches name the claim they testsrc/markdown/parse/markdown-to-adf.ts:161quoteNode: the title is read in the reader's own flavour, no hop throughinlineLeavessrc/index.ts:5exports: each call named by its flavour; "plain" no longer means two things
Inherited architect, decided by:
src/markdown/parse/markdown-to-adf.ts:26Reading: the hiddencarriedset and the retryingmintTaskIdsare gonesrc/markdown/parse/markdown-to-adf.ts:161quoteNode: parser and emitter no longer correct only togethersrc/markdown/parse/markdown-to-adf.ts:113readBlock: branches name the claim (claims.alerts,claims.taskMarkers)src/index.ts:5exports: flavour names say which file to opensrc/markdown/portable/conventions.ts:3flavourClaims: cost, all three flavours' rows live underportable/
2026-10-09T00:56:04Z, PR #19 at 5fc877e, against 9519606
Ruling: better
| Seat | Vote |
|---|---|
| Mid A | better |
| Inherited architect | better |
Mid A, decided by:
src/markdown/portable/conventions.ts:8flavourClaims: one table says what each flavour reads; every gate reads a named fieldsrc/markdown/portable/task-ids.ts:7mintTaskIds: one pass, no carried set crossing modulessrc/index.ts:5exports: each name says which markdown it meanssrc/markdown/parse/markdown-to-adf.ts:161quoteNode: no reach into the portable writer's reductionsrc/markdown/portable/conventions.ts:20ReadClaims: cost,directiveNodeleans on a type in another file
Inherited architect, decided by:
src/markdown/portable/task-ids.ts:6mintTaskIds: the retry loop and the parser-filled set are gonesrc/markdown/parse/markdown-to-adf.ts:26Reading: no hidden state; branches name the feature they gatesrc/markdown/portable/conventions.ts:8flavourClaims: cost, the table for all three flavours lives underportable/src/markdown/emit/line-escaping.ts:92escapeClaims: directive escaping under the flag the parser checkssrc/markdown/emit/adf-to-markdown.ts:146spellPortableBlock: no hard-coded lossless title
2026-10-09T01:43:11Z, PR #21 at c45320b, against 9a242c7
Ruling: better
| Seat | Vote |
|---|---|
| Mid A | better |
| Inherited architect | better |
Mid A, decided by:
src/markdown/parse/markdown-to-adf.ts:23MarkerParagraph: the block kind says a marker's paragraph holds no lone image, wherereadMarkedscanned its output afterwardssrc/markdown/emit/image.ts:7tryImage: builds what the reader would build and compares, whereimageShaperestated the shape by handsrc/markdown/parse/inline-content.ts:25InlineContent: one rule replaces five image refusal sites over two filessrc/markdown/external-image.ts:4centeredImage: one builder for the shape three literals heldsrc/markdown/parse/inline-content.ts:550pieceNodes: costs more — its image arm relies onassemblehaving linked every top-level image
Inherited architect, decided by:
src/markdown/external-image.ts:4centeredImage: the image's ADF shape is defined once for reader, emitter and portable reducersrc/markdown/parse/markdown-to-adf.ts:23MarkerParagraph: replacesreadMarked's after-the-fact search and its caller-computed flagsrc/result.ts:1ConvertErrorCode:unmappable-imageand its refusal paths are gonesrc/markdown/parse/inline-content.ts:43Image: costs more — four functions must agree on the image'slinksrc/markdown/parse/inline-content.ts:26InlineContent: costs more — no longer image xor nodes
2026-10-09T08:38:28Z, PR #21 at 1098b5e, against 9a242c7
Ruling: better
| Seat | Vote |
|---|---|
| Mid A | better |
| Inherited architect | better |
Mid A, decided by:
src/markdown/external-image.ts:4centeredImage: one builder where three places built the image node by handsrc/markdown/emit/image.ts:7tryImage: compares against what the reader builds, whereimageShaperestated the shapesrc/markdown/parse/markdown-to-adf.ts:26TaskParagraph: a named block kind replacesreadMarked's after-the-fact index searchsrc/markdown/parse/inline-content.ts:302assemble: costs more — which of three readings an image takes hangs on a one-line condition and theinLinkflagsrc/markdown/parse/inline-content.ts:26InlineContent: costs more — no longer image xor nodes
Inherited architect, decided by:
src/markdown/external-image.ts:4centeredImage: the image shape is defined once for reader and both writerssrc/markdown/emit/image.ts:7tryImage: the emitter cannot drift from the readersrc/markdown/parse/markdown-to-adf.ts:136readBlock: the task paragraph is routed where the block is classifiedsrc/markdown/parse/inline-content.ts:302assemble: costs more — the most expensive line to decodesrc/markdown/parse/markdown-to-adf.ts:154paragraphsOf: costs more — the name does not say it splits the marker line
2026-10-09T08:46:45Z, PR #21 at e7029c1, against 9a242c7
Ruling: better
| Seat | Vote |
|---|---|
| Mid A | better |
| Inherited architect | better |
Mid A, decided by:
src/markdown/emit/image.ts:7tryImage: builds what the reader would build and compares, whereimageShaperestated the shapesrc/markdown/external-image.ts:4centeredImage: the image shape lives in one named filesrc/markdown/parse/markdown-to-adf.ts:26TaskParagraph: a typed block kind replacesreadMarked's after-the-fact searchsrc/markdown/parse/inline-content.ts:302assemble: costs more — one dense ternary overinLinksrc/markdown/parse/inline-content.ts:26InlineContent: costs more — no longer a discriminated union
Inherited architect, decided by:
src/markdown/external-image.ts:4centeredImage: one builder where three had to stay in stepsrc/markdown/parse/markdown-to-adf.ts:136readBlock: the task paragraph is routed by a named block kindsrc/result.ts:1ConvertErrorCode: one rule no longer enforced at five sitessrc/markdown/parse/inline-content.ts:26InlineContent: costs more —contentNodedropsimagesilentlysrc/markdown/parse/inline-content.ts:302assemble: costs more — three routes from an image piece to text
2026-10-09T09:00:13Z, PR #22 at fe5c731, against 78655bc
Ruling: same
| Seat | Vote |
|---|---|
| Mid A | same |
| Inherited architect | same |
2026-10-09T09:52:41Z, PR #22 at 6f1a16b, against 78655bc
Ruling: worse
| Seat | Vote |
|---|---|
| Mid A | worse |
| Inherited architect | worse |
Mid A, decided by:
src/markdown/emit/inline-line.ts:106takeFallback: a range may part joined breaks or carry, decided by state an earlier pass builtsrc/markdown/emit/inline-line.ts:316emitMarkedRun: a carry that signals parting totakeFallbacktwo levels upsrc/markdown/emit/inline-line.ts:233joinsRun: a lookahead whose shortcut holds only byinlineRuns' call ordersrc/markdown/emit/inline-line.ts:58portableLineFallback: a second retry loop sharing the partingsrc/adf/inline-nodes.ts:5InlineNodeModel.marks: reads as "has marks", not "takes marks"src/markdown/parse/inline-content.ts:328linkTo: the comment hides that the breaks stay after the destination
Inherited architect, decided by:
src/markdown/emit/inline-line.ts:331emitMarkedRun: the newline check returns a carry that is a parting signal, one fact over three functionssrc/markdown/emit/inline-line.ts:106takeFallback: two growing sets whose order matterssrc/markdown/emit/inline-line.ts:58portableLineFallback: a second retry loop with its own exit rulesrc/markdown/emit/inline-line.ts:233joinsRun: lookahead, shortcut and three conditions per break;inlineRunstakes the whole contextsrc/adf/inline-nodes.ts:5InlineNodeModel.marks: the name hides "takes marks"src/markdown/parse/inline-content.ts:328linkTo: the comment no longer says an empty destination reads as nothing
2026-10-09T09:57:25Z, PR #22 at 45b5446, against 78655bc
Ruling: worse
| Seat | Vote |
|---|---|
| Mid A | worse |
| Inherited architect | worse |
Mid A, decided by:
src/markdown/emit/inline-line.ts:100takeFallback: the first fallback is discarded to stop joining, known only from a commentsrc/markdown/emit/inline-line.ts:200inlineRuns: an indexed loop moving its own counter byjoinedBreaks' resultsrc/markdown/emit/inline-line.ts:226joinedBreaks: six positional parameters and two jobs
Inherited architect, decided by:
src/markdown/emit/inline-line.ts:101takeFallback: a hidden first step that takes no fallbacksrc/markdown/emit/inline-line.ts:200inlineRuns: runs built by a forward scan the reader steps through by handsrc/markdown/emit/inline-line.ts:56portableLineFallback: checks an unjoined line while the final emit starts joinedsrc/markdown/emit/inline-line.ts:40LineFallbacks.joinsBreaks: a fallbacks field whose fallback value is false
2026-10-09T10:02:23Z, PR #22 at f195ebd, against 78655bc
Ruling: same
| Seat | Vote |
|---|---|
| Mid A | same |
| Inherited architect | same |
2026-10-09T10:07:15Z, PR #22 at 37629e4, against 78655bc
Ruling: same
| Seat | Vote |
|---|---|
| Mid A | same |
| Inherited architect | same |
2026-10-09T10:19:03Z, PR #22 at 239218f, against 78655bc
Ruling: same
| Seat | Vote |
|---|---|
| Mid A | same |
| Inherited architect | same |
2026-10-09T12:13:22Z, PR #24 at d109199, against 78655bc
Ruling: same
| Seat | Navigation | Locality | Shape | Self-sufficiency | Overall |
|---|---|---|---|---|---|
| Mid A | better | same | same | better | better |
| Inherited architect | same | same | same | worse | same |
| Maintainability senior | same | better | worse | same | same |
| Junior A | better | better | same | same | better |
Mid A, decided by:
- Navigation, Self-sufficiency:
src/markdown/portable/task-list.ts:5splitTaskList: the split rule is one named unit both directions import, where it sat inbulletNodeandreduceTaskList/nestIn - Self-sufficiency, Navigation:
src/adf/inline-nodes.ts:12inlineNodes: "a hard break takes no marks" is the fieldtakesMarks: false, read by parser and emitter - Shape:
src/markdown/portable/adf-to-portable-markdown.ts:289reduceTaskList: the loop lost itsnestedaccumulator andnestIn; line 303 packs the split and a merge into one expression - Shape, Locality:
src/markdown/portable/task-list.ts:8splitTaskList: astandingflag across iterations andstandsoverwritten mid-iteration;heldTasksays little - Locality:
src/markdown/parse/markdown-to-adf.ts:86readBlocks:bulletNodereturns a schema-breaking task list that its caller splits, and neither says so - Self-sufficiency:
src/markdown/parse/inline-content.ts:328linkTo: the comment covers the hard-break case
Inherited architect, decided by:
- Self-sufficiency:
src/markdown/portable/task-list.ts:5splitTaskList: the comment states the schema constraint, not the rule; the loop must be traced by hand - Locality:
src/markdown/parse/markdown-to-adf.ts:201bulletNode: builds a schema-breaking intermediate that onlyreadBlocksrepairs under an unexplained guard - Locality:
src/markdown/portable/adf-to-portable-markdown.ts:311reduceTask: droppingblankedCoderests on a guarantee neither unit states - Locality:
src/markdown/portable/adf-to-portable-markdown.ts:317nestIn: two hand-mirrored halves of one rule became one function - Self-sufficiency, Locality:
src/adf/inline-nodes.ts:12inlineNodes:takesMarks: falsemakes the hard-break rule checkable at its source - Self-sufficiency:
src/markdown/portable/adf-to-portable-markdown.ts:288reduceTaskList: the comment no longer prepares the reader for line 303 - Shape:
src/markdown/portable/task-list.ts:12splitTaskList:standing/standsreuse a wordreduceStandinguses for another meaning
Maintainability senior, decided by:
- Locality:
src/markdown/portable/task-list.ts:5splitTaskList: the stay-or-stand rule lives once, where the reader'sbulletNodeand the writer'snestInmirrored it - Locality:
src/markdown/parse/markdown-to-adf.ts:86readBlocks:bulletNodereturns a shape the caller quietly replaces, behind an unexplainedblock.kindguard - Shape:
src/markdown/portable/task-list.ts:9splitTaskList: two cross-iteration accumulators, a negated compound ternary, near-synonym names, andheldTaskhides the taskItem conversion - Shape:
src/markdown/portable/adf-to-portable-markdown.ts:303reduceTaskList: one 180-character line maps the split and re-merges - Shape:
AGENTS.md:28decision index: a title grew into a two-clause sentence
Junior A, decided by:
- Locality, Navigation:
src/markdown/portable/task-list.ts:5splitTaskList: one function decides for reader and writer, where each had its own rule - Locality:
src/markdown/parse/markdown-to-adf.ts:86readBlocks:bulletNodereturns an unfinished shape only the caller completes - Locality:
src/adf/inline-nodes.ts:3InlineNodeModel.takesMarks: the hard break's rule lives in one row both directions read - Shape:
src/markdown/portable/task-list.ts:5splitTaskList: a carriedstandingflag, a reassignedstands, andheldTask's name hides the conversion - Navigation:
src/markdown/parse/markdown-to-adf.ts:22imports: both converters lead to the same named file
2026-10-09T12:35:05Z, PR #24 at e487fa4, against 78655bc
Ruling: better
| Seat | Navigation | Locality | Shape | Self-sufficiency | Overall |
|---|---|---|---|---|---|
| Mid A | same | better | same | same | better |
| Inherited architect | better | better | same | better | better |
Mid A, decided by:
- Locality, Overall:
src/markdown/portable/adf-to-portable-markdown.ts:289reduceTaskList: a plain collect loop handing the list tosplitTasks, where the base carried anestedaccumulator andnestInmutatedtasks - Locality:
src/markdown/portable/task-list.ts:6splitTaskList: reader and writer share one rule, wherebulletNodeandnestIneach encoded it - Locality, Shape:
src/markdown/parse/markdown-to-adf.ts:84readBlocks: the portable task list is caught beforereadBlock, which depends on that order - Shape:
src/markdown/portable/task-list.ts:33itemParts:paragraphsandnestedare indices named like collections, and the demotion totaskItemis unnamed - Navigation, Shape:
src/adf/block-nodes.ts:92isTaskItem: one findable predicate, against one more hop from a parse symptom
Inherited architect, decided by:
- Locality, Navigation, Overall:
src/markdown/portable/task-list.ts:6splitTaskList: one unit decides where a task item's blocks go, for reader and writer - Locality, Shape:
src/markdown/portable/adf-to-portable-markdown.ts:289reduceTaskList: one pass then one call, no state carried across iterations - Self-sufficiency, Locality:
src/adf/inline-nodes.ts:5takesMarks: the hard-break rule is a field both directions read - Shape:
src/markdown/portable/task-list.ts:33itemParts: an index overcontentused overrun, andnestedrunning into the siblings - Shape, Locality:
src/markdown/parse/markdown-to-adf.ts:84readBlocks: a third special case ahead of the dispatch - Shape:
src/adf/block-nodes.ts:92isTaskItem: one predicate replaces two copies - Self-sufficiency:
src/markdown/portable/task-list.ts:5comment: states the schema limit and what follows from it
2026-10-09T13:03:22Z, PR #25 at 2b211e9, against 875c0e5
Ruling: better
| Seat | Navigation | Locality | Shape | Self-sufficiency | Overall |
|---|---|---|---|---|---|
| Mid A | better | better | better | same | better |
| Inherited architect | same | better | better | same | better |
Mid A, decided by:
- Locality, Shape, Overall:
src/markdown/portable/adf-to-portable-markdown.ts:118portableSequence: a plain splice withindex -= 1, where the base merged neighbours after every splice throughspliced,mergedLists,joinedListsandsplitTasks - Locality, Navigation:
src/markdown/parse/markdown-to-adf.ts:98listBreakFault: gone, with the base's look atblocks[index - 1]andblocks[index + 1]and the separator spelled in four places - Navigation, Shape:
src/markdown/parse/blocks.ts:232continuesList: one named predicate on kind and delimiter thatitemStartandopenedListshare - Locality:
src/markdown/emit/adf-to-markdown.ts:73joinBlocks: a toggledalternatedflag decides each list's text from the one before it, andisOrderedcounts a task list as a bullet list unsaid - Shape:
src/markdown/emit/adf-to-markdown.ts:334spelledList:tryListbuilds both spellings then falls back once, andtryTaskListshares the helper
Inherited architect, decided by:
- Locality, Shape, Overall:
src/markdown/portable/adf-to-portable-markdown.ts:118portableSequence: a filter and a loop ending inindex -= 1, where the base kept the splice window, the merge rules and the renumbering-as-text rule together - Locality, Shape:
src/markdown/parse/markdown-to-adf.ts:79readBlocks: reads one block at a time, where the base judged a separator by its siblings - Locality:
src/markdown/emit/adf-to-markdown.ts:73joinBlocks: a toggle carried across iterations sends a third adjacent list back to-, seen only by tracing - Shape:
src/markdown/emit/adf-to-markdown.ts:334spelledList: the both-or-neither rule is one uncommented expression - Self-sufficiency:
src/markdown/emit/adf-to-markdown.ts:369tryListItemLines:inner.startsWith('*')depends on the alternate bullet being*, and the comment needs the inline escaping worked out - Self-sufficiency:
src/markdown/parse/blocks.ts:232continuesList: states the rule the base sent the reader to the spec for
2026-10-09T13:37:16Z, PR #25 at ca3d703, against 875c0e5
Ruling: better
| Seat | Navigation | Locality | Shape | Self-sufficiency | Overall |
|---|---|---|---|---|---|
| Mid A | better | better | better | better | better |
| Inherited architect | better | better | better | same | better |
Mid A, decided by:
- Locality, Shape, Overall:
src/markdown/portable/adf-to-portable-markdown.ts:118portableSequence: a worklist that keeps a block that spells or pushes its items back, where the base spliced, merged neighbours and stepped the index back by hand - Navigation, Locality:
src/markdown/parse/markdown-to-adf.ts:70readBlocks: handles each block alone, where the base judged a separator by its neighbours across five places - Shape, Self-sufficiency:
src/markdown/parse/blocks.ts:232continuesList: one named predicate on kind and delimiter, its rule stated in place - Self-sufficiency, Locality:
src/markdown/emit/adf-to-markdown.ts:27SpelledBlock: its comment states whyalternateTextexists, thoughjoinBlocksnow carries a toggle across siblings - Shape:
src/markdown/emit/adf-to-markdown.ts:334spelledList: line building in small units, the fallback once after the loop, shared bytryTaskList - Self-sufficiency:
src/markdown/emit/adf-to-markdown.ts:369tryListItemLines: the*branch's comment needs a reread
Inherited architect, decided by:
- Locality, Shape, Overall:
src/markdown/portable/adf-to-portable-markdown.ts:118portableSequence: a work stack replacing six helpers and the base's cursor rewind - Locality, Navigation:
src/markdown/parse/markdown-to-adf.ts:70readBlocks: each block reads alone, and two merged lists lead to one emitter and one parser unit - Locality, Navigation:
src/markdown/parse/blocks.ts:232continuesList: a list continues exactly where CommonMark says, checkable without the spec - Locality:
src/markdown/emit/adf-to-markdown.ts:72joinBlocks: a block's spelling depends on the run before it, where the base's separation was a pure function of a pair - Shape:
src/markdown/emit/adf-to-markdown.ts:334spelledList: one exit to the directive form, though bullets pass() => ''as the number - Self-sufficiency:
src/markdown/emit/adf-to-markdown.ts:369tryListItemLines: the*branch needs the spec open, cancelling the spec pointers removed
2026-10-09T14:50:52Z, PR #27 at 2378782, against a9fedb3
Ruling: better
| Seat | Navigation | Locality | Shape | Self-sufficiency | Overall |
|---|---|---|---|---|---|
| Mid A | better | better | better | better | better |
| Inherited architect | better | better | better | same | better |
Mid A, decided by:
- Locality, Self-sufficiency:
src/markdown/inline-tokens.ts:20readInlineToken: the parser and the escaper ask one function what the reader takes at a character, where each held its own copy of the rules - Locality, Shape:
src/markdown/emit/line-escaping.ts:102escapeClaims: the order-dependentafterEscapeandpairsEqualsflags are gone; runs go whole toescapeRunand fixed inputs ride oneEscapeWalkrecord - Shape, Navigation:
src/markdown/parse/inline-content.ts:110scanInline: a two-level character dispatch and eight helpers became one switch over token kinds - Shape:
src/markdown/emit/line-escaping.ts:158claimsCharacter: switches ontoken.kindin place of a chain of character tests
Inherited architect, decided by:
- Navigation, Shape:
src/markdown/inline-tokens.ts:20readInlineToken: one tokenizer answers what the reader sees at an index, where two parallel implementations had to agree - Locality:
src/markdown/emit/line-escaping.ts:112escapeClaims: each step reads on its own, no flag carried from the previous character - Shape:
src/markdown/emit/line-escaping.ts:158claimsCharacter: switches on the token kind and takes the shared record; the heading closer is worked out once inclosingHashes - Shape, Navigation:
src/markdown/parse/inline-content.ts:121readToken: one exhaustive switch overInlineToken['kind']replaces a two-level dispatch - Locality:
src/markdown/emit/line-escaping.ts:173claimsCharacter:default: return trueclaims every kind it does not name, so a new kind is escaped without its author deciding
2026-10-09T17:14:17Z, PR #27 at 65d2a26, against a9fedb3
Ruling: better
| Seat | Navigation | Locality | Shape | Self-sufficiency | Overall |
|---|---|---|---|---|---|
| Mid A | better | better | better | same | better |
| Inherited architect | better | better | better | same | better |
Mid A, decided by:
- Navigation, Locality:
src/markdown/inline-tokens.ts:21readInlineToken: the one place that says what a character opens, which the reader and the escaper both dispatch on, where each held a copy that could drift - Locality, Shape:
src/markdown/emit/line-escaping.ts:156claimsCharacter: a flat switch on the token kind over a readonlyEscapeWalk, where one character's escape hung on flags the previous iteration set - Shape:
src/markdown/parse/inline-content.ts:121readToken: one flat switch, recognition in the tokenizer and action here, where a two-level character switch fanned out to eight helpers - Locality:
src/markdown/directive-syntax.ts:14ClaimedPrefix: the directive read can no longer answer that no prefix stands there - Shape:
src/markdown/emit/line-escaping.ts:147claimsRunRest: re-reading each suffix of a run is a step the name does not say
Inherited architect, decided by:
- Navigation, Locality:
src/markdown/inline-tokens.ts:21readInlineToken: the 3am symptom of an unescaped character leads to one file both directions ask - Locality, Shape:
src/markdown/emit/line-escaping.ts:156claimsCharacter: an exhaustive switch read one case at a time, where the decision needed replaying the loop forpairsEquals - Shape, Locality:
src/markdown/parse/inline-content.ts:121readToken: one pure tokenizer and one switch that applies tokens - Shape:
src/markdown/directive-syntax.ts:14ClaimedPrefix: the directive read needs proof of its prefix, and the misnamedopensConstructis gone - Locality:
src/markdown/emit/line-escaping.ts:112escapeClaims: the escaper steps one character at a time while the reader steps by token, which only the==comment explains
2026-10-10T09:16:56Z, PR #30 at 6182ba6, against c11aa91
Ruling: worse
Fell: Locality. Under the floor of 7.0: Locality 5.63, so the same ruling counts as worse.
| Seat | Navigation | Locality | Shape | Self-sufficiency | Overall |
|---|---|---|---|---|---|
| Mid A | same | worse | same | same | same |
| Inherited architect | better | worse | same | same | same |
| Seat | Navigation | Locality | Shape | Self-sufficiency | Overall |
|---|---|---|---|---|---|
| Junior A | 7 | 5.5 | 6.5 | 5.5 | 6 |
| Mid A | 7 | 5.5 | 6.5 | 5.5 | 6 |
| Maintainability senior | 7 | 6 | 6.5 | 6 | 6 |
| Inherited architect | 6.5 | 5.5 | 6 | 6 | 6 |
| Mean | 6.88 | 5.63 | 6.38 | 5.75 | 6.00 |
Mid A, decided by:
- Locality:
src/markdown/parse/blocks.ts:79Walk.endedByDefinitions: written incloseLeafat:469and read inopenedListat:257, never cleared, correct only by identity withblocks.at(-1);closeLeaftakes on recording where definitions ended a list
Inherited architect, decided by:
- Locality:
src/markdown/parse/blocks.ts:79Walk.endedByDefinitions: a never-reset fieldcloseLeafwrites andopenedListreads, right only by identity and byopenContainersclosing before it opens; reordering those steps breaks the split silently - Locality:
src/markdown/parse/blocks.ts:432readLineBlock: a second path that can find a paragraph emptied by definitions records nothing, which a reader must prove harmless by hand - Navigation:
src/markdown/parse/blocks.ts:252openedList: the comment names the exception, so a reader of two lists merged or not lands on the right unit - Navigation:
README.md:242the CommonMark exceptions bullet: each exception is named rather than counted by position - Navigation:
CHANGELOG.md:5## Unreleased: breaking entries come first, other changes last
2026-10-11T10:33:32Z, PR #32 at be23835, against c11aa91
Ruling: worse
| Seat | Navigation | Locality | Shape | Self-sufficiency | Overall |
|---|---|---|---|---|---|
| Mid A | same | worse | same | worse | worse |
| Inherited architect | same | worse | worse | worse | worse |
Mid A, decided by:
- Overall, Locality, Self-sufficiency:
src/markdown/parse/markdown-to-adf.ts:229splitPath: builds stand-in nodes and replayssplitTaskListto place a refused block's path, checkable only by knowing how the split moves blocks - Locality, Self-sufficiency:
src/markdown/portable/task-list.ts:23splitPlace: finds the stand-in by object identity, which holds only whiletaskOfParagraphskeeps the original children, and nothing there says so - Locality:
src/markdown/parse/blocks.ts:262endList:closeLeaffillsWalk.endedListsandopenedListreads it, whereopenedListlooked only at the previous block
Inherited architect, decided by:
- Locality, Self-sufficiency, Overall:
src/markdown/parse/markdown-to-adf.ts:229splitPath: a fake task list replayed throughsplitTaskListand found again by identity; iftaskOfParagraphsever copies nodes the old wrong path returns silently - Shape, Locality:
src/markdown/parse/markdown-to-adf.ts:203bulletBlocks: onereadBlockscall became a per-block loop with a hand-built failure, a second depth check and a fan-out throughtaskItems,splitPath,childTypeandsplitPlace;Refusalnames a context bag - Locality:
src/markdown/parse/blocks.ts:78Walk.endedLists: identity-keyed walk state thatcloseLeafwrites andopenedListreads - Shape:
src/markdown/portable/adf-to-portable-markdown.ts:354reduceMedia: the callback'sheldshadows the alt's, and the link goes mark to definition to mark
2026-10-11T10:33:35Z, PR #32 at be23835
| Seat | Navigation | Locality | Shape | Self-sufficiency | Overall |
|---|---|---|---|---|---|
| Junior A | 7 | 6 | 6.5 | 6 | 6.5 |
| Mid A | 7 | 6 | 6.5 | 5.5 | 6 |
| Maintainability senior | 7 | 5.5 | 6.5 | 5.5 | 6 |
| Inherited architect | 6.5 | 5.5 | 6 | 6 | 6 |
| Mean | 6.88 | 5.75 | 6.38 | 5.75 | 6.13 |
Junior A, hardest first:
- Locality:
src/markdown/parse/markdown-to-adf.ts:229splitPath: replayssplitTaskList's internals to name a path - Self-sufficiency:
src/markdown/emit/line-escaping.ts:189escapeClosedRuns: the escaping rule lives inspec/flavour.md
Mid A, hardest first:
- Locality:
src/markdown/emit/adf-to-markdown.ts:30SpellingMemo: reference-keyed memo shared by parse and emit - Self-sufficiency:
src/markdown/parse/inline-content.ts:62Scan: rules read withspec/flavour.mdopen alongside
Maintainability senior, hardest first:
- Locality:
src/markdown/parse/markdown-to-adf.ts:257directiveNode: the parser asks the emitter whether input was legal - Self-sufficiency:
src/markdown/emit/line-escaping.ts:189escapeClosedRuns: needsspec/flavour.mdEscaping open
Inherited architect, would restructure first:
- Navigation:
src/markdown/portable/conventions.ts:23flavourClaims: every flavour's switchboard sits inportable/ - Locality:
src/markdown/emit/adf-to-markdown.ts:117readableBlock: reader acceptance hangs on emitter verdicts
2026-10-11T11:29:00Z, PR #32 at 27c8f9b, against c11aa91
Ruling: worse
| Seat | Navigation | Locality | Shape | Self-sufficiency | Overall |
|---|---|---|---|---|---|
| Mid A | same | worse | same | same | worse |
| Inherited architect | same | worse | same | same | worse |
Mid A, decided by:
- Locality, Overall:
src/markdown/parse/markdown-to-adf.ts:229splitPath: rewrites a refused path by replayingsplitTaskListon stand-in nodes, so a change to the split moves error paths quietly - Locality:
src/markdown/parse/blocks.ts:262endList:closeLeafwritesWalk.endedListsandopenedListreads it later
Inherited architect, decided by:
- Locality, Overall:
src/markdown/parse/markdown-to-adf.ts:229splitPath: four facts held at once, the mutatedtask.content, the path slice, the stand-ins and a second parse inchildType - Locality:
src/markdown/portable/task-list.ts:23splitPlace: finds the refused node by object identity, right only whiletaskOfParagraphskeeps its children
2026-10-11T11:29:02Z, PR #32 at 27c8f9b
| Seat | Navigation | Locality | Shape | Self-sufficiency | Overall |
|---|---|---|---|---|---|
| Junior A | 7 | 5.5 | 6.5 | 5.5 | 6 |
| Mid A | 7 | 5.5 | 6.5 | 5.5 | 6 |
| Maintainability senior | 7 | 5.5 | 6.5 | 5.5 | 6 |
| Inherited architect | 6.5 | 6 | 6 | 6.5 | 6.5 |
| Mean | 6.88 | 5.63 | 6.38 | 5.75 | 6.13 |
Junior A, hardest first:
- Locality:
src/markdown/parse/inline-content.ts:62Scan: a mutable bag many functions change - Self-sufficiency:
src/markdown/emit/line-escaping.ts:189escapeClosedRuns: the rule lives inspec/flavour.md
Mid A, hardest first:
- Locality:
src/markdown/parse/markdown-to-adf.ts:257directiveNode: the parser asks the emitter for verdicts - Self-sufficiency:
src/markdown/emit/line-escaping.ts:100escapeClaims: needs the spec open alongside
Maintainability senior, hardest first:
- Locality:
src/markdown/parse/inline-content.ts:62Scan: flags that act at a distance between escaper, emitter and parser - Self-sufficiency:
src/markdown/emit/line-escaping.ts:189escapeClosedRuns: no local statement of the escaping contract
Inherited architect, would restructure first:
- Navigation:
src/markdown/portable/conventions.ts:23flavourClaims: the table for all three flavours sits inportable/ - Shape:
src/markdown/emit/adf-to-markdown.ts:131spellReadableBlock: the flavour concern spread over three directories
2026-10-11T18:44:18Z, PR #35 at 0227c0b, against 4f00e60
Ruling: same
| Seat | Navigation | Locality | Shape | Self-sufficiency | Overall |
|---|---|---|---|---|---|
| Mid A | better | same | same | same | better |
| Inherited architect | same | worse | worse | same | same |
| Maintainability senior | better | worse | same | same | same |
| Junior A | better | same | same | same | better |
Mid A, decided by:
- Navigation, Overall:
README.md:211"The calls": each public call sits in one row with the codes it refuses, where the base split that knowledge across prose bullets and the feature list - Navigation:
README.md:384"The errors": parsing, emitting and either direction have their own sub-headings, and the error shape is a bulleted list - Navigation:
src/result.ts:49withinEngineLimits: the refusal for output too long is visible at both public entry points, its message in one place
Inherited architect, decided by:
- Locality, Shape:
src/result.ts:49withinEngineLimits: one try/catch wraps each writer's whole call and matches four exact engine messages; a concatenation deep in the emitter does not show it is caught at the top, a reworded engine message turns the refusal back into a throw, andengineLimitFaultsborrows "fault" fromConvertFaultwhile holding plain strings - Shape:
src/result.ts:54withinEngineLimits: an engine overflow is reported asunsupported-node-shapeat an empty path, though the node shapes are fine and the output is what is too big - Locality:
src/canonical-json.ts:30writeCanonicalJson: one walker serves two callers through a stop-returningwritecallback, one more contract to hold when editingschedule
Maintainability senior, decided by:
- Locality:
src/result.ts:49withinEngineLimits: the guard sits only at the two public writers whilewriteMarkdownstays exported and unguarded and the readers rely on another mechanism; nothing states which paths can outgrow the engine's longest string - Locality:
src/result.ts:46engineLimitFaults: errors match exact engine strings, and why a stack overflow stays a throw is not said - Navigation:
README.md:211"The calls": one table maps each call to its refusal codes, where the base spread them over prose that was wrong foradfToPortableMarkdown - Navigation:
src/markdown/opaque-carry.ts:78readCarriedJson:spellsCanonicalJsonreads as plainly at the call site, with its reason beside it
Junior A, decided by:
- Navigation, Overall:
README.md:193"The calls": a table pairs each call with what it reads or writes and what it refuses, and a node-to-spelling table turns a symptom into a concept to grep for
2026-10-11T19:02:20Z, PR #35 at 90de6cb, against 4f00e60
Ruling: better
| Seat | Navigation | Locality | Shape | Self-sufficiency | Overall |
|---|---|---|---|---|---|
| Mid A | better | same | same | same | better |
| Inherited architect | better | same | worse | better | better |
Mid A, decided by:
- Navigation, Overall:
README.md:211"The calls": each call's row says what it reads or writes and what it refuses, and the errors split by direction, where the base spread the codes across a prose list and paragraphs - Navigation:
src/result.ts:49withinEngineLimits: the engine-limit refusal lives in one wrapper, called once at each public writer
Inherited architect, decided by:
- Navigation, Self-sufficiency:
README.md:211"The calls": one row per call gives what it reads or writes and its refusal codes, where the base split them and left outunsupported-node-shapefor the portable writer - Self-sufficiency:
README.md:241"The lossless flavour": two tables map ADF types to their spellings, so the 3am case reads without the spec open - Shape:
src/result.ts:55withinEngineLimits: a length failure is reported underunsupported-node-shapeat an empty path, and the README cell explaining it holds four cases - Shape:
src/result.ts:45engineLimitThrows: matching exact engine message text rots silently when an engine rewords, and JavaScriptCore'sOut of memoryblurs a heap shortage with length
2026-10-12T15:56:53Z, PR #36 at 584b214, against 7a27f6b
Ruling: worse
| Seat | Navigation | Locality | Shape | Self-sufficiency | Overall |
|---|---|---|---|---|---|
| Mid A | better | worse | worse | same | worse |
| Inherited architect | better | worse | worse | same | worse |
Mid A, decided by:
- Locality, Shape, Overall:
src/markdown/emit/adf-to-markdown.ts:61walkBlocks: a running forecast depends onWriting.indent, which each container must pass correctly,tryListdeliberately not indenting - Shape, Locality:
src/markdown/emit/adf-to-markdown.ts:398spelledList: template strings becamejoinedWithinpiped through nestedboundedThencallbacks, andjoinedItemsrepeats the counting loop - Locality:
src/markdown/emit/adf-to-markdown.ts:147readableBlock: the memo is filled incommonMarkSpellingand emptied on read, so when an entry is present depends on call order across two functions - Shape:
src/markdown/directive-syntax.ts:114spellAttributes: each spelling exists twice, as a string and as a generator of pieces - Locality:
src/markdown/portable/editor-normal.ts:26toEditorNormal: editor normalization imports the markdown length bound - Locality:
src/markdown/portable/adf-to-portable-markdown.ts:126portableSequence: each block carries its source path, rebuilt by hand for a replacement - Navigation:
src/markdown/length-bound.ts:1withinEngineLimits: the bound, its refusal and the catch share one module named for them
Inherited architect, decided by:
- Locality, Shape:
src/markdown/emit/adf-to-markdown.ts:61walkBlocks: the forecast is a second length bound besidejoinedWithin, whose never-overcount rule fixes how every container walks - Locality:
src/markdown/emit/adf-to-markdown.ts:377tryList: whether items walk indented depends on whatspelledOrDirectiveListmay decide later - Locality:
src/markdown/parse/markdown-to-adf.ts:266directiveNode: the emitter'sindentleaks into the parser and the portable reduction - Locality:
src/markdown/emit/adf-to-markdown.ts:147readableBlock: filling and emptying the memo split across two functions - Shape:
src/markdown/emit/adf-to-markdown.ts:194quotedBlock: nestedboundedThenreads as continuation passing where a template stood - Shape, Locality:
src/markdown/emit/pipe-table.ts:9tryPipeTable: the sum-then-check rule appears in seven shapes, and a reader cannot tell which is the real bound - Navigation, Shape:
src/markdown/length-bound.ts:41withinEngineLimits: a too-long symptom leads straight to the module named for it - Shape:
src/markdown/directive-syntax.ts:133spellDirectiveOpener: each spelling is a string function and a pieces generator - Shape:
src/markdown/opaque-carry.ts:64carriedJson: the lambda parameterspelledshadows the function's own
2026-10-12T16:40:52Z, PR #36 at acd22aa, against 7a27f6b
Ruling: worse
| Seat | Navigation | Locality | Shape | Self-sufficiency | Overall |
|---|---|---|---|---|---|
| Mid A | better | worse | worse | same | worse |
| Inherited architect | better | worse | worse | same | worse |
Mid A, decided by:
- Locality, Shape:
src/markdown/emit/adf-to-markdown.ts:374spelledList: a builder'sundefinednow means either no list spelling or past the length bound, and every caller ofjoinBlocksmust remember which it holds - Shape:
src/markdown/emit/adf-to-markdown.ts:383listLines: split, map and join became generators yielding pieces intoseparatedByandjoinedWithin, so a reader rebuilds the string in their head - Locality:
src/markdown/emit/adf-to-markdown.ts:125readableBlock: the memo is filled incommonMarkSpellingand deleted on read, a one-shot cache whose hits depend on which walk came first - Navigation:
src/markdown/length-bound.ts:41withinEngineLimits: a too-long refusal leads to a module named for it
Inherited architect, decided by:
- Locality, Shape:
src/markdown/emit/adf-to-markdown.ts:374spelledList:undefinedmeans two things a few lines apart, told apart only by the side of a nestedboundedThencallback - Locality:
src/markdown/emit/adf-to-markdown.ts:125readableBlock: reading the memo is a mutation, and a second read spells again - Shape:
src/markdown/pipe-table-syntax.ts:43pipeRowPieces: one-line templates became generators whose output cannot be read off one line - Locality, Shape:
src/markdown/emit/block-directive-spelling.ts:27spellBlockDirectiveOpener: the opener's layout is known here and inspellDirectiveOpener - Shape:
src/markdown/portable/adf-to-portable-markdown.ts:231reduceCodeBlock: an ADF-to-ADF reducer carries a markdown length bound through a callback - Navigation:
src/markdown/length-bound.ts:41withinEngineLimits: a too-long refusal leads straight to one small, well-named module
2026-10-12T19:45:45Z, PR #36 at 1f4551a, against 7a27f6b
Ruling: worse
Fell: Locality. Under the floor of 7.0: Locality 5.13, so the same ruling counts as worse.
| Seat | Navigation | Locality | Shape | Self-sufficiency | Overall |
|---|---|---|---|---|---|
| Mid A | better | worse | better | same | same |
| Inherited architect | better | worse | better | same | same |
| Seat | Navigation | Locality | Shape | Self-sufficiency | Overall |
|---|---|---|---|---|---|
| Junior A | 6.5 | 5 | 6 | 5.5 | 5.5 |
| Mid A | 7 | 5 | 6 | 5 | 5.5 |
| Maintainability senior | 7 | 5.5 | 6.5 | 6 | 6 |
| Inherited architect | 6.5 | 5 | 5.5 | 6.5 | 5.5 |
| Mean | 6.75 | 5.13 | 6.00 | 5.75 | 5.63 |
Mid A, decided by:
- Locality:
src/markdown/emit/adf-to-markdown.ts:114commonMarkSpelling: the memo is filled here and read-and-deleted inreadableBlock, a write-once, read-once protocol whose order is set in another module - Locality:
src/markdown/emit/adf-to-markdown.ts:52writeMarkdown: one rule, output pastlongestMarkdownis refused, is checked in six places with different triggers - Navigation, Shape:
src/markdown/length-bound.ts:1tooLong: a too-long refusal leads to one small module holding the bound, its message and the engine guard - Shape:
src/canonical-json.ts:23canonicalJsonPieces: a generator replaces a boolean-returning callback, and both readers become plain loops - Shape, Locality:
src/markdown/portable/adf-to-portable-markdown.ts:128portableSequence: a refused spelling is returned where it is produced, and each block carries its own path - Shape:
src/markdown/emit/inline-line.ts:235emitLeaf: one content-or-text check, and the path is built only to refuse
Inherited architect, decided by:
- Locality:
src/markdown/emit/adf-to-markdown.ts:114commonMarkSpelling: filling and consuming the memo split across an exported predicate and a private reader, a consume-once protocol among three callers - Locality:
src/markdown/emit/adf-to-markdown.ts:52writeMarkdown: one bound enforced at five sites in four files, and a new builder has nothing nearby saying whether it needs a check - Navigation, Shape:
src/markdown/length-bound.ts:1withinEngineLimits: an output-too-long symptom leads straight to a module named for it - Navigation:
src/markdown/parse/markdown-to-adf.ts:47readDocument: the parse takes the same guard as both writers - Shape:
src/canonical-json.ts:23canonicalJsonPieces: plain loops replace a boolean-returning callback - Shape:
src/markdown/emit/inline-line.ts:235emitLeaf: both leaf emitters return a plain emission, the path built only on refusal
Junior A, hardest first:
- Locality:
src/markdown/emit/adf-to-markdown.ts:114commonMarkSpelling: a mutable memo shared by three walks, deleted on read and rebased by depth
Mid A, hardest first:
- Locality:
src/markdown/emit/adf-to-markdown.ts:125readableBlock: shared mutable state with no single owner, parse and emit coupled both ways
Maintainability senior, hardest first:
- Locality:
src/markdown/emit/adf-to-markdown.ts:114commonMarkSpelling: the parser and the portable reducer call into the emitter and share a reference-keyed, delete-on-read memo
Inherited architect, would restructure first:
- Locality:
src/markdown/emit/adf-to-markdown.ts:126readableBlock: the memo is mutated and deleted across parse, emit and portable, and the length bound is applied at five sites
2026-10-13T14:48:38Z, PR #37 at ecd695a, against 7a27f6b
Ruling: worse
| Seat | Navigation | Locality | Shape | Self-sufficiency | Overall |
|---|---|---|---|---|---|
| Mid A | better | worse | better | worse | worse |
| Inherited architect | better | worse | same | worse | worse |
Mid A, decided by:
- Locality, Self-sufficiency:
src/markdown/emit/adf-to-markdown.ts:116commonMarkSpelling/readableBlock/takeKeptSpelling: only commonMarkSpelling fills the memo and a read empties it, so whether an entry exists depends on which caller ran first; the reason lives only behind a pointer to docs/decisions.md - Locality:
src/markdown/emit/line-escaping.ts:229escapeClosedRuns: both steps write one shared Uint8Array, and correctness rests on the scan order a second comment line must defend - Navigation, Shape:
src/markdown/length-bound.ts:30withinEngineLimits: the engine-limit catch moves out of result.ts into one well-named file, with string-length and engine limits apart andengine-limita code of its own - Locality:
src/markdown/emit/adf-to-markdown.ts:51writeMarkdown/walkBlocks/commonMarkSpelling: the length bound is enforced in layers a reader changing it must hold together - Shape:
src/markdown/parse/markdown-to-adf.ts:266directiveNode: undefined is wrapped into a Result to pass the engine guard, then unpicked - Shape:
src/markdown/emit/line-escaping.ts:35Escapings: the type is a lookup function, its comment describes the Uint8Array behind it;backslashedadds 4096-piece chunking - Shape, Locality:
src/canonical-json.ts:23canonicalJsonPieces: a generator replaces a boolean-continue callback - Shape:
src/markdown/emit/inline-line.ts:235emitLeaf: the content-or-text refusal moves into one place - Locality:
src/markdown/portable/adf-to-portable-markdown.ts:128portableSequence: a spelling refusal propagates where it was swallowed, at the cost of Sourced path plumbing
Inherited architect, decided by:
- Locality, Self-sufficiency:
src/markdown/emit/adf-to-markdown.ts:139takeKeptSpelling: reading deletes the entry and only commonMarkSpelling fills it, so readableBlock is right only if another file's caller asked first, once per node; explained only by a pointer to docs/decisions.md - Locality, Shape:
src/markdown/parse/markdown-to-adf.ts:266directiveNode: a second withinEngineLimits inside readDocument's, fed?? success(undefined), so null and undefined carry meaning the reader must remember - Locality:
src/markdown/emit/adf-to-markdown.ts:58walkBlocks: the length bound is enforced at about six sites across three files - Navigation:
src/markdown/length-bound.ts:30withinEngineLimits: engine-limit handling sits in a file named for it, and the engine-limit code parts memory from the length bound - Shape, Locality:
src/markdown/emit/line-escaping.ts:229escapeClosedRuns: mutates its input in place and needs a two-line comment arguing it is safe; output joined in batches of 4096 - Locality, Shape:
src/markdown/portable/adf-to-portable-markdown.ts:128portableSequence: a refusal propagates with its source path, where it was swallowed - Shape:
src/markdown/emit/inline-line.ts:235emitLeaf: one place refuses content and text, and a generator replaces the boolean-callback JSON writer
2026-10-13T15:35:32Z, PR #37 at 025ccc0, against 7a27f6b
Ruling: worse
| Seat | Navigation | Locality | Shape | Self-sufficiency | Overall |
|---|---|---|---|---|---|
| Mid A | better | worse | same | same | worse |
| Inherited architect | better | worse | same | worse | worse |
Mid A, decided by:
- Locality:
src/markdown/emit/adf-to-markdown.ts:58walkBlocks: the length bound is enforced at six sites across four files, each comment giving only its own reason, where one wrapper covered the conversion - Locality:
src/markdown/emit/adf-to-markdown.ts:126readableBlock: the memo is emptied on read and filled only whenasked, so whether a spelling is cached depends on call order and caller - Navigation:
src/markdown/length-bound.ts:1withinEngineLimits: a refused long document leads to a file named for the problem, holding the bound, both throw lists and both messages - Locality:
src/markdown/parse/markdown-to-adf.ts:266directiveNode:success(undefined)andsuccess(null)encode the ask's answer, decoded only by tracing commonMarkSpelling - Shape:
src/canonical-json.ts:23canonicalJsonPieces: a generator replaces a boolean-continue callback - Shape:
src/markdown/emit/line-escaping.ts:38PlacedSegment: segment placements drop the cursor arithmetic two functions repeated - Shape:
src/markdown/emit/line-escaping.ts:113backslashed: byte flags, codes and 4096-piece joins read harder than a character loop - Locality:
src/markdown/portable/adf-to-portable-markdown.ts:128portableSequence: a refused spelling propagates where it was silently swallowed
Inherited architect, decided by:
- Locality:
src/markdown/emit/adf-to-markdown.ts:58walkBlocks: one rule, no markdown past longestMarkdown, is checked at about seven places across four files - Locality, Shape:
src/markdown/emit/adf-to-markdown.ts:126readableBlock: a read deletes the entry and a bare positionalaskedboolean decides what is stored, so results depend on call order - Locality, Self-sufficiency:
src/markdown/emit/line-escaping.ts:113backslashed: flags, byte codes, a lookup closure and batched joins take more passes to read as putting a backslash before characters - Self-sufficiency:
src/markdown/emit/adf-to-markdown.ts:65walkBlocks: the refusal's comment makes sense only once you know V8's limit applies on every engine, which lives in docs/decisions.md; tooLong carries path [] though the walk knows the path - Shape:
src/markdown/length-bound.ts:17tooLong: the length refusal keeps unsupported-node-shape while engine-limit got a name of its own; directiveNode folds three outcomes into one Result to fit the wrapper - Navigation:
src/markdown/length-bound.ts:37withinEngineLimits: the engine guard moves out of the Result module, and engine-limit leads from the symptom to it - Shape, Locality:
src/markdown/portable/adf-to-portable-markdown.ts:128portableSequence: a refusal propagates with its block's path, where it was silently swallowed - Shape:
src/canonical-json.ts:23canonicalJsonPieces: a generator, emitLeaf's one refusal and PlacedSegment each read simpler than before
2026-10-13T15:41:57Z, PR #37 at f1ea9fd, against 7a27f6b
Ruling: same
| Seat | Navigation | Locality | Shape | Self-sufficiency | Overall |
|---|---|---|---|---|---|
| Mid A | better | worse | better | same | same |
| Inherited architect | better | worse | same | same | worse |
| Maintainability senior | better | worse | better | same | same |
| Junior A | better | worse | better | same | same |
Mid A, decided by:
- Locality:
src/markdown/parse/markdown-to-adf.ts:266directiveNode: a second engine guard inside the parse's own, explained by how each engine overflows - Locality:
src/markdown/emit/adf-to-markdown.ts:127readableBlock: a caller flag decides the fill and every read deletes, so what a later call sees depends on who called first - Locality:
src/markdown/emit/adf-to-markdown.ts:66walkBlocks: the length bound is checked at four points, each relying on the others to cover what it skips - Navigation, Shape:
src/markdown/length-bound.ts:37withinEngineLimits: engine and length refusals have their own file and code, and result.ts is back to types - Shape:
src/markdown/length-bound.ts:17tooLong: a string overflow keeps unsupported-node-shape while array and memory take engine-limit, explained only by a comment - Shape, Locality:
src/markdown/portable/adf-to-portable-markdown.ts:128portableSequence: a failed spelling returns early with each block's own path, where it was swallowed - Shape:
src/markdown/emit/adf-to-markdown.ts:117commonMarkSpelling: returns Result, which says what it means, where undefined and success(null) encoded the answer - Shape:
src/canonical-json.ts:23canonicalJsonPieces: a generator replaces a boolean early-stop callback - Shape:
src/markdown/emit/line-escaping.ts:113backslashed: PlacedSegment drops repeated cursor arithmetic, at the cost of byte codes, chunked joins and RunEscapes
Inherited architect, decided by:
- Locality:
src/markdown/emit/adf-to-markdown.ts:126readableBlock: a read deletes and only an asked caller fills, so whether a node is spelled again depends on call order; the first place to rot - Locality, Navigation:
src/markdown/length-bound.ts:36withinEngineLimits: wrap-every-builder is a project-wide duty, and six sites refuse with one message and path [], so a report cannot say which fired - Navigation:
src/markdown/length-bound.ts:1withinEngineLimits: the size concern has a file named for it and engine refusals their own code - Locality:
src/markdown/parse/markdown-to-adf.ts:265directiveNode: a nested engine guard mid-walk, there only to place V8's throw at this directive - Shape:
src/markdown/emit/adf-to-markdown.ts:117commonMarkSpelling: Result tells the truth and a refusal now propagates with its path; line 134's conditional is dense - Shape:
src/markdown/emit/line-escaping.ts:40RunEscapes: byte flags, codes and batched joins read less directly, andescapablereads close to backwards; PlacedSegment is a real gain
Maintainability senior, decided by:
- Navigation, Shape:
src/markdown/length-bound.ts:37withinEngineLimits: guard, bound and refusals share one file, and result.ts is back to describing results - Locality:
src/markdown/emit/adf-to-markdown.ts:127readableBlock: deletes on every read and writes only when asked, so a hit depends on call order across the parser, the portable reduction and the walk - Locality, Self-sufficiency:
src/markdown/parse/markdown-to-adf.ts:266directiveNode: a check's place is justified by where V8 would throw, with a nested engine guard, so moving one needs V8's behaviour reconstructed - Locality:
src/markdown/portable/adf-to-portable-markdown.ts:128portableSequence: a refused spelling comes back as a value with its block's path, where it was swallowed - Shape:
src/markdown/emit/adf-to-markdown.ts:117commonMarkSpelling: Result where absence coded both answers - Shape:
src/markdown/length-bound.ts:17tooLong: a length refusal under unsupported-node-shape with path [], and the README row grown into a catch-all - Shape:
src/markdown/emit/line-escaping.ts:113backslashed: byte codes and chunked joins against PlacedSegment removing duplicated cursor arithmetic, about even - Shape:
src/canonical-json.ts:23canonicalJsonPieces: a generator replaces a boolean-returning callback - Locality:
src/markdown/emit/inline-line.ts:235emitLeaf: the content-or-text refusal is hoisted once, a small gain
Junior A, decided by:
- Navigation, Shape:
src/markdown/length-bound.ts:37withinEngineLimits: the engine-overflow catch moves out of result.ts into a file named for the job, with the two message lists saying which throw means what - Locality:
src/markdown/emit/adf-to-markdown.ts:127readableBlock: a read deletes and a caller flag decides the store, an order dependence across three files - Locality:
src/markdown/parse/markdown-to-adf.ts:266directiveNode: a nested engine guard to pin V8's throw, and the bound checked in five places - Shape, Locality:
src/markdown/emit/adf-to-markdown.ts:117commonMarkSpelling: Result matches its name, and portableSequence propagates a refusal with each block's path - Shape:
src/markdown/emit/line-escaping.ts:38PlacedSegment: replaces a parallel placements array and hand-advanced cursor, against byte codes and chunked joins - Shape:
src/canonical-json.ts:23canonicalJsonPieces: a generator replaces a write callback threading a keep-going flag - Shape:
src/markdown/emit/inline-line.ts:175heldContentOrText: the content-or-text refusal checked once in emitLeaf
2026-10-13T18:05:39Z, PR #37 at 3ba3a82, against 7caa823
Ruling: better
| Seat | Navigation | Locality | Shape | Self-sufficiency | Overall |
|---|---|---|---|---|---|
| Mid A | better | better | better | same | better |
| Inherited architect | better | better | better | better | better |
Mid A, decided by:
- Shape:
src/markdown/emit/adf-to-markdown.ts:117commonMarkSpelling: returns Result, where undefined and success(null) had to be decoded from the callers - Shape, Locality:
src/markdown/parse/markdown-to-adf.ts:266directiveNode: one boolean test where a typed guard, a fallback and an undefined check decoded the tri-state again - Locality:
src/markdown/emit/adf-to-markdown.ts:127readableBlock: every memo read, delete and write sits in one function, where three held its life cycle - Navigation:
src/markdown/length-bound.ts:52engineLimit: an engine-limit refusal has its own code and constructor, where it shared unsupported-node-shape with shape refusals - Shape, Locality:
src/markdown/portable/adf-to-portable-markdown.ts:128portableSequence: one check on spelled.value, and a flatMap replaces listItemBlocks - Locality:
src/markdown/emit/line-escaping.ts:38PlacedSegment: computed once and passed on, where three functions each re-derived starts with their own cursor - Shape:
src/markdown/emit/line-escaping.ts:52escapingCodes: byte codes, flags and a 4096-piece join, and the RunEscapes union, read harder than a plain list
Inherited architect, decided by:
- Navigation, Self-sufficiency:
src/result.ts:2ConvertErrorCode: engine-limit names its cause and points at one function, where the most overloaded code hid whether the document or the runtime failed - Shape, Locality:
src/markdown/emit/adf-to-markdown.ts:117commonMarkSpelling: Result, so directiveNode tests one boolean where it decoded a tri-state - Locality:
src/markdown/emit/adf-to-markdown.ts:127readableBlock: the memo's read, delete and write sit in one function under one comment, at the cost of a caller flag - Shape, Self-sufficiency:
src/markdown/portable/adf-to-portable-markdown.ts:134portableSequence: one boolean test, though the list's own path for its items is now stated only in the README - Locality:
src/markdown/emit/line-escaping.ts:38PlacedSegment: each segment arrives with its start, so two functions no longer walk in step; backslashed itself reads costlier - Shape:
src/markdown/emit/line-escaping.ts:41RunEscapes: its field collides with isEscapable and the call site handles false first, the slowest spot to read - Self-sufficiency:
src/markdown/length-bound.ts:43withinEngineLimits: the stack-overflow comment sits on its line, the carry comment says why the join is bounded
2026-10-13T22:23:11Z, PR #40 at 8d14bbf, against 341280d
Ruling: same
| Seat | Navigation | Locality | Shape | Self-sufficiency | Overall |
|---|---|---|---|---|---|
| Mid A | same | same | better | same | same |
| Inherited architect | same | better | better | same | better |
| Maintainability senior | worse | same | better | same | same |
| Junior A | same | same | better | better | better |
Mid A, decided by:
- Shape:
src/markdown/directive-syntax.ts:109slotFault: both branches return unsupported-node-shape through its constructor, where one small function returned two codes and the old name sounded like a writer's failure
Inherited architect, decided by:
- Shape, Locality:
src/markdown/directive-syntax.ts:109slotFault: one rule with one code, where two branches gave the same kind of problem different codes and the reason lay outside the function - Shape:
src/result.ts:1ConvertErrorCode: the list loses a code named for writing that only the parser raised, so every name matches its producer
Maintainability senior, decided by:
- Shape:
src/markdown/directive-syntax.ts:109slotFault: the two checks raise one code, where sibling refusals of one slot took different codes under a name untrue twice over - Navigation:
README.md:451unsupported-node-shape: a symptom arrives as a code many sites raise, and its longest cell grows, so a reader searches on the message text where one row and one producer led straight there
Junior A, decided by:
- Shape:
src/result.ts:1ConvertErrorCode: the list loses a writer-named code only the parser raised - Shape, Self-sufficiency:
src/markdown/directive-syntax.ts:109slotFault: one code for both branches, and the message states the rule and the fix that lived only in the README
2026-10-13T23:14:24Z, PR #41 at d1dc155, against e0ead52
Ruling: same
| Seat | Navigation | Locality | Shape | Self-sufficiency | Overall |
|---|---|---|---|---|---|
| Mid A | same | same | same | better | same |
| Inherited architect | same | worse | worse | better | worse |
| Maintainability senior | same | same | worse | same | same |
| Junior A | same | same | same | better | same |
Mid A, decided by:
- Self-sufficiency:
src/markdown/directive-syntax.ts:108slotFault: the comment now names the node the emitter carries, where "such" pointed at nothing in view - Self-sufficiency:
src/markdown/portable/conventions.ts:13Claims.pipeTables: the three-valued claim's comment says what each value accepts, so every check in blocks.ts reads without the spec
Inherited architect, decided by:
- Locality, Overall:
src/markdown/parse/blocks.ts:381readBlockLine/openLeaf/openGfmTable/pipeTableRow/pipeTableBlock/bareTableFault: a three-valued claim tested in six places with four comparisons, and no single place states what each mode does to a table - Locality:
src/markdown/parse/blocks.ts:497openGfmTable: cuts the open paragraph through walk.leaf, closes it, then sets walk.leaf again, an order on shared state; its call must precede the pipeCells branch and nothing says so - Shape:
src/markdown/portable/conventions.ts:14Claims.pipeTables:'flavour'names the lossless rule though every reader is a flavour, so=== 'flavour'needs the field's comment to decode - Shape:
src/markdown/parse/blocks.ts:514pipeTableRow: oneifmerges three reasons into "return cells", two of which mean "end the table"; the indentation guard is duplicated at two call sites - Self-sufficiency:
src/markdown/parse/blocks.ts:496openGfmTable,pipeTableRow: each opens with a "GFM, Tables:" line stating the rule it enforces
Maintainability senior, decided by:
- Shape:
src/markdown/portable/conventions.ts:14Claims.pipeTables:'flavour'names only the lossless reader's strict rule though portable is a flavour too, and blocks.ts tests the three states three ways - Locality:
src/markdown/parse/blocks.ts:497openGfmTable: rewrites walk.leaf, closes it, then installs the table, and its call must precede the pipeCells claim and the setext check with no comment saying so - Locality:
src/markdown/parse/blocks.ts:63ParagraphLine: each line keeps its position, where two parallel arrays had to stay the same length
Junior A, decided by:
- Self-sufficiency:
src/markdown/directive-syntax.ts:108slotFault: the comment says on its own which node the emitter carries - Self-sufficiency:
src/markdown/portable/conventions.ts:13Claims.pipeTables: the comment says what each mode reads, so the branches in blocks.ts read without the spec
2026-10-14T08:45:14Z, PR #43 at b83adc4, against e193536
Ruling: worse
| Seat | Navigation | Locality | Shape | Self-sufficiency | Overall |
|---|---|---|---|---|---|
| Mid A | same | worse | worse | same | worse |
| Inherited architect | same | worse | worse | same | worse |
Mid A, decided by:
- Locality:
src/markdown/parse/directive-nodes.ts:140readNamedMark: words its error by deleting; ${directiveEscape}from a fault built in directive-syntax.ts, so rewording that message silently changes this one - Shape, Locality:
src/markdown/parse/directive-nodes.ts:100readMarks/readMarkArray/readNamedMarks/readNamedMark: one attribute's parse now spans four units and three modules, a cursor-driven list parser in a file about directive nodes - Shape:
src/markdown/directive-syntax.ts:299readAttributes/readDirectiveName: exported but left among the private helpers, below the file's export block - Locality:
src/markdown/directive-syntax.ts:69attributeValue: the numbers branch reads a JSON array only for a respelling check that lives in another file
Inherited architect, decided by:
- Locality, Overall:
src/markdown/parse/directive-nodes.ts:140readNamedMark: strips the escape hint with a string replace tied to the wording of pairFault and prefixFault in directive-syntax.ts, which nothing there warns of - Locality, Shape:
src/markdown/parse/directive-nodes.ts:117readNamedMarks/readNamedMark: a grammar inside a quoted attribute value, two levels of escaping held at once, the reader in a file otherwise about building nodes and the writer in block-directive.ts - Shape:
src/adf/mark-attributes.ts:22markVocabularies/markAttributes/isMarkType: markAttributes silently means inline marks beside markVocabularies meaning all, and isMarkType('alignment') is false
2026-10-14T08:45:16Z, PR #43 at b83adc4
| Seat | Navigation | Locality | Shape | Self-sufficiency | Overall |
|---|---|---|---|---|---|
| Junior A | 6.5 | 5 | 6 | 5 | 5.5 |
| Mid A | 6 | 5 | 5.5 | 5 | 5.5 |
| Maintainability senior | 7 | 5.5 | 6.5 | 5.5 | 6 |
| Inherited architect | 7 | 6 | 6 | 6.5 | 6.5 |
| Mean | 6.63 | 5.38 | 6.00 | 5.50 | 5.88 |
Junior A, hardest first:
- Locality, Overall:
src/markdown/parse/markdown-to-adf.ts:237splitPath: builds stand-in nodes and re-runs splitTaskList to find an error path, the comments naming the trick but not why it is correct - Locality, Self-sufficiency:
src/markdown/emit/line-escaping.ts:230escapeClosedRuns/escapeClaims: per-character flags in Uint8Arrays and a backward-filled set of backtick lengths, opaque without the spec open - Locality:
src/markdown/emit/adf-to-markdown.ts:127readableBlock: an identity-keyed memo deleted on read and filled by the parser and the portable writer, action at a distance - Locality:
src/markdown/parse/inline-content.ts:330closeBracket: mutable Scan flags set mid-scan and read later, then a call back into the emitter to decide a parse error - Shape:
src/markdown/emit/inline-line.ts:82emitLine: a retry loop widening a carried index set threaded through nested emitRun calls - Shape:
src/markdown/portable/inline-reduction.ts:194trimmedEdges: two nested fixpoint loops and a number-or-undefined edge depth
Mid A, hardest first:
- Locality, Self-sufficiency:
src/markdown/emit/line-escaping.ts:142escapeClaims/escapeClosedRuns: three passes over a Uint8Array whose conditions tie escaping kind, token kind and position, unverifiable against the spec's prose - Locality:
src/markdown/emit/adf-to-markdown.ts:127readableBlock: filled only on an asked call, deleted on any read, so correctness depends on the order two directions call it - Locality:
src/markdown/parse/markdown-to-adf.ts:237splitPath: stand-in nodes and a re-run split to report an error path - Locality:
src/markdown/emit/inline-line.ts:82emitLine: a fixpoint loop the parser re-enters through openingLinkTakesDirective - Shape:
src/markdown/portable/conventions.ts:24flavourClaims: the switch every reader and writer uses lives under portable/ - Shape:
src/markdown/directive-syntax.ts:32Read: the general reader-failure type defined in the directive grammar file
Maintainability senior, hardest first:
- Locality, Overall:
src/markdown/parse/markdown-to-adf.ts:237splitPath: rebuilds a fake task list to place a refusal, correct only by knowing how splitTaskList and splitPlace move children - Self-sufficiency:
src/markdown/emit/line-escaping.ts:142escapeClaims/escapeClosedRuns: four escaping kinds and three special cases at once, complete only against spec §Canonical form - Locality:
src/markdown/emit/adf-to-markdown.ts:127readableBlock: a reference-keyed memo with delete-on-read and depth rebasing, called from the parser and the portable reducer - Shape:
src/markdown/parse/inline-content.ts:443resolveNodes/pairedHighlights: parallel pieces and nodes arrays, a cursor advanced inside an index expression, and a seven-way Piece union - Shape:
src/markdown/portable/conventions.ts:8Claims: sets all three readers' behaviour yet lives under portable/
Inherited architect, would restructure first:
- Shape, Navigation:
src/markdown/portable/conventions.ts:8Claims/flavourClaims: the switch for all three flavours filed under the portable directory - Locality:
src/markdown/emit/adf-to-markdown.ts:127readableBlock: the parse-to-emit dependency runs through a reference-keyed SpellingMemo shared across calls - Shape:
src/markdown/parse/markdown-to-adf.ts:143quoteNode/splitPath: the portable reader lives in parse/ and reaches back into portable/ - Shape:
src/markdown/emit/adf-to-markdown.ts:157spellPortableBlock: portable-only writing in a file whose name matches neither flavour - Locality:
src/markdown/emit/line-escaping.ts:260unspellableRuns: the 3am unit, concentrated escaping that needs spec §Canonical form and §Marks open to change safely
2026-10-14T13:01:12Z, PR #46 at 1e8fa26, against 06739b40b7
Ruling: better
| Seat | Navigation | Locality | Shape | Self-sufficiency | Overall |
|---|---|---|---|---|---|
| Mid A | better | better | better | same | better |
| Inherited architect | better | better | same | better | better |
Mid A, decided by:
- Locality, Shape:
src/adf/inline-nodes.ts:37takesMark: the per-node mark types say which marks each node takes, and one predicate serves the parser and the emitter where each worked it out differently - Locality:
src/markdown/parse/directive-nodes.ts:138readNamedMark: the caller passes the message it wants instead of cutting text out of another module's message - Locality:
src/markdown/parse/markdown-to-adf.ts:280commonMarkSpellings: a new hand-kept table the parser must keep in step with the emitter'scommonMarkSpelling - Navigation:
src/markdown/emit/inline-line.ts:224carries: "withheld-mark" names the carry the same way as the corpus fixture and the decision index - Shape:
src/markdown/parse/inline-content.ts:405linkPiece: refusals name the fix, thoughmarksItemreturning true for a non-node and the hard-break carve-out read a little harder
Inherited architect, decided by:
- Navigation, Self-sufficiency:
README.md:455unsupported-node-shape: each cause sits beside its own remedy, grouped by direction, where one cell held them all - Locality, Self-sufficiency:
src/adf/inline-nodes.ts:37takesMark: one predicate and a per-type mark list replace a boolean read two ways by the parser and the emitter - Locality:
src/markdown/parse/directive-nodes.ts:137readNamedMark: the caller passes its message rather than editing another module's text - Locality:
src/markdown/parse/markdown-to-adf.ts:279commonMarkSpellings: a hand-kept list of the emitter's CommonMark spellings in another file, where the new version rots first - Shape:
src/markdown/parse/inline-content.ts:294marksItem: reads as a verb phrase and returns true for items no mark lands on - Locality:
src/markdown/parse/inline-content.ts:400linkPiece:linkTo's destination-ahead-of-hard-breaks branch is right only becauselinkPiecerefused every other unlinkable node first, and neither says so - Navigation:
MIGRATION.md:3From 0.2.0 to 0.3.0: a reader starting from a mark lost after upgrading finds a table and a fixture named after the cause
2026-10-14T13:02:45Z, PR #46 at 1e8fa26
| Seat | Navigation | Locality | Shape | Self-sufficiency | Overall |
|---|---|---|---|---|---|
| Junior A | 7 | 5.5 | 6.5 | 5.5 | 6 |
| Mid A | 7 | 5 | 6 | 5 | 5.5 |
| Maintainability senior | 7 | 5.5 | 6.5 | 5.5 | 6 |
| Inherited architect | 6.5 | 6 | 5.5 | 7 | 6 |
| Mean | 6.88 | 5.50 | 6.13 | 5.75 | 5.88 |
Junior A, hardest first:
- Self-sufficiency, Overall:
src/markdown/emit/line-escaping.ts:230escapeClosedRuns/escapeClaims: three parallel per-character arrays and a backward-built set of backtick lengths, opaque without spec §Canonical form open - Locality:
src/markdown/emit/adf-to-markdown.ts:127readableBlock: a memo filled by the parser and the portable reducer and drained by the walk, deleted on read - Locality:
src/markdown/parse/markdown-to-adf.ts:237splitPath: stand-in nodes and a re-run split to place an error path - Locality, Shape:
src/markdown/parse/inline-content.ts:449resolveNodes/pairedHighlights: placeholder text nodes until a highlight pairs, counters and in-place overwrites - Shape:
src/markdown/emit/inline-line.ts:82emitLine: a retry loop whose outcome also flows back into the parser
Mid A, hardest first:
- Locality, Overall:
src/markdown/parse/markdown-to-adf.ts:237splitPath: fake taskList and bulletList stand-ins and a probe node re-run through the split to name a path - Self-sufficiency:
src/markdown/emit/line-escaping.ts:230escapeClosedRuns: why a right-to-left walk suffices lives only in the spec - Locality:
src/markdown/parse/inline-content.ts:332closeBracket/truncatePieces: four sites mutatescan.piecesanddeactivatedBefore - Locality:
src/markdown/emit/adf-to-markdown.ts:127readableBlock: filled from the parser and the portable reducer, the clearest action at a distance - Shape:
src/markdown/portable/inline-reduction.ts:194trimmedEdges: two fixpoint loops with no termination argument and a number-or-undefined edge depth
Maintainability senior, hardest first:
- Self-sufficiency, Overall:
src/markdown/emit/line-escaping.ts:142escapeClaims/unspellableRuns: three passes whose sufficiency no statement gives, and an opening-link signal read from segment structure - Locality:
src/markdown/parse/inline-content.ts:332closeBracket/resolveNodes:Scanmutated from about ten functions over a three-wayInlineunion - Locality:
src/markdown/parse/markdown-to-adf.ts:237splitPath: a local simulation of the task-list split, hard to convince oneself is right - Locality:
src/markdown/emit/adf-to-markdown.ts:127readableBlock: a reference-keyed memo filled across three directories - Shape:
src/markdown/portable/adf-to-portable-markdown.ts:59reduceToPortable: reruns the reduction on the raw document to get a refusal's path
Inherited architect, would restructure first:
- Navigation, Shape:
src/markdown/portable/conventions.ts:8Claims/flavourClaims: the switch for all three flavours filed under portable/ - Navigation:
src/markdown/parse/markdown-to-adf.ts:161quoteNode/splitPath: the portable reader lives in parse/ and the portable writer's spellings inemit/adf-to-markdown.ts:157spellPortableBlock - Locality:
src/markdown/parse/markdown-to-adf.ts:266directiveNode: the reader asks the writer'scommonMarkSpelling, and the writer reuses the reader's tokenizer, so neither side changes alone - Shape:
src/markdown/directive-syntax.ts:32Read: the general reader-failure type housed in the directive grammar file, among 15 loose files insrc/markdown/ - Shape:
src/markdown/emit/adf-to-markdown.ts:45writeMarkdown: writes both flavours in a file named for the lossless one
2026-10-14T19:06:43Z, PR #49 at d8fbff6fde, against 696aca1c71
Ruling: better
| Seat | Navigation | Locality | Shape | Self-sufficiency | Overall |
|---|---|---|---|---|---|
| Mid A | better | better | same | same | better |
| Inherited architect | same | same | worse | same | same |
| Maintainability senior | same | better | same | same | better |
| Junior A | better | same | worse | same | better |
Mid A, decided by:
- Navigation, Locality:
src/adf/inline-nodes.ts:41takenMarkTypes/takesMark: the code-text rule lives in one predicate beside the mark table, reached by the parser, the emitter's carry and the portable reducer - Locality:
src/markdown/parse/inline-content.ts:584highlighted: asksmarksIteminstead of a hand-kept code check - Locality:
src/markdown/portable/inline-reduction.ts:136portableMarks: drops exactly the marks the reader refuses, by the shared name - Locality:
src/markdown/emit/inline-line.ts:103freshFallbacks:carriesno longer shows every reason a node is carried; the set starts pre-filled - Shape, Self-sufficiency:
src/adf/inline-nodes.ts:40takenMarkTypes:undefinedmeans every mark, explained only by its comment; spec says code text takes onlylink
Inherited architect, decided by:
- Shape, Locality:
src/markdown/emit/inline-line.ts:102freshFallbacks: seeds schema carries into a set named for fallbacks, andcarriesno longer says why a node is carried - Locality:
src/adf/inline-nodes.ts:5codeTextMarkTypes: holdscodewith nothing saying why, and spec/flavour.md says code text takes onlylink - Locality:
src/adf/inline-nodes.ts:46takesMark: the answer depends on the node's marks at call time, right only because a code span is built withcodefirst - Locality:
src/markdown/parse/inline-content.ts:584highlighted: one table now answers what two hand-written checks did
Maintainability senior, decided by:
- Locality, Overall:
src/adf/inline-nodes.ts:41takenMarkTypes/takesMark: one function states the code-text rule the parser and emitter both ask;undefinedmeaning every mark is visible only in its comment - Locality:
src/markdown/parse/inline-content.ts:587highlighted: routes throughmarksIteminstead of a private copy of a schema rule - Locality:
src/markdown/portable/inline-reduction.ts:146portableMarks: filters by the shared list, but checkscodeitself rather than askingtakesMark - Locality:
src/markdown/emit/inline-line.ts:103freshFallbacks:carriesis right only if the caller seeded the set, and its comment no longer names withheld marks
Junior A, decided by:
- Navigation, Overall:
src/adf/inline-nodes.ts:5codeTextMarkTypes: the code-text rule lives in one table beside the other inline nodes' table - Shape:
src/adf/inline-nodes.ts:41takenMarkTypes: "taken" reads as accepted or as already held, andundefinedmeans every mark - Shape:
src/markdown/emit/inline-line.ts:103freshFallbacks: named fresh but seeds the carried set, andcarries's comment no longer names the withheld-mark carry
2026-10-14T20:46:20Z, PR #53 at 787d909, against 498e874
Ruling: better
| Seat | Navigation | Locality | Shape | Self-sufficiency | Overall |
|---|---|---|---|---|---|
| Mid A | same | better | better | same | better |
| Inherited architect | better | better | better | same | better |
Mid A, decided by:
- Shape:
src/markdown/emit/inline-line.ts:103withheldMarkFallbacks: renamed fromfreshFallbacks, it now says the fallbacks start seeded with every node holding a withheld mark - Locality:
src/markdown/emit/inline-line.ts:234carries: the comment now nameswithheldMarkFallbacksas where the withheld-mark carries are decided, linking the two units
Inherited architect, decided by:
- Locality, Navigation:
src/markdown/emit/inline-line.ts:234carries: the comment now points atwithheldMarkFallbacksfor the third kind of carry, a hidden dependence made followable - Shape, Navigation:
src/markdown/emit/inline-line.ts:103withheldMarkFallbacks: the old namefreshFallbackshid a pre-seeded set; the new one says what it holds - Shape:
src/markdown/portable/inline-reduction.ts:84mediaLeaves: three branches, two writing[alt](url)by different routes, seen only by readingportableMarks - Self-sufficiency:
src/markdown/portable/inline-reduction.ts:83mediaLeaves: the comment says why an inline image becomes a link, not why the other target goes in parentheses asimage