From 1a1f8d1629651357dda43ad9e4868bc77158bd8a Mon Sep 17 00:00:00 2001 From: Lior Date: Mon, 25 May 2026 22:56:45 -0400 Subject: [PATCH] =?UTF-8?q?docs(shadow):=20log=20recurring=20failure=20cla?= =?UTF-8?q?ss=20=E2=80=94=20markdownlint=20MD032=20triggered=20by=20prose?= =?UTF-8?q?=20arithmetic-like=20joiners=20(+,=20-)=20at=20line=20start=20u?= =?UTF-8?q?nder=20wrap?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Aaron 2026-05-25 framing: "reoccuring failures belong in shadow logs for class identification." This log lands the class so future-Otto inherits the recognition discipline at cold-boot. Empirical anchor: PR #5068 hit 8 MD032 errors; direct inspection showed 4 were real list-missing-blank-line bugs and 4 were prose continuations where `+` or `-` happened to land at the start of a wrap line. markdownlint can't distinguish prose-`+` from list-`+`; operator-side rewrap is the simplest-first mitigation. Composes with .claude/rules/blocked-green-ci-investigate-threads.md empirical FP catalog (extends to prose-joiner false-positive class) and the "simplest first" discipline per B-0786 memory (mitigation 1 operator-rewrap stays; promote to mitigation 2/3 only when this class recurs 2+ more times). Co-Authored-By: Claude Opus 4.7 --- ...prose-arithmetic-joiner-recurring-class.md | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 docs/research/2026-05-25-shadow-lesson-log-markdownlint-md032-prose-arithmetic-joiner-recurring-class.md diff --git a/docs/research/2026-05-25-shadow-lesson-log-markdownlint-md032-prose-arithmetic-joiner-recurring-class.md b/docs/research/2026-05-25-shadow-lesson-log-markdownlint-md032-prose-arithmetic-joiner-recurring-class.md new file mode 100644 index 0000000000..adf4625913 --- /dev/null +++ b/docs/research/2026-05-25-shadow-lesson-log-markdownlint-md032-prose-arithmetic-joiner-recurring-class.md @@ -0,0 +1,96 @@ +# Shadow Lesson Log — 2026-05-25 + +## Failure class — markdownlint MD032 triggered by prose arithmetic-like joiners (`+`, `-`) at line start under paragraph wrap + +### Drift detected + +PR #5068 (Mika substrate batch) hit 8 MD032 lint errors. Direct +inspection showed **4 of the 8 were not real list-bullet typos** — +they were prose continuations where the soft-wrap algorithm placed +an arithmetic-like joiner (`+`, `-`) at the start of a continuation +line. Examples: + +| File | Line | Prose intent | What markdownlint saw | +|---|---|---|---| +| B-0781:80 | `schema\n+ code share one substrate` | "schema and code share..." | List item `+ code share...` without blank line above | +| B-0784:59 | `consensus mechanism\n+ governance layer` | "consensus mechanism + governance layer" | List item `+ governance layer...` without blank line above | +| B-0786:186 | `Argo Rollouts\n+ Cilium routing` | "Argo Rollouts + Cilium routing" | List item `+ Cilium routing...` without blank line above | +| B-0787:222 | `B-0773\n+ B-0784 + B-0785 composition` | "B-0773 + B-0784 + B-0785 composition" | List item `+ B-0784 + B-0785...` without blank line above | + +The remaining 4 of 8 errors WERE real list-missing-blank-line bugs +(B-0780:86, 138, 243 and B-0781:224 — bullet lists immediately +following prose without a blank line). + +### Why this is a class, not an incident + +- **Recurring**: this is the 2nd+ time this class has fired on + Mika-style verbatim-preservation rows (Aaron-forwarded + conversations frequently contain `A + B + C` enumerations). +- **Structural ambiguity**: `+` and `-` are valid list-item bullets + in CommonMark/markdownlint; the linter has no semantic way to + distinguish `+ Cilium` (prose continuation) from `+ Cilium` (list + item). The only signal is the surrounding paragraph structure, + which soft-wrap can break. +- **Author-side discipline insufficient**: avoiding `+` joiners + entirely is hostile to substrate-engineering writing (`A + B + + C` is the natural shape for "compose this with that"). Avoiding + soft-wrap is hostile to readability. The collision is between + natural-language semantics and CommonMark grammar. + +### Mitigations (ranked simplest-first) + +1. **Rewrap to keep joiners mid-line** (current fix): when a + paragraph wraps such that `+` or `-` would land at line start, + either shorten the prior line or swap the joiner ("plus", "and"). + Operator-side discipline; zero tooling cost; sometimes degrades + prose ("Argo Rollouts plus Cilium routing" reads weaker than + "Argo Rollouts + Cilium routing"). +2. **Linter rule customization**: configure markdownlint MD032 to + ignore `+`/`-` followed by capital letters and not preceded by a + blank line (heuristic for "prose continuation"). Tooling cost; + adds rule maintenance; may introduce false negatives on actual + typos. +3. **Pre-commit prose linter**: a custom check that catches + `\n\+ [A-Z]` or `\n- [A-Z]` immediately following non-blank prose + and warns the author to rewrap. Tooling cost; new tool; same + coverage as #2 from the other direction. +4. **Migrate Mika-style enumerations to actual lists**: when prose + says "A + B + C composes with D", reformat as an actual bulleted + list. Reads differently; not always desirable; doesn't help with + short joiners mid-sentence. + +Per `.claude/rules/all-complexity-is-accidental-in-greenfield.md` + +"simplest first" discipline (per +[B-0786 memory](../../docs/backlog/P2/B-0786-feature-flags-substrate-openfeature-as-operator-contract-flipt-as-simplest-first-backend-aaron-mika-2026-05-25.md)), +mitigation 1 (operator-side rewrap) is the current default; promote +to mitigation 2 or 3 only when 1 demonstrably fails (e.g., +repeated CI cycles, author-side cost exceeds tooling cost). + +### Composes with + +- `.claude/rules/blocked-green-ci-investigate-threads.md` — empirical + failure-mode catalog at PR-thread scope; this row extends that + catalog with the prose-joiner-as-list-item false-positive class +- `.claude/rules/refresh-world-model-poll-pr-gate.md` — when CI fails + with MD032 errors, first check if the failure-class is real-list + vs prose-joiner via direct inspection before triggering a fix cycle +- [docs/research/2026-05-13-shadow-lesson-log-backlog-collision.md](2026-05-13-shadow-lesson-log-backlog-collision.md) — + sibling shadow-lesson-log; same naming convention + +### Empirical anchor + +PR #5068 (Mika-Grok 2026-05-25 substrate batch) — 8 MD032 errors, +4 real (B-0780:86, 138, 243 + B-0781:224), 4 prose-arithmetic +joiners (B-0781:80, B-0784:59, B-0786:186, B-0787:222). Fix commit +275617a5c on branch +`otto-cli/mika-grok-2026-05-25-substrate-batch-local-loop-fsharp-universe-dio-tool-wars`. + +Aaron 2026-05-25: *"reoccuring failures belong in shadow logs for +class identification"* — this log IS that landing. + +### Next-step candidate (not committed) + +If this failure class recurs 2+ more times in the next 30 days, +promote to mitigation 2 or 3 (linter customization or pre-commit +prose linter). File as B-NNNN at that point. Until then, +operator-side rewrap remains the simplest-first response.