textmachine/backend/cmd/tmmutate/mutations.json

6993 lines
359 KiB
JSON
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[
{
"id": "A-lock-arbiter",
"why": "the lock bank-apply takes is the same flock a RUN holds; a pin that holds it with LockProject only proves LockProject conflicts with itself",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/store/store.go",
"find": "\tf, err := acquireLock(dbPath + \".lock\")",
"replace": "\tf, err := acquireLock(dbPath + \".lock-not-the-run-lock\")"
}
]
},
{
"id": "B-report-mitigations",
"why": "canonical_rewrite and preexisting_problems are the two published fields the pack's own named risks are mitigated by",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/bankdecisions.go",
"find": "\trep.CanonicalRewrite = rep.CanonicalRewriteDelta || rep.CanonicalRewriteRejects",
"replace": "\trep.CanonicalRewrite = false"
},
{
"file": "internal/pipeline/bankdecisions.go",
"find": "\t\tPreexistingProblems: orEmpty(res.Preexisting),",
"replace": "\t\tPreexistingProblems: []string{},"
}
]
},
{
"id": "C-refusal-table-total",
"why": "a refusal class with no exit number falls into the catch-all 19; the totality gate must enumerate the classes from the SOURCE, constants included",
"package": "./cmd/tmctl/",
"edits": [
{
"file": "internal/pipeline/refusal.go",
"find": "\tRefusalDecisionsRejected RefusalClass = \"decisions_rejected\"",
"replace": "\tRefusalDecisionsRejected RefusalClass = \"decisions_rejected\"\n\n\t// RefusalPlanted is a mutation: a class with no number in refusalExit.\n\tRefusalPlanted RefusalClass = \"planted_class\""
}
]
},
{
"id": "D-decline-normalizes",
"why": "the REPLACEMENT half of a decline must match the surface the way the matcher does — an approval written in the simplified form has to fall to a decline written in the traditional one",
"package": "./internal/membank/",
"edits": [
{
"file": "internal/membank/decisions.go",
"find": "func dropTerms(f *seed.File, src string) []seed.Term {\n\tnk := text.NormalizeSourceKey(src)",
"replace": "func dropTerms(f *seed.File, src string) []seed.Term {\n\tnk := src"
}
]
},
{
"id": "E1-ruby-deep-copy",
"why": "withRubyAliases must copy the alias slices deeply; AttachRubyAliasesToManual appends in place and would reach back into the seed rows the before/after comparison reads again",
"package": "./internal/membank/",
"edits": [
{
"file": "internal/membank/decisions.go",
"find": "\t\te.Aliases = append([]store.GlossaryAlias(nil), e.Aliases...)",
"replace": "\t\t_ = e.Aliases"
}
]
},
{
"id": "E2-promotion-note",
"why": "a promotion carries the owner's note into the delta row",
"package": "./internal/membank/",
"edits": [
{
"file": "internal/membank/decisions.go",
"find": "\tif d.Note != \"\" {\n\t\tt.Note = d.Note\n\t}",
"replace": "\tif false {\n\t\tt.Note = d.Note\n\t}"
}
]
},
{
"id": "E3-unreadable-is-not-undecided",
"why": "an UNREADABLE decision file must stay a loud error; only ABSENT means «nobody has decided anything yet» (the declared-path era is retired, the distinction that survives is absent-vs-unreadable)",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/mining.go",
"find": "\tdefault:\n\t\treturn false, fmt.Errorf(\"pipeline: %s is not readable: %w\", path, err)\n\t}",
"replace": "\tdefault:\n\t\treturn false, nil\n\t}"
}
]
},
{
"id": "F-artifact-paths-absolute",
"why": "the published artifact paths are absolute; a consumer runs in another working directory, so a relative one names a different file",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/status.go",
"find": "\t\tMinedDelta: absPath(r.Book.MinedDelta),",
"replace": "\t\tMinedDelta: r.Book.MinedDelta,"
}
]
},
{
"id": "G-byte-gate",
"why": "the second write gate is the BYTES. UNREACHABLE behind the first: *Touched is set only when a decision changed the document, and `next` is the render of the CHANGED document, so bytes-equal implies nothing-changed implies !*Touched. Kept as depth against a coarser future *Touched and pinned as a function contract (TestChangedDocIsTheSecondFence...), which no source mutation of the CALL can reach.",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/bankdecisions.go",
"find": "\tdelta = res.DeltaBytes != nil && res.DeltaTouched &&\n\t\tchangedDoc(st.deltaRaw, res.DeltaBytes, emptyDelta(res.Delta))",
"replace": "\tdelta = res.DeltaBytes != nil && res.DeltaTouched"
}
],
"expect": "survives"
},
{
"id": "H-decisions-travel-with-the-book",
"why": "the decision files default beside the BOOK, not beside project_db: they are the user's data and must travel with the book directory in a backup or an export",
"package": "./internal/config/",
"edits": [
{
"file": "internal/config/book.go",
"find": "\tb.MinedDelta = filepath.Join(dir, b.BookID+MinedDeltaSuffix)",
"replace": "\tb.MinedDelta = filepath.Join(filepath.Dir(b.ProjectDB), b.BookID+MinedDeltaSuffix)"
}
]
},
{
"id": "I-normalize-text",
"why": "the document the door writes is normalized, which is what keeps a lawful note with a leading newline writable at all",
"package": "./internal/membank/",
"edits": [
{
"file": "internal/seed/normalize.go",
"find": "func normText(s string) string { return strings.TrimSpace(s) }",
"replace": "func normText(s string) string { return strings.TrimLeft(s, \"\") }"
}
]
},
{
"id": "J-render-gate",
"why": "the render PROVES its bytes read back as the same document; without the equality half it only proves they parse",
"package": "./internal/membank/",
"edits": [
{
"file": "internal/membank/decisions.go",
"find": "\tif reflect.DeepEqual(back, doc) {\n\t\treturn b, nil\n\t}",
"replace": "\tif reflect.DeepEqual(back, doc) || true {\n\t\treturn b, nil\n\t}"
}
]
},
{
"id": "K-decision-text-trimmed",
"why": "the door trims the free text it accepts, the same rule it already applies to src/sense/dst",
"package": "./internal/membank/",
"edits": [
{
"file": "internal/membank/decisions.go",
"find": "\t\td.Kind, d.Note = strings.TrimSpace(d.Kind), strings.TrimSpace(d.Note)",
"replace": "\t\td.Kind = strings.TrimSpace(d.Kind)"
}
]
},
{
"id": "L-book-id-is-a-path-element",
"why": "book_id names four files; a separator in it walks the whole set out of the book's directory",
"package": "./internal/config/",
"edits": [
{
"file": "internal/config/book.go",
"find": "\t} else if strings.ContainsAny(b.BookID, `/\\`) || b.BookID == \".\" || b.BookID == \"..\" {",
"replace": "\t} else if false {"
}
]
},
{
"id": "M-owned-paths-distinct",
"why": "two config keys on one path means one document silently overwrites the other",
"package": "./internal/config/",
"edits": [
{
"file": "internal/config/book.go",
"find": "\t\t\tif owned[i].path == \"\" || owned[i].path != owned[j].path {\n\t\t\t\tcontinue\n\t\t\t}",
"replace": "\t\t\tif true {\n\t\t\t\tcontinue\n\t\t\t}"
}
]
},
{
"id": "N-flag-presence",
"why": "the flag guards key on the flag being PRESENT, not on its value being non-empty",
"package": "./cmd/tmctl/",
"edits": [
{
"file": "cmd/tmctl/invocation.go",
"find": "\tif given[\"decisions\"] {",
"replace": "\tif *decisions != \"\" {"
}
]
},
{
"id": "O-reversed-window",
"why": "a chapter window that ends before it begins is written, loads, and fires nowhere",
"package": "./internal/membank/",
"edits": [
{
"file": "internal/membank/decisions.go",
"find": "\tif key.Until != 0 && key.Since > key.Until {",
"replace": "\tif false {"
}
]
},
{
"id": "P-alias-judged-on-the-set",
"why": "an inert decline is judged AFTER the fold, on the result of the whole call: the term that owns the alias may be approved by another decision of the same set (anchor re-pointed when refuseInertDeclines gained its ApplyInput argument; the attacked property — the ORDER of the two phases — is unchanged)",
"package": "./internal/membank/",
"edits": [
{
"file": "internal/membank/decisions.go",
"find": "\tfoldAccepted(in, rs, &res)\n\trefuseInertDeclines(in, rs, &res)",
"replace": "\trefuseInertDeclines(in, rs, &res)\n\tfoldAccepted(in, rs, &res)"
}
]
},
{
"id": "Q-note-not-erased-by-omission",
"why": "a repeat decision that carries no note keeps the note the owner wrote, in BOTH files",
"package": "./internal/membank/",
"edits": [
{
"file": "internal/membank/decisions.go",
"find": "\t\tif note == \"\" {\n\t\t\tnext.Note = r.Note\n\t\t}",
"replace": "\t\tif false {\n\t\t\tnext.Note = r.Note\n\t\t}"
}
]
},
{
"id": "R-decisions-cap",
"why": "the decision document is the one input a USER sizes; uncapped, the engine dies of memory and the platform reads that as a successful run",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/bankdecisions.go",
"find": "\tif len(raw) > maxDecisionsBytes {",
"replace": "\tif false {"
}
]
},
{
"id": "S-stop-writes-nothing",
"why": "a SIGTERM between the decision and the write must leave the files untouched",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/bankdecisions.go",
"find": "\tif err := ctx.Err(); err != nil {\n\t\treturn finishReport(verdict, outcomeStopped, book, st, res, writtenFiles{}), err\n\t}",
"replace": "\tif err := ctx.Err(); err != nil && false {\n\t\treturn finishReport(verdict, outcomeStopped, book, st, res, writtenFiles{}), err\n\t}"
}
]
},
{
"id": "T-problems-by-subject",
"why": "a pre-existing fault is recognised per SUBJECT; joined into one string, fixing one term makes every other term's fault look new",
"package": "./internal/membank/",
"edits": [
{
"file": "internal/membank/decisions.go",
"find": "\t\tif errors.As(err, &sp) {\n\t\t\tproblems = append(problems, sp.Problems...)",
"replace": "\t\tif errors.As(err, &sp) && false {\n\t\t\tproblems = append(problems, sp.Problems...)"
}
]
},
{
"id": "U-signature-honesty",
"why": "a call that leaves surfaces of the signature map undecided must not read as «done»",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/bankdecisions.go",
"find": "\t\tst.Surfaces++\n\t\tif !handled[nk] {\n\t\t\tst.Undecided++\n\t\t}",
"replace": "\t\tst.Surfaces++\n\t\tif !handled[nk] && false {\n\t\t\tst.Undecided++\n\t\t}"
}
]
},
{
"id": "V-manifest-artifacts",
"why": "the artifact envelope reaches the surface the consumer actually calls",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/manifest.go",
"find": "\t\tChunksTotal: len(chunks), Artifacts: r.artifacts(),",
"replace": "\t\tChunksTotal: len(chunks),"
}
]
},
{
"id": "W-decision-count-cap",
"why": "the COUNT of decisions is what holds the call inside a caller's timeout; the byte cap admits ~29 000 minimal declines and five minutes of work",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/bankdecisions.go",
"find": "\tif n := len(doc.Decisions); n > maxDecisions {",
"replace": "\tif n := len(doc.Decisions); false {"
}
]
},
{
"id": "Y-subject-has-no-rendering",
"why": "a fault's subject is the term's IDENTITY; embedding the rendering makes a fault look new the moment the door changes that term's dst — and gender has no channel through which to fix it",
"package": "./internal/membank/",
"edits": [
{
"file": "internal/membank/memseed.go",
"find": "\t\t\t\tSubject: subjectOf(\"gender\", e.Src, e.Sense, e.SinceCh, e.UntilCh),",
"replace": "\t\t\t\tSubject: fmt.Sprintf(\"%s\\u2192%s: gender %q\", e.Src, e.Dst, e.Gender),"
}
]
},
{
"id": "Z-signature-unreadable",
"why": "a signature map that cannot be parsed must not report as «nothing left undecided»",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/bankdecisions.go",
"find": "\t\t// «everything is decided», which is the one answer this field must never give by accident.\n\t\treturn SignatureState{Map: absPath(path), Unreadable: true}\n\t}",
"replace": "\t\t// «everything is decided», which is the one answer this field must never give by accident.\n\t\treturn SignatureState{Map: absPath(path)}\n\t}"
}
]
},
{
"id": "AB-alias-escape",
"why": "a decline is judged by what the surface DOES after the call; the «it was a term of its own» escape let through a decline that leaves the surface firing as another term's alias",
"package": "./internal/membank/",
"edits": [
{
"file": "internal/membank/decisions.go",
"find": "\t\tif owner, held := aliasOwner(res.Delta, r.key.Src); held {",
"replace": "\t\tdroppedARow := false\n\t\tfor _, a := range res.Accepted {\n\t\t\tif a.Index == i {\n\t\t\t\tdroppedARow = len(a.Replaced) > 0\n\t\t\t}\n\t\t}\n\t\tif owner, held := aliasOwner(res.Delta, r.key.Src); held && !droppedARow {"
}
]
},
{
"id": "AC-alias-owner-status",
"why": "only a SIGNED row excludes its surfaces from proposals, so declining the alias of a status:auto row is not inert — and row 199's first format mine is exactly that state",
"package": "./internal/membank/",
"edits": [
{
"file": "internal/membank/decisions.go",
"find": "\t\tif st := strings.TrimSpace(t.Status); st != \"\" && st != \"approved\" {",
"replace": "\t\tif st := strings.TrimSpace(t.Status); st != \"\" && st != \"approved\" && false {"
}
]
},
{
"id": "AD-loader-partial-set",
"why": "the loader hands back the entries it built even when it refuses; without them the checks below it cannot see a document that does not load, and repairing loadability reads as introducing everything the blindness was hiding",
"package": "./internal/membank/",
"edits": [
{
"file": "internal/membank/memseed.go",
"find": "\t\t\t\tfmt.Sprintf(\"term %q: a %s term must have a non-empty dst (an empty one is silently inert; only status=auto may lack a dst)\", t.Src, status))",
"replace": "\t\t\t\tfmt.Sprintf(\"term %q: a %s term must have a non-empty dst (an empty one is silently inert; only status=auto may lack a dst)\", t.Src, status))\n\t\t\tcontinue"
}
]
},
{
"id": "AE-positionless-subject",
"why": "the three «record N has no identity» messages key on a POSITION, which moves when an earlier record is removed; the explicit positionless subject is what keeps a shifted position from reading as a new fault",
"package": "./internal/membank/",
"edits": [
{
"file": "internal/membank/problems.go",
"find": "func (p *problemList) addKeyed(subject, text string) {\n\t*p = append(*p, Problem{Subject: subject, Text: text})\n}",
"replace": "func (p *problemList) addKeyed(subject, text string) {\n\t_ = subject\n\t*p = append(*p, Problem{Subject: text, Text: text})\n}"
}
]
},
{
"id": "AF-keys-file-reason-covers-all",
"why": "the reason a refusal gives must describe the command that receives it; a hand-written list left `bank-apply` — the verb this pack added — undescribed by its own refusal",
"package": "./cmd/tmctl/",
"edits": [
{
"file": "cmd/tmctl/invocation.go",
"find": "The $0 read commands (report/status/export/build/manifest/seed-lint/bank-apply) must not demand provider keys at all (D20.4)",
"replace": "The $0 read commands (report/status/export/build/manifest/seed-lint) must not demand provider keys at all (D20.4)"
}
]
},
{
"id": "AG-stopped-report",
"why": "a call stopped by a signal must not PRINT that it applied — not in mode, not in changed, and not in the accepted list, which is the field a consumer iterates",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/bankdecisions.go",
"find": "\t\trep.Mode, rep.Changed, rep.Accepted = \"stopped\", false, []membank.AcceptedDecision{}",
"replace": "\t\trep.Mode, rep.Changed = \"apply\", true"
}
]
},
{
"id": "AH-signature-read-error",
"why": "a signature map that exists but cannot be READ must not report as «nothing left undecided»",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/bankdecisions.go",
"find": "\t\tif errors.Is(err, fs.ErrNotExist) {\n\t\t\treturn SignatureState{} // no run has reached the bank boundary: nothing to count against\n\t\t}",
"replace": "\t\treturn SignatureState{}"
}
]
},
{
"id": "AI-refused-warns-nothing",
"why": "canonical_rewrite warns about a mutation that is about to happen; a refused call performs none",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/bankdecisions.go",
"find": "\t\trep.Mode, rep.Changed = \"refused\", false\n\t\trep.Signature = signatureState(book, st.seed.Terms, docsFromDisk(st))",
"replace": "\t\trep.Mode, rep.Changed = \"refused\", false\n\t\twarn()\n\t\trep.Signature = signatureState(book, st.seed.Terms, docsFromDisk(st))"
}
]
},
{
"id": "AJ-seed-alias-decline",
"why": "a decline of a seed ALIAS is inert only while the delta has no row of its own for that surface; when it does, the decline drops it and repairs the collision the report is listing (anchor re-pointed when the refusal gained its second carve-out; the attacked property is unchanged)",
"package": "./internal/membank/",
"edits": [
{
"file": "internal/membank/decisions.go",
"find": "held &&\n\t\t\t!deltaHoldsSurface(in.Delta, r.key.Src) && !rejectsHoldSurface(in.Rejects, r.key.Src) {",
"replace": "held && !rejectsHoldSurface(in.Rejects, r.key.Src) {"
}
]
},
{
"id": "FX1-stop-memory-not-recorded",
"why": "a stop that does not RECORD what it presented re-stops on the same map forever — the flag stops paying once per novelty",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/mining.go",
"find": "\tif merr := r.Store.MarkStopPresented(r.Book.BookID, presentedSurfaces(mined)); merr != nil {",
"replace": "\tif merr := r.Store.MarkStopPresented(r.Book.BookID, nil); merr != nil {"
}
]
},
{
"id": "FX2-old-stop-semantics",
"why": "the pre-D39.144 formula — stop on ANY non-empty delta — is the exact regression §4.11 says no test guarded; the flag-model chain must redden on it",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/mining.go",
"find": "\t\tstopping = hasUnpresentedCluster(mined, presented)",
"replace": "\t\tstopping = len(mined) > 0 && len(presented) >= 0"
}
]
},
{
"id": "FX3-memory-by-representative-only",
"why": "a memory keyed on the representative alone re-stops when a cluster's first-ranked member changes to an alias of the same entity",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/mining.go",
"find": "\tfor _, a := range t.Aliases {\n\t\tif nk := text.NormalizeSourceKey(a); nk != \"\" {\n\t\t\tout = append(out, nk)\n\t\t}\n\t}\n\treturn out\n}\n\n// hasUnpresentedCluster",
"replace": "\t_ = t.Aliases\n\treturn out\n}\n\n// hasUnpresentedCluster"
}
]
},
{
"id": "FX4-auto-wire-gated-on-the-flag",
"why": "§4.3: a raised flag on a NON-stopping run must not switch the auto wire off — the unsigned rows must still ride to the editor",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/mining.go",
"find": "\t\tif err := r.writeAutoBank(ctx, mined, proposals, ownerHandled(unsignedEngineSurfaces(seed), rejects)); err != nil {\n\t\t\treturn false, err\n\t\t}",
"replace": "\t\tif !r.VerifyBank {\n\t\t\tif err := r.writeAutoBank(ctx, mined, proposals, ownerHandled(unsignedEngineSurfaces(seed), rejects)); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}"
}
]
},
{
"id": "FX5-normalize-one-trigger",
"why": "the canonical form trims the WHOLE whitespace class, not the one trigger (leading newline) the emitter defect made famous",
"package": "./internal/seed/",
"edits": [
{
"file": "internal/seed/normalize.go",
"find": "func normText(s string) string { return strings.TrimSpace(s) }",
"replace": "func normText(s string) string { return strings.TrimLeft(s, \"\\n\") }"
}
]
},
{
"id": "FX6-subject-collapses-to-class",
"why": "a fault subject without identity lets any pre-existing fault of a class excuse every INTRODUCED fault of that class",
"package": "./internal/membank/",
"edits": [
{
"file": "internal/membank/problems.go",
"find": "\treturn fmt.Sprintf(\"%s|%s|%s|%d|%d\", class, src, sense, since, until)",
"replace": "\treturn class"
}
]
},
{
"id": "FX7-subject-loses-the-window",
"why": "a fault subject without the chapter window masks a new fault on the SAME term in ANOTHER window",
"package": "./internal/membank/",
"edits": [
{
"file": "internal/membank/problems.go",
"find": "\treturn fmt.Sprintf(\"%s|%s|%s|%d|%d\", class, src, sense, since, until)",
"replace": "\treturn fmt.Sprintf(\"%s|%s|%s\", class, src, sense)"
}
]
},
{
"id": "FX8-report-paths-relative",
"why": "the bank-apply report's file paths must be absolute — the consumer runs in its own working directory (the status report pins the same guarantee separately)",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/bankdecisions.go",
"find": "\tif abs, err := filepath.Abs(p); err == nil {\n\t\treturn abs\n\t}\n\treturn p",
"replace": "\treturn p"
}
]
},
{
"id": "FX9-byte-cap-boundary",
"why": "a document of exactly the byte cap is lawful; > tightened to >= refuses it",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/bankdecisions.go",
"find": "\tif len(raw) > maxDecisionsBytes {",
"replace": "\tif len(raw) >= maxDecisionsBytes {"
}
]
},
{
"id": "FX10-count-cap-boundary",
"why": "a document of exactly the count cap is lawful; > tightened to >= refuses it",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/bankdecisions.go",
"find": "\tif n := len(doc.Decisions); n > maxDecisions {",
"replace": "\tif n := len(doc.Decisions); n >= maxDecisions {"
}
]
},
{
"id": "FX12-absolute-paths-not-cleaned",
"why": "an uncleaned absolute path is a second spelling of a guarded path; the acceptance walked through exactly this and reproduced the data-loss blocker",
"package": "./internal/config/",
"edits": [
{
"file": "internal/config/book.go",
"find": "\t\t\treturn filepath.Clean(p)",
"replace": "\t\t\treturn p"
}
]
},
{
"id": "FX13-retired-keys-honoured",
"why": "a declared decision-path key must fail naming the cure, never silently resolve to the convention while the operator believes the declared path is in force",
"package": "./internal/config/",
"edits": [
{
"file": "internal/config/book.go",
"find": "\tif b.RetiredMinedDelta != \"\" || b.RetiredMinedRejects != \"\" {",
"replace": "\tif false && (b.RetiredMinedDelta != \"\" || b.RetiredMinedRejects != \"\") {"
}
]
},
{
"id": "FX14-map-truncated-in-place",
"why": "the signature map is read by the other side of the seam; os.WriteFile truncates first and a live reader gets a half-written map",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/mining.go",
"find": "\tif err := writeFileAtomic(r.signatureMapPath(), mapBytes); err != nil {",
"replace": "\tif err := os.WriteFile(r.signatureMapPath(), mapBytes, 0o644); err != nil {"
}
]
},
{
"id": "FX15-envelope-dropped",
"why": "the map's seam envelope (version + content id) is 17-seam-inbound-law п.3; without it two maps are indistinguishable without a diff",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/membank/decisions.go",
"find": "\tm := seed.SignatureMap{Version: seed.SignatureMapVersion, ID: id, File: content}",
"replace": "\tm := seed.SignatureMap{File: content}\n\t_ = id"
}
]
},
{
"id": "FX16-interleaved-commit",
"why": "§4.8: both documents are STAGED before either rename; committing the first before staging the second re-opens «half landed» for failures staging would catch with zero bytes moved",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/bankdecisions.go",
"find": "\tif rejectsChanged {\n\t\tif rejectsStage, err = stageFileAtomic(book.MinedRejects, res.RejectBytes); err != nil {\n\t\t\tif deltaStage != nil {\n\t\t\t\tdeltaStage.abort()\n\t\t\t}\n\t\t\treturn wrote, err\n\t\t}\n\t}",
"replace": "\tif deltaStage != nil {\n\t\tif err := deltaStage.commit(); err != nil {\n\t\t\treturn wrote, err\n\t\t}\n\t\twrote.delta = true\n\t\tdeltaStage = nil\n\t}\n\tif rejectsChanged {\n\t\tif rejectsStage, err = stageFileAtomic(book.MinedRejects, res.RejectBytes); err != nil {\n\t\t\treturn wrote, err\n\t\t}\n\t}"
}
]
},
{
"id": "FX17-dir-sync-skipped",
"why": "the decision files are the user's words: either the directory entries are flushed or the report says durability is unproven — silence is neither",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/bankdecisions.go",
"find": "\tif err := syncDir(filepath.Dir(book.MinedDelta)); err != nil {\n\t\treturn wrote, fmt.Errorf(\"the files are renamed but their directory entries are not proven durable (a host crash could still lose them): %w\", err)\n\t}",
"replace": "\t_ = syncDir"
}
]
},
{
"id": "FX18-write-incomplete-unmapped",
"why": "a refusal class without a number falls to exit 19 and the consumer loses the one thing the class buys — «re-send the same document»",
"package": "./cmd/tmctl/",
"edits": [
{
"file": "cmd/tmctl/main.go",
"find": "\tpipeline.RefusalDecisionsRejected: exitDecisionsRejected,\n\tpipeline.RefusalWriteIncomplete: exitWriteIncomplete,",
"replace": "\tpipeline.RefusalDecisionsRejected: exitDecisionsRejected,"
}
]
},
{
"id": "FX19-cap-report-dropped",
"why": "§4.7: every refusal of the decisions class prints a report, the caps included — the contract's two carriers must not diverge again",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/bankdecisions.go",
"find": "\t\t\treturn capRefusalReport(book, err), err",
"replace": "\t\t\treturn BankDecisionsReport{}, err"
}
]
},
{
"id": "FX20-write-failed-success-shape",
"why": "the acceptance's repro: EXIT=1 with a success-shaped report over a half-written pair; the write-failed outcome must never print «apply»",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/bankdecisions.go",
"find": "\t\trep.Mode, rep.Changed = \"write_incomplete\", files.delta || files.rejects",
"replace": "\t\trep.Mode, rep.Changed = \"apply\", true"
}
]
},
{
"id": "FX11-window-boundary",
"why": "a single-chapter window (since == until) is a lawful term of one chapter; > tightened to >= refuses it as a reversal",
"package": "./internal/membank/",
"edits": [
{
"file": "internal/membank/decisions.go",
"find": "\tif key.Until != 0 && key.Since > key.Until {",
"replace": "\tif key.Until != 0 && key.Since >= key.Until {"
}
]
},
{
"id": "FX21-dry-run-silently-paid",
"why": "`tmctl translate --dry-run` used to parse cleanly and run a PAID translation — the flag's silent version inverts the one promise (--dry-run = spends nothing) the caller relies on",
"package": "./cmd/tmctl/",
"edits": [
{
"file": "cmd/tmctl/invocation.go",
"find": "\tif given[\"dry-run\"] && cmd != \"bank-apply\" && cmd != \"redrive\" {",
"replace": "\tif false && given[\"dry-run\"] && cmd != \"bank-apply\" && cmd != \"redrive\" {"
}
]
},
{
"id": "FX22-retry-never-reproves-durability",
"why": "the retry the write-incomplete class prescribes lands on the byte-no-op branch; without a directory sync there, the one thing exit 15 warned about is never re-proven and the retry answers 0",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/bankdecisions.go",
"find": "\t\tif err := syncDir(filepath.Dir(book.MinedDelta)); err != nil {\n\t\t\treturn finishReport(verdict, outcomeWriteFailed, book, st, res, writtenFiles{}),\n\t\t\t\trefuse(RefusalWriteIncomplete, fmt.Errorf(\"nothing was written by this call, but the directory holding the decision files still cannot be flushed — their durability is unproven: %w\", err))\n\t\t}",
"replace": "\t\t_ = syncDir"
}
]
},
{
"id": "FX23-map-write-failure-downgraded",
"why": "the map-before-memory ORDER is load-bearing: a run that proceeds past a failed map write stops pointing the owner at a file that is not there and marks the clusters presented — no later flag ever stops on them again (acceptance planting, survived three candidate packages)",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/mining.go",
"find": "\tif err := writeFileAtomic(r.signatureMapPath(), mapBytes); err != nil {\n\t\treturn false, fmt.Errorf(\"pipeline: the bank-mining stop write signature map %s: %w\", r.signatureMapPath(), err)\n\t}",
"replace": "\tif err := writeFileAtomic(r.signatureMapPath(), mapBytes); err != nil {\n\t\tr.Log.WarnContext(ctx, \"pipeline: the bank-mining stop write signature map failed\", \"err\", err)\n\t}"
}
]
},
{
"id": "FX24-write-failed-signature-from-intent",
"why": "the write-failed report must measure the signature against the DISK: fed the call's own result, a class-15 report whose write landed nothing prints undecided:0 — a success-shaped block on the one outcome the honesty work was done for (panel finding, reproduced)",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/bankdecisions.go",
"find": "\t\t// The POST-state, re-read from disk: for an outcome that touched the world the report describes\n\t\t// the files as they now are, never the bytes the call intended.\n\t\trep.Signature = signatureState(book, st.seed.Terms, docsReRead(book))",
"replace": "\t\t// The POST-state, re-read from disk: for an outcome that touched the world the report describes\n\t\t// the files as they now are, never the bytes the call intended.\n\t\trep.Signature = signatureState(book, st.seed.Terms, docsFromResult(st, res))"
}
]
},
{
"id": "SH1-system-join",
"why": "an endpoint that carries ONE system message must receive the memory-bank injection INSIDE that message; without the join the glossary is dropped by the provider at HTTP 200 and no gate can see it",
"package": "./internal/llm/",
"edits": [
{
"file": "internal/llm/httpllm.go",
"find": "\tif mode != SystemMessagesSingle {",
"replace": "\tif true {"
}
]
},
{
"id": "SH2-system-axis-from-yaml",
"why": "the declared quirk has to survive the trip from models.yaml to the resolved Capability; dropped there, the join never runs and the loss is silent again",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/config/models.go",
"find": "\tdefault:\n\t\tc.SystemMessages = llm.SystemMessagesMode(cfg.SystemMessages)\n\t}",
"replace": "\tdefault:\n\t}"
}
]
},
{
"id": "SH3-gap-marker",
"why": "a unit that ships text with a member chunk MISSING must say so in the text a human reads; without the marker the reader gets a seamless concatenation with a hole and no seam",
"package": "./cmd/tmctl/",
"edits": [
{
"file": "cmd/tmctl/render.go",
"find": "\tm := fmt.Sprintf(\"[⚠ TEXT MISSING — %d source %s of this unit could not be translated and %s NOT in the text below\",",
"replace": "\tm := fmt.Sprintf(\"[%d %s %s\","
}
]
},
{
"id": "SH4-dropped-members-counted",
"why": "the incompleteness fact is carried by DroppedMembers, not inferred from a flag reason; stop counting it and both renderers go back to guessing, which is how the reader was told a member drop was a cosmetic clean-up",
"package": "./cmd/tmctl/",
"edits": [
{
"file": "internal/pipeline/export.go",
"find": "\tce.DroppedMembers = len(drops)",
"replace": "\tce.DroppedMembers = 0"
}
]
},
{
"id": "SH5-decline-converges",
"why": "a decline already on the record is a decision being RE-SENT, not one being made; without this carve-out the door refuses the identical document forever and a worker that retries splits the state",
"package": "./internal/membank/",
"edits": [
{
"file": "internal/membank/decisions.go",
"find": " && !rejectsHoldSurface(in.Rejects, r.key.Src) {",
"replace": " {"
}
]
},
{
"id": "SH6-rejects-rename-first",
"why": "the delta is the document the seed-conflict refusal READS, so it must not be the one that lands first: a decline interrupted after a delta-first rename leaves a state no predicate can tell from an inert decline, and the re-send is refused forever",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/bankdecisions.go",
"find": "\tif rejectsStage != nil {\n\t\tif err := rejectsStage.commit(); err != nil {\n\t\t\tif deltaStage != nil {\n\t\t\t\tdeltaStage.abort()\n\t\t\t}\n\t\t\treturn wrote, err\n\t\t}\n\t\twrote.rejects = true\n\t}\n\tif deltaStage != nil {\n\t\tif err := deltaStage.commit(); err != nil {\n\t\t\treturn wrote, err\n\t\t}\n\t\twrote.delta = true\n\t}",
"replace": "\tif deltaStage != nil {\n\t\tif err := deltaStage.commit(); err != nil {\n\t\t\tif rejectsStage != nil {\n\t\t\t\trejectsStage.abort()\n\t\t\t}\n\t\t\treturn wrote, err\n\t\t}\n\t\twrote.delta = true\n\t}\n\tif rejectsStage != nil {\n\t\tif err := rejectsStage.commit(); err != nil {\n\t\t\treturn wrote, err\n\t\t}\n\t\twrote.rejects = true\n\t}"
}
]
},
{
"id": "SH7-drop-reason-is-the-holes-own",
"why": "the marker must name why the MEMBER dropped, not the unit's flag reason: a unit whose edit flagged for a cosmetic strip AND lost a member would otherwise tell the reader a clean-up ate a chunk of the book — the same false claim the pack removes, moved into the prose",
"package": "./cmd/tmctl/",
"edits": [
{
"file": "cmd/tmctl/render.go",
"find": "gapMarker(ce.DroppedMembers, ce.DroppedReason)",
"replace": "gapMarker(ce.DroppedMembers, ce.FlagReason)"
}
]
},
{
"id": "SH8-draft-only-has-no-members",
"why": "a draft-only pipeline makes every chunk a SINGLETON unit whose own draft row is its final row, so the member-drop rule reads the unit's own flag as a lost member; without the guard a cosmetically stripped chunk that lost NOTHING is announced as incomplete — a marker that misinforms, which the order forbids as firmly as the silence it replaces",
"package": "./cmd/tmctl/",
"edits": [
{
"file": "internal/pipeline/export.go",
"find": "\tif r.finalStageWave() == waveEdit {",
"replace": "\tif true {"
}
]
},
{
"id": "SH9-shipped-gemini-declaration",
"why": "the two lines in configs/models.yaml are the ONLY thing that makes the system-message join reach the real endpoint; everything else about the fix is exercised against a synthetic fixture provider, and deleting them used to leave the whole module green",
"package": "./internal/config/",
"edits": [
{
"file": "configs/models.yaml",
"find": " capabilities:\n system_messages: single\n",
"replace": ""
}
]
},
{
"id": "SH10-translate-empty-text-guard",
"why": "renderTranslate's non-empty-text guards are what stop the gap marker pointing at text that does not exist; the code calls them load-bearing and nothing pinned them",
"package": "./cmd/tmctl/",
"edits": [
{
"file": "cmd/tmctl/render.go",
"find": "\t\tcase ch.DroppedMembers > 0 && ch.FinalText != \"\":",
"replace": "\t\tcase ch.DroppedMembers > 0:"
}
]
},
{
"id": "SH11-explicit-multi-costs-nothing",
"why": "writing the DEFAULT out loud must not put a key in the capability the snapshot carries — otherwise a line that changes no byte on the wire re-buys the book",
"package": "./internal/config/",
"edits": [
{
"file": "internal/config/models.go",
"find": "\tcase \"multi\":\n\t\tc.SystemMessages = llm.SystemMessagesMulti",
"replace": "\tcase \"multi\":\n\t\tc.SystemMessages = llm.SystemMessagesMode(\"multi\")"
}
]
},
{
"id": "SH12-declined-never-enters-the-bank",
"why": "the rejects-first rename order leaves the delta row on disk so an interrupted decline can converge; without this filter that window is one in which a PAID run injects a term the owner explicitly declined",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/mining.go",
"find": "\t\t\tif rejects[text.NormalizeSourceKey(e.Src)] {",
"replace": "\t\t\tif false {"
}
]
},
{
"id": "SH13-inert-decline-second-door",
"why": "the ALIAS door refuses an inert decline for its own good reason, but a decline ALREADY on the record is a decision being re-sent; unnarrowed it refused the standing ledger forever and, the layer being all-or-nothing, discarded the lawful decisions sent beside it",
"package": "./internal/membank/",
"edits": [
{
"file": "internal/membank/decisions.go",
"find": "\t\tif rejectsHoldSurface(in.Rejects, r.key.Src) {\n\t\t\tcontinue\n\t\t}\n",
"replace": ""
}
]
},
{
"id": "FC1-book-filter-store",
"why": "CheckpointUsageForBook's `WHERE j.book_id = ?` is the only thing keeping another book's checkpoints out of the consent number when two books share a project database; removing it left every store and money test green (backlog row 197, ФЧ-1 — reproduced by the acceptance), because no fixture had two books at one position",
"package": "./internal/store/",
"run": "TestCheckpointUsageForBookIsScopedToTheBook",
"edits": [
{
"file": "internal/store/ledger.go",
"find": "\t\tWHERE j.book_id = ?\n\t\tORDER BY c.rowid",
"replace": "\t\tWHERE j.book_id = ? OR 1 = 1\n\t\tORDER BY c.rowid"
}
]
},
{
"id": "FC1-book-filter-pipeline",
"why": "the same planting judged where the money is published: another book's calls at the same positions, ten times the price, must not overshoot this book's rows into «quoted from history» or move its projected book cost",
"package": "./internal/pipeline/",
"run": "TestAnotherBooksMoneyNeverEntersTheConsentNumber",
"edits": [
{
"file": "internal/store/ledger.go",
"find": "\t\tWHERE j.book_id = ?\n\t\tORDER BY c.rowid",
"replace": "\t\tWHERE j.book_id = ? OR 1 = 1\n\t\tORDER BY c.rowid"
}
]
},
{
"id": "FC1-cell-key",
"why": "the repricer's cell is the POSITION (chapter AND chunk); keyed by chapter alone it pools the neighbours' calls and the newest-first walk eats the neighbour's money — invisible while every money fixture had one chunk per chapter (backlog row 197, ФЧ-1)",
"package": "./internal/pipeline/",
"run": "TestEveryChunkOfAChapterIsRePricedFromItsOwnCalls",
"edits": [
{
"file": "internal/pipeline/reprice.go",
"find": "\t\tkey := chunkKey{cu.Chapter, cu.ChunkIdx}",
"replace": "\t\tkey := chunkKey{cu.Chapter, 0}"
},
{
"file": "internal/pipeline/reprice.go",
"find": "\tcalls := rp.cells[chunkKey{cs.Chapter, cs.ChunkIdx}][cs.Stage]",
"replace": "\tcalls := rp.cells[chunkKey{cs.Chapter, 0}][cs.Stage]"
}
]
},
{
"id": "FC1-unpriced-not-disclosed",
"why": "a call carried at its billed figure (no usable usage) must mark the row as quoted from history; without the mark the amount stays right and every disclosure of «part of this sum is old money» — consent text, status --json, CLI — goes silent (backlog row 197, ФЧ-1 / ФЧ-4)",
"package": "./internal/pipeline/",
"run": "TestABilledDecodeRowIsDisclosedAsOldMoneyEndToEnd|TestRepricerCountsOnlyTheCurrentGenerationOfCheckpoints",
"edits": [
{
"file": "internal/pipeline/reprice.go",
"find": "\t\tif !calls[i].priced {\n\t\t\tfromHistory = true\n\t\t}\n",
"replace": ""
}
]
},
{
"id": "FC5-carry-unbounded",
"why": "the volume grant admits units an earlier run started and never shipped OUTSIDE the grant, and that carry must be bounded BY the grant; unbounded, a run that drafted a whole book hands every unit to the next purchase and --max-units stops bounding anything (measured on a fixture: a grant of one paid for five units)",
"package": "./internal/pipeline/",
"run": "TestTheCarryIsBoundedByTheGrant",
"edits": [
{
"file": "internal/pipeline/volume.go",
"find": "\t\tif s.stop.Carried >= r.MaxUnits {\n\t\t\ts.stop.LeftFresh++\n\t\t\tcontinue\n\t\t}\n",
"replace": ""
}
]
},
{
"id": "FC5-model-axis-configured-slot",
"why": "the re-payment prices a stored call at the model its stage RESOLVES to (label routing applied), not at the configured `model:` key; reading the configured slot prices a labelled book's re-payment at a model the run never calls, and no other test in the tree tells the two slots apart",
"package": "./internal/pipeline/",
"run": "TestTheModelAxisReadsTheRESOLVEDSlotNotTheConfiguredOne",
"edits": [
{
"file": "internal/pipeline/reprice.go",
"find": "\t\tif escalation && st.ResolvedHop != \"\" {\n\t\t\treturn st.ResolvedHop, true\n\t\t}\n\t\treturn st.ResolvedModel, st.ResolvedModel != \"\"",
"replace": "\t\tif escalation && st.EscalateTo != \"\" {\n\t\t\treturn st.EscalateTo, true\n\t\t}\n\t\treturn st.Model, st.Model != \"\""
}
]
},
{
"id": "FC6-reconcile-fresh-branch",
"why": "reconcile's docstring claims EVERY branch keeps Carried inside Delivered, and granted() = Delivered - Carried + Reworked depends on it; the fresh branch reverted to `Delivered > 0` drives the grant arithmetic negative and prints «0 NEW unit(s) delivered» beside «1 of the new ones had been started by an earlier run» — a sentence that cannot be true",
"package": "./internal/pipeline/",
"run": "TestReconcileKeepsContainmentOnTheFreshBranch",
"edits": [
{
"file": "internal/pipeline/volume.go",
"find": "\t\tcase class == unitFresh && s.stop.Delivered > s.stop.Carried:",
"replace": "\t\tcase class == unitFresh && s.stop.Delivered > 0:"
}
]
},
{
"id": "FC6-capped-refusal-borrows-book-basis",
"why": "the --accept-rebill=<usd> refusal quotes THIS run's figure, so it must carry THIS run's basis; borrowing the book's tells a caller sizing their cap that more units are an upper estimate than the number beside it covers. Its twin, the threshold refusal's scoped clause, was pinned from the start; this branch was not",
"package": "./internal/pipeline/",
"run": "TestTheScopedClauseOfTheRefusalCarriesItsOwnBasis",
"edits": [
{
"file": "internal/pipeline/rebill.go",
"find": "\t\t\tproj.USD, proj.Rows, projectionBasis(proj), r.AcceptRebill.CapUSD, r.AcceptRebill.CapUSD)",
"replace": "\t\t\tproj.USD, proj.Rows, projectionBasis(book), r.AcceptRebill.CapUSD, r.AcceptRebill.CapUSD)"
}
]
},
{
"id": "FC6-model-caveat-printed-at-zero",
"why": "a caveat that prints when its count is zero puts «0 of the N unit(s) were bought from a model their stage no longer resolves to» into EVERY consent text; a reader who learns to skip it skips it when it means something. The old-money twin has had this negative pin since it was written",
"package": "./internal/pipeline/",
"run": "TestProjectionBasisNamesWhatTheAmountIsMadeOf",
"edits": [
{
"file": "internal/pipeline/rebill.go",
"find": "\tif p.ModelMovedRows > 0 {",
"replace": "\tif p.ModelMovedRows >= 0 {"
}
]
},
{
"id": "FC6-escalation-flag-store",
"why": "the re-pricing reads the escalation flag through CheckpointUsageForBook to know that a hop call's «today» is the stage's current escalate_to; dropping the column from the SELECT survives the store's own battery and only the pipeline's goes red — the same one-sided seam the book filter is pinned on both sides for",
"package": "./internal/store/",
"run": "TestCheckpointUsageCarriesTheEscalationFlag",
"edits": [
{
"file": "internal/store/ledger.go",
"find": "\t\t c.cost_usd, c.escalation\n\t\tFROM checkpoints c JOIN jobs j ON j.id = c.job_id",
"replace": "\t\t c.cost_usd, 0\n\t\tFROM checkpoints c JOIN jobs j ON j.id = c.job_id"
}
]
},
{
"id": "FC7-volume-stop-silent-outside-grant",
"why": "a run that finished units an earlier run began delivered MORE than its grant, and the stop line is the only channel that says why; judged by the remainder alone the report goes silent in exactly the case with the largest discrepancy",
"package": "./internal/pipeline/",
"run": "TestARunThatWorkedOutsideItsGrantSaysSo",
"edits": [
{
"file": "internal/pipeline/volume.go",
"find": "func (s *volumeScope) bound() bool { return s != nil && (s.stop.Left() > 0 || s.stop.Carried > 0) }",
"replace": "func (s *volumeScope) bound() bool { return s != nil && s.stop.Left() > 0 }"
}
]
},
{
"id": "FC7-reconcile-free-branch",
"why": "the second fall-through of reconcile must keep Carried inside Delivered too; the guard removed there drives granted() negative on a book with one carried unit and one free unit that flags on resume",
"package": "./internal/pipeline/",
"run": "TestReconcileKeepsCarriedInsideDelivered",
"edits": [
{
"file": "internal/pipeline/volume.go",
"find": "\t\tcase s.stop.Delivered > s.stop.Carried:\n\t\t\ts.stop.Delivered--\n\t\tcase s.stop.Carried > 0:\n\t\t\ts.stop.Delivered--\n\t\t\ts.stop.Carried--\n",
"replace": "\t\tcase s.stop.Delivered > 0:\n\t\t\ts.stop.Delivered--\n"
}
]
},
{
"id": "FC7-zero-usage-row-silent-after-a-move",
"why": "a $0 row with no usage on file cannot be re-priced once its stage resolves elsewhere — there are no tokens to price at the new model; publishing a bare $0 with no caveat is the silent under-quote D39.150 п.1 forbids",
"package": "./internal/pipeline/",
"run": "TestRepriceCheckpointFallsBackToTheBilledAmount",
"edits": [
{
"file": "internal/pipeline/reprice.go",
"find": "\t\t\ttoday, ok := r.currentModelFor(cu.Stage, cu.Escalation)\n\t\t\treturn 0, !ok || today == cu.ModelRequested, false",
"replace": "\t\t\treturn 0, true, false"
}
]
},
{
"id": "FC7-scoped-clause-without-basis",
"why": "the threshold refusal prints the BOOK's figure and THIS run's slice; each travels with the basis of the projection it came from, because which of the slice's units are an upper estimate is not something the book's basis states for them",
"package": "./internal/pipeline/",
"run": "TestTheScopedClauseOfTheRefusalCarriesItsOwnBasis",
"edits": [
{
"file": "internal/pipeline/rebill.go",
"find": "\t\t\tproj.Rows, proj.USD, projectionBasis(proj), scopedRepin)",
"replace": "\t\t\tproj.Rows, proj.USD, scopedRepin)"
},
{
"file": "internal/pipeline/rebill.go",
"find": "would re-pay %d of them, ~$%.6f (%s)%s — but the threshold",
"replace": "would re-pay %d of them, ~$%.6f%s — but the threshold"
}
]
},
{
"id": "FC7-overshoot-claims-a-model-move",
"why": "the revert/overshoot branch quotes a row at what it was BILLED, which is priced at no model's current table; counting it among the units priced across a model move inflates the caveat with rows the caveat does not describe",
"package": "./internal/pipeline/",
"run": "TestRepricerCountsOnlyTheCurrentGenerationOfCheckpoints",
"edits": [
{
"file": "internal/pipeline/reprice.go",
"find": "\t\treturn cs.CostUSD, true, false\n\t}\n\tif residue := cs.CostUSD - accounted; residue > residueEpsilonUSD {",
"replace": "\t\treturn cs.CostUSD, true, moved\n\t}\n\tif residue := cs.CostUSD - accounted; residue > residueEpsilonUSD {"
}
]
},
{
"id": "FC8-free-call-dropped-from-a-paid-generation",
"why": "a call that cost NOTHING can neither complete a row's cost nor overshoot it, so a walk that stops on money drops it — and with it the price that call carries today. A $0 primary whose PAID escalation hop alone accounts for the row (a local model with a cloud fallback) is then quoted at half what the re-run buys, with no caveat: the silent under-quote D39.150 п.1 forbids",
"package": "./internal/pipeline/",
"run": "TestRepricerCountsOnlyTheCurrentGenerationOfCheckpoints",
"edits": [
{
"file": "internal/pipeline/reprice.go",
"find": "\t\tfree := calls[i].then <= residueEpsilonUSD\n\t\tif accounted >= cs.CostUSD-residueEpsilonUSD && !free {",
"replace": "\t\tfree := calls[i].then <= residueEpsilonUSD\n\t\t_ = free\n\t\tif accounted >= cs.CostUSD-residueEpsilonUSD {"
}
]
},
{
"id": "FC8-unestablished-zero-row-published-as-free",
"why": "a $0 row whose newest call on file belongs to an older generation cannot be caught by the overshoot test — no walk overshoots $0 — so without this it is published as a bare $0 with no caveat; a `skipped` row is genuinely free, any other is one whose generation could not be established",
"package": "./internal/pipeline/",
"run": "TestRepricerCountsOnlyTheCurrentGenerationOfCheckpoints",
"edits": [
{
"file": "internal/pipeline/reprice.go",
"find": "\tif taken == 0 && len(calls) > 0 && cs.Disposition != string(DispSkipped) {\n\t\tfromHistory = true\n\t}\n",
"replace": ""
}
]
},
{
"id": "FC8-log-fork-at-the-end-of-the-book",
"why": "the run log takes the same fork as the operator line: a run that reached the end of the book did NOT stop short of it, and saying so of every bounded run makes the sentence worthless exactly where the grant behaved unusually",
"package": "./internal/pipeline/",
"run": "TestTheRunLogSaysWhichKindOfVolumeStopItWas",
"edits": [
{
"file": "internal/pipeline/waverun.go",
"find": "\t\tif scope.stop.Left() == 0 {\n\t\t\tmsg = \"the run reached the end of the book under a VOLUME ceiling that held nothing back; it is reported because units an earlier run began were finished outside this grant\"\n\t\t}\n",
"replace": ""
}
]
},
{
"id": "FC8-empty-cell-disclosed-as-unestablished",
"why": "the «generation could not be established» mark is for a $0 row whose calls belong to somebody else, NOT for a row with no call at all — that one is free by construction; without the guard every such row inflates the count of units the operator is told could not be re-priced",
"package": "./internal/pipeline/",
"run": "TestRepricerCountsOnlyTheCurrentGenerationOfCheckpoints",
"edits": [
{
"file": "internal/pipeline/reprice.go",
"find": "\tif taken == 0 && len(calls) > 0 && cs.Disposition != string(DispSkipped) {",
"replace": "\tif taken == 0 && cs.Disposition != string(DispSkipped) {"
}
]
},
{
"id": "WB1-head-always-end-of-book",
"why": "the stop line's two openings are a fork, and only the NEW opening was held: a fork that reaches the end-of-book wording unconditionally passed the whole tree, and in a run whose grant really did cut it short it printed «reached the END of the book … Still in the book: 1 unit(s) NEVER delivered» — the book is finished and a unit of it was never delivered, in one sentence",
"package": "./internal/pipeline/",
"run": "TestTheStopLineSaysTheGrantHeldWorkBackWhenItDid",
"edits": [
{
"file": "internal/pipeline/volume.go",
"find": "\tif v.Left() == 0 {\n\t\thead = \"reached the END of the book",
"replace": "\tif v.Left() >= 0 {\n\t\thead = \"reached the END of the book"
}
]
},
{
"id": "WB2-head-keyed-on-the-carry",
"why": "the same fork asked about the wrong quantity. Which opening applies is the REMAINDER — did the grant hold work back — not the CARRY, which is why the report is attached at all. Keyed on the carry the fork is right on every state the tree exercised and wrong on the mixed one the carry itself made reachable: work carried AND work held back",
"package": "./internal/pipeline/",
"run": "TestTheStopLineSaysTheGrantHeldWorkBackWhenItDid",
"edits": [
{
"file": "internal/pipeline/volume.go",
"find": "\tif v.Left() == 0 {\n\t\thead = \"reached the END of the book",
"replace": "\tif v.Carried > 0 {\n\t\thead = \"reached the END of the book"
}
]
},
{
"id": "WB3-bound-border-drops-a-single-carry",
"why": "bound() reports a run that did work OUTSIDE its grant, and the smallest such run is ONE interrupted unit finished at the end of the book. A `> 1` border drops exactly that one: the run delivers a unit it never paid a slot for and returns no report at all — the silent limit D39.165 §1б names. The existing carry test finishes TWO units and survives the border",
"package": "./internal/pipeline/",
"run": "TestOneCarriedUnitIsStillWorkOutsideTheGrant",
"edits": [
{
"file": "internal/pipeline/volume.go",
"find": "return s != nil && (s.stop.Left() > 0 || s.stop.Carried > 0) }",
"replace": "return s != nil && (s.stop.Left() > 0 || s.stop.Carried > 1) }"
}
]
},
{
"id": "WB4-cut-tag-drops-the-embedded-data",
"why": "the cut tag rides inside every unit id, and a component dropped from it is invisible by construction — the id still looks like an id while it now points at different text. The embedded language data decides where boundaries fall (CJK numerals, sentence terminators), so without it an injection.txt edit re-cuts the whole book and re-mints nothing. Found by planting: removing it left the ENTIRE battery green, and this pack's point 3 chose the Go render over the data precisely because that component is load-bearing",
"package": "./internal/pipeline/",
"run": "TestTheCutTagActuallyCarriesTheEngineData",
"edits": [
{
"file": "internal/pipeline/manifest.go",
"find": "\t\tChunker: chunkerVersion, Segmentation: r.segmentationSnapshot(), ShippingWave: r.shippingWaveTag(),\n\t\tLangpack: r.packVersion(), Embedded: lang.EmbeddedVersion(), Norm: text.NormVersion(),",
"replace": "\t\tChunker: chunkerVersion, Segmentation: r.segmentationSnapshot(), ShippingWave: r.shippingWaveTag(),\n\t\tLangpack: r.packVersion(), Embedded: \"\", Norm: text.NormVersion(),"
}
]
},
{
"id": "WB5-target-screen-never-sees-the-target",
"why": "the target-language screen must be handed the target's DECLARED scripts; given none it abstains, so the verdict row 46 exists for is never reached. Re-anchored: the assembly of the input moved into one builder (WB33 guards that), so this entry now attacks the screen's own call",
"package": "./internal/pipeline/",
"run": "TestTheRunnerHandsTheScreenItsData",
"edits": [
{
"file": "internal/pipeline/disposition.go",
"find": "if scr := langscreen.Screen(out, in.TargetScripts); scr.Verdict == langscreen.OffTarget {",
"replace": "if scr := langscreen.Screen(out, nil); scr.Verdict == langscreen.OffTarget {"
}
]
},
{
"id": "WB6-off-target-flag-not-escalatable",
"why": "D39.93 п.2 refused to reuse FlagCJKArtifact precisely so the new flag would need an EXPLICIT entry in escalatable(). Without it a caught off-target chunk is silently LOST instead of re-attacked on another model — the failure the whitelist exists to prevent, and the one the design was warned about before the code was written",
"package": "./internal/pipeline/",
"run": "TestAnOffTargetCompletionIsFlaggedAndEscalated",
"edits": [
{
"file": "internal/pipeline/disposition.go",
"find": "\tcase FlagCJKArtifact, FlagOffTargetLang, FlagExcisionSuspect, FlagLoopDegenerate,",
"replace": "\tcase FlagCJKArtifact, FlagExcisionSuspect, FlagLoopDegenerate,"
}
]
},
{
"id": "WB7-bank-role-exemption-narrows-to-one-role",
"why": "the exemption is the role SET: a bank role answers a term table, whose letters are engine identifiers and source terms, so BOTH the echo rule and the target screen fire on every healthy batch. It was `role == roleTerminologist` for as long as no shipping config ran the classifier; row 140 runs it, so the regression goes live with it",
"package": "./internal/pipeline/",
"run": "TestTheRunnerHandsTheScreenItsData",
"edits": [
{
"file": "internal/pipeline/terminologist.go",
"find": "\treturn role == roleTerminologist || role == roleClassifier",
"replace": "\treturn role == roleTerminologist"
}
]
},
{
"id": "WB8-latin-residue-runs-on-a-latin-target",
"why": "the Latin-residue detector reads a run of Latin words as an untranslated leak — true for a Cyrillic target, inverted for a Latin-written one, where it drops every chunk of clean target prose. The guard was declared in a doccomment two layers up for years while standing only on the repair path",
"package": "./internal/checks/",
"run": "TestTheLatinResidueClassIsGatedOnTheTargetsOwnScript",
"edits": [
{
"file": "internal/checks/sanitizer.go",
"find": "\tif c.TargetScriptNonLatin() {\n\t\tif det := detectLatinInsertion(glossMasked); det != \"\" {",
"replace": "\tif true {\n\t\tif det := detectLatinInsertion(glossMasked); det != \"\" {"
}
]
},
{
"id": "WB9-contour-configured-and-inert",
"why": "both bank roles run INSIDE the bank-mining stop, which returns before building a single candidate without a contrast artifact. The loader refuses the unset key; without that refusal a fully budgeted contour is configured and never executes, the class this loader refuses everywhere else",
"package": "./internal/config/",
"run": "TestABankContourThatCanNeverFireIsRefused",
"edits": [
{
"file": "internal/config/pipeline.go",
"find": "\t\tif p.Mining.ContrastPath == \"\" {\n\t\t\tbad(\"gates.terminology is enabled but `mining.contrast_path` is not set",
"replace": "\t\tif false {\n\t\t\tbad(\"gates.terminology is enabled but `mining.contrast_path` is not set"
}
]
},
{
"id": "WB10-missing-contrast-costs-a-wave",
"why": "the run opens the contrast artifact at the bank-mining stop, AFTER the whole draft wave is bought. The write-path preflight is what turns «a deployment forgot the artifact» from a wave's money into a free refusal naming the path",
"package": "./internal/pipeline/",
"run": "TestTheContourRefusesAWriteRunItCannotExecute",
"edits": [
{
"file": "internal/pipeline/runner.go",
"find": "\t\tif err := pipe.CheckMiningContrast(); err != nil {\n\t\t\treturn nil, refuse(RefusalBadConfig, err)\n\t\t}",
"replace": ""
}
]
},
{
"id": "WB11-nil-pack-contour-never-runs",
"why": "the OTHER condition of the same early return, and the one a config loader structurally cannot see: a book with no langpack_root, or one whose pair has no catalog directory, gets a nil pack and the stop returns before any candidate exists. The gate is known to the pipeline and the pack to the book; only the runner holds both",
"package": "./internal/pipeline/",
"run": "TestTheContourRefusesAWriteRunItCannotExecute",
"edits": [
{
"file": "internal/pipeline/runner.go",
"find": "\tif forWrite && r.Pipeline.Gates.Terminology.Enabled && r.pack == nil {",
"replace": "\tif false && r.Pipeline.Gates.Terminology.Enabled && r.pack == nil {"
}
]
},
{
"id": "WB12-two-orders-for-one-term",
"why": "the law block binds a canon to its SOURCE, and one surface legitimately carries several signed senses (the bank's key is (src, sense, since, until)). Deduping on the bare src drops a signature silently while the translator's block still renders both — the regression this entry used to enshrine before the rule was corrected",
"package": "./internal/membank/",
"run": "TestTheLawBlockGivesOneOrderPerSourceTerm",
"edits": [
{
"file": "internal/membank/memory.go",
"find": "\t\tkey := src + \"\\x00\" + dst",
"replace": "\t\tkey := src"
}
]
},
{
"id": "WB13-placeholder-refusal-arrives-after-a-paid-wave",
"why": "Render refuses an unknown placeholder per stage per chunk MID-RUN, so a prompt pack carrying a retired marker fails on the first call of that stage — for an editor prompt, after the whole draft wave is bought (measured on the {{genre}} retirement). The load-time scan makes the same refusal free. 27 eval/ prompt files still carry {{genre}}",
"package": "./internal/pipeline/",
"run": "TestRenderRejectsUnknownPlaceholder",
"edits": [
{
"file": "internal/pipeline/render.go",
"find": "\tif err := CheckPlaceholders(canon); err != nil {\n\t\treturn nil, fmt.Errorf(\"pipeline: prompt %s: %w\", path, err)\n\t}",
"replace": ""
}
]
},
{
"id": "WB14-corpus-softened-until-the-number-looked-good",
"why": "a FIXTURE mutation, and the first this catalogue carries. The 12.87x margin rests on ONE healthy specimen; zeroing its source runes left the whole battery green while REPORTING A BETTER NUMBER than the corpus ever had, because the margin test asserts a floor and a floor is not a measurement. Found by planting into data, which is the half of the method that was missing",
"package": "./internal/pipeline/",
"run": "TestTheCorpusStillHoldsItsHardestSpecimens",
"edits": [
{
"file": "internal/pipeline/testdata/offtarget-corpus.json",
"find": "\"source_script_runes\": 109,\n \"total_runes\": 9352,",
"replace": "\"source_script_runes\": 0,\n \"total_runes\": 9352,"
}
]
},
{
"id": "WB15-screen-floor-slides-inside-its-interval",
"why": "a threshold ratified as a CONTRACT (D39.92 п.1а) was pinned only to an INTERVAL — 0.45 is still inside the corpus's empty band — so a slide re-verdicted a resumed chunk under a threshold nobody re-billed for. Version is derived from the constants, so THIS edit moves the snapshot and the golden catches it. ⚠ THAT IS THE WHOLE OF WHAT THIS ENTRY PROVES: the golden sees a slide, and it CANNOT see a literal that stops tracking the constants — under `literal + slide` the string is byte-identical, the golden does not move and this entry survives. The derivation itself is WB36's, in the langscreen package. An earlier `why` here claimed «the snapshot moves by construction» and read as a guarantee against both",
"package": "./internal/pipeline/",
"run": "TestGoldenDeterminism",
"edits": [
{
"file": "internal/langscreen/langscreen.go",
"find": "const OnTargetFloor = 0.50",
"replace": "const OnTargetFloor = 0.45"
}
]
},
{
"id": "WB16-validator-blesses-what-the-renderer-refuses",
"why": "the load-time gate and the renderer must accept the SAME set. The validator's own copy of that set is gone (it now renders), so this entry attacks what replaced it: a gate that swallows the renderer's unknown-name refusal blesses every word and the pack dies mid-run, after the wave",
"package": "./internal/pipeline/",
"run": "TestTheValidatorAndTheRendererAcceptTheSameSet",
"edits": [
{
"file": "internal/pipeline/render.go",
"find": "\tif _, err := render(tpl, renderVals(RenderVars{Book: &config.Book{}})); err != nil {",
"replace": "\tif _, err := render(tpl, renderVals(RenderVars{Book: &config.Book{}})); err != nil && !strings.Contains(err.Error(), \"unknown placeholder\") {"
}
]
},
{
"id": "WB17-priority-rank-loses-its-disposition-axis",
"why": "priorityRank orders by DISPOSITION and by STATUS, and every fixture correlated them (an auto row is always ambiguous), so dropping the disposition bit passed everything. The state that separates them is two SIGNED rows where one was matched by a collision-prone key — and since row 134 that state decides WHICH of two lawful orders the editor is given",
"package": "./internal/membank/",
"run": "TestTheBudgetKeepsTheTrustworthyMatchFirst",
"edits": [
{
"file": "internal/membank/memory.go",
"find": "\tif p.Disp != Confirmed {\n\t\trank |= 1 << 2\n\t}",
"replace": "\tif false {\n\t\trank |= 1 << 2\n\t}"
}
]
},
{
"id": "WB18-banknote-buys-what-nobody-reads",
"why": "the banknote channel's only consumer is the bank-mining stop; a book that cannot reach it still pays for the term table the pair's prompt asks for on every draft call. Not a refusal — the run is correct and the slice does its own job — but an operator must be told what is being bought",
"package": "./internal/pipeline/",
"run": "TestTheBanknoteChannelSaysWhenNobodyWillReadIt",
"edits": [
{
"file": "internal/pipeline/runner.go",
"find": "\tif forWrite && r.Pipeline.Gates.Banknote.Enabled && (r.pack == nil || r.Pipeline.Mining.ContrastPath == \"\") {",
"replace": "\tif false && r.Pipeline.Gates.Banknote.Enabled && (r.pack == nil || r.Pipeline.Mining.ContrastPath == \"\") {"
}
]
},
{
"id": "WB19-a-prompt-path-routes-around-the-load-gate",
"why": "the load-time placeholder gate covers FOUR paths — a stage, a repair class, and each bank role — and «the check stands once and covers all of them» rested on the funnel's SHAPE, not on any pin. Every one of the four could be routed around it with the whole battery green; the cost is the refusal returning mid-run, after the wave that stage sits behind is bought",
"package": "./internal/pipeline/",
"run": "TestEveryPromptLoadPathRefusesAnUnrenderableTemplate",
"edits": [
{
"file": "internal/pipeline/render.go",
"find": "\tif err := CheckPlaceholders(canon); err != nil {\n\t\treturn nil, fmt.Errorf(\"pipeline: prompt %s: %w\", path, err)\n\t}",
"replace": ""
}
]
},
{
"id": "WB20-law-block-drops-a-second-signature",
"why": "the law block's dedup is about SIGNATURES, not about the surface. Keying it on the bare src discards a signed canon whenever one source term carries two — 青山 the surname and 青山 the direction, which the bank's (src, sense, …) key exists to permit — silently, while the translator's block still rendered both, so the two wires disagreed. A live regression of the dofix, found by an adversarial probe",
"package": "./internal/membank/",
"run": "TestTheLawBlockGivesOneOrderPerSourceTerm",
"edits": [
{
"file": "internal/membank/memory.go",
"find": "\t\tif p.entry.status != \"approved\" && signedSrc[src] {\n\t\t\tcontinue // an unsigned rendering yields to the signed canon of the same surface\n\t\t}",
"replace": "\t\tif seen[src] {\n\t\t\tcontinue\n\t\t}\n\t\tseen[src] = true"
}
]
},
{
"id": "WB21-bank-models-are-not-reachable-models",
"why": "buildClients pre-builds ReachableModels and CheckKeys demands their keys, both at OPEN time. With the bank roles missing from that list a terminologist or classifier model without a key passes the whole preflight and kills the run after the draft wave is bought",
"package": "./internal/config/",
"run": "TestABankModelIsAReachableModel",
"edits": [
{
"file": "internal/config/pipeline.go",
"find": "\tif p.Gates.Terminology.Enabled {\n\t\tif m := p.Gates.Terminology.Model; m != \"\" {",
"replace": "\tif false && p.Gates.Terminology.Enabled {\n\t\tif m := p.Gates.Terminology.Model; m != \"\" {"
}
]
},
{
"id": "WB22-sticky-carry-recomputes-the-trust",
"why": "a carry has no firing key of its own, so recomputing the match-trust from the ROW re-trusts a doubtful match — and since row 134 that hands the model a gender directive for an entity that may not be on the page. Invisible where src IS the firing key, which is every fixture that existed; the separating state is a Han src with a short phonetic ALIAS",
"package": "./internal/membank/",
"run": "TestAStickyCarryKeepsTheTrustOfTheKeyThatFiredIt",
"edits": [
{
"file": "internal/membank/memory.go",
"find": "Disp: carried.Disp, KeyTrusted: carried.KeyTrusted}",
"replace": "Disp: carried.Disp, KeyTrusted: keyTrusted(e, text.NormalizeSourceKey(e.src))}"
}
]
},
{
"id": "WB24-sticky-window-narrows",
"why": "scene inertia carries the previous TWO chunks; at one, a term named in chunk N is gone by N+2 and the injection silently narrows. Survived the first round's plantings and was carried as a finding before it was closed",
"package": "./internal/membank/",
"run": "TestTheStickyWindowIsTwoChunksDeep",
"edits": [
{
"file": "internal/membank/memory.go",
"find": "const StickyDepth = 2",
"replace": "const StickyDepth = 1"
}
]
},
{
"id": "WB25-label-sweep-quietly-stops-covering-a-role",
"why": "the sweep walked only what it FOUND, never what the ledger RECORDS, so dropping a role from it orphaned that role's entry and unpinned its prompt with every test green. The classifier line was added by the pack that made it ship, and removing it again cost nothing",
"package": "./internal/pipeline/",
"run": "TestPromptLabelsPinTheirBytes",
"edits": [
{
"file": "internal/pipeline/promptlabel_test.go",
"find": "\t\t\t\t{\"classifier\", g.ClassifyPromptPath},\n",
"replace": ""
}
]
},
{
"id": "WB26-sticky-records-vanish-from-the-law-block",
"why": "the editor's block claims «every injected record with a rendering», and a term carried by scene inertia into a pronominal chunk is exactly where the editor most needs to know what the book calls it. Excluding carries dropped them from the law with the whole tree green, golden included",
"package": "./internal/membank/",
"run": "TestAStickyRecordIsStillLawForTheEditor",
"edits": [
{
"file": "internal/membank/memory.go",
"find": "\tvar lines []string\n\tseen := map[string]bool{}\n\tfor _, p := range injected {\n\t\tif !p.valid() {\n\t\t\tcontinue\n\t\t}",
"replace": "\tvar lines []string\n\tseen := map[string]bool{}\n\tfor _, p := range injected {\n\t\tif !p.valid() || p.Sticky {\n\t\t\tcontinue\n\t\t}"
}
]
},
{
"id": "WB27-the-stop-sentence-undercounts-what-was-billed",
"why": "the first number an operator reads is «%d paying output unit(s)», and dropping the flagged units out of it under-reports what the run was billed for. The struct's arithmetic was pinned; the SENTENCE, which is what reaches a human, was pinned nowhere",
"package": "./internal/pipeline/",
"run": "TestTheStopSentenceCountsEveryUnitTheRunPaidFor",
"edits": [
{
"file": "internal/pipeline/volume.go",
"find": "\t\tv.MaxUnits, v.Paid()+v.Flagged, v.Delivered, v.Reworked)",
"replace": "\t\tv.MaxUnits, v.Paid(), v.Delivered, v.Reworked)"
}
]
},
{
"id": "WB28-a-free-unit-that-flagged-is-billed",
"why": "reconcile's default branch exists so a unit that rode along at $0 and then flagged is not counted as paid; without it the run invents a charge and reports money spent on nothing that was never spent",
"package": "./internal/pipeline/",
"run": "TestReconcileLeavesUnpaidAndReworkedUnitsAlone",
"edits": [
{
"file": "internal/pipeline/volume.go",
"find": "\t\tdefault:\n\t\t\tcontinue // it was never counted as paid (a free unit that flagged on resume); nothing to move",
"replace": "\t\tdefault:"
}
]
},
{
"id": "WB29-a-flagged-rework-is-counted-twice",
"why": "a re-made unit that flags must LEAVE the rework count as it enters the flagged one; keeping both double-counts the grant and over-reports the paying units by one",
"package": "./internal/pipeline/",
"run": "TestReconcileLeavesUnpaidAndReworkedUnitsAlone",
"edits": [
{
"file": "internal/pipeline/volume.go",
"find": "\t\tcase s.stop.Reworked > 0:\n\t\t\ts.stop.Reworked--",
"replace": "\t\tcase s.stop.Reworked > 0:"
}
]
},
{
"id": "WB30-offtarget-severity-ranked",
"why": "a flag the engine raises must be RANKED, or it becomes the most benign reason in the chapter passport and a chapter in the wrong language reports `length` as its worst problem",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/status.go",
"find": "\tFlagCJKArtifact: 1,\n\tFlagOffTargetLang: 1,\n",
"replace": "\tFlagCJKArtifact: 1,\n"
}
]
},
{
"id": "WB31-cjk-target-unscreened",
"why": "a CJK target must be screened for the LANGUAGE of the answer; putting the screen back under the echo gate leaves ja/zh/ko books judged by nothing",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/disposition.go",
"find": "\t\tif !in.NonProseReply {\n",
"replace": "\t\tif !in.NonProseReply && !isCJKTarget(in.TargetLang) {\n"
}
]
},
{
"id": "WB32-echo-rule-for-cjk-target",
"why": "the ECHO rule must stay OFF for a CJK target — asking «is the output in the source's script» of a →ja book flags every correct chapter",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/disposition.go",
"find": "\t\t\tif !isCJKTarget(in.TargetLang) {\n\t\t\t\tif share := sourceScriptShare(out, in.SourceScripts); share > cjkEchoThreshold {",
"replace": "\t\t\tif true {\n\t\t\t\tif share := sourceScriptShare(out, in.SourceScripts); share > cjkEchoThreshold {"
}
]
},
{
"id": "WB33-classify-input-loses-target-scripts",
"why": "every live classify() call must carry the target's scripts; the builder exists because the second call site forgot them once already",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/chunkrun.go",
"find": "\t\tTargetScripts: lang.LangScripts(r.Book.TargetLang),\n",
"replace": "\t\tTargetScripts: nil,\n"
}
]
},
{
"id": "WB34-unlabelled-preflight-skips-gates",
"why": "the UNLABELLED preflight — the shipping default — must demand the keys of the models the GATES call, or the run buys the draft wave and dies at the gate",
"package": "./internal/config/",
"edits": [
{
"file": "internal/config/models.go",
"find": "\tfor _, mdl := range pipe.gateModels() {\n\t\tneeded[mdl] = struct{}{}\n\t}\n",
"replace": ""
}
]
},
{
"id": "WB35-classifier-model-demanded-when-off",
"why": "a gate that is OFF must not make a book hold a key it never uses; the classifier model is reachable only when the classify phase is on",
"package": "./internal/config/",
"edits": [
{
"file": "internal/config/pipeline.go",
"find": "\t\tif p.Gates.Terminology.ClassifyTypes {\n\t\t\tif m := p.Gates.Terminology.ClassifierModel(); m != \"\" {",
"replace": "\t\tif true {\n\t\t\tif m := p.Gates.Terminology.ClassifierModel(); m != \"\" {"
}
]
},
{
"id": "WB36-langscreen-version-literal",
"why": "the screen's version must be DERIVED from its constants. ⚠ TWO edits, and both are the entry: the literal ALONE is harmless (it prints what the derivation prints) and the slide alone moves the derived string honestly. Only together do they reproduce the finding — the floor slides 0.50→0.45 while the version stays byte-identical, so a resumed chunk is re-verdicted under a threshold nobody re-billed for. An earlier version of this entry carried the SLIDE ONLY under this name, and passed for a pin it was not: it reddened the boundary fixture, never the derivation",
"package": "./internal/langscreen/",
"edits": [
{
"file": "internal/langscreen/langscreen.go",
"find": "var Version = fmt.Sprintf(\"langscreen-v1-target-script-share+floor%.2f+min%d\", OnTargetFloor, MinLetters)",
"replace": "var Version = fmt.Sprint(\"langscreen-v1-target-script-share+floor0.50+min200\")"
},
{
"file": "internal/langscreen/langscreen.go",
"find": "const OnTargetFloor = 0.50",
"replace": "const OnTargetFloor = 0.45"
}
]
},
{
"id": "WB37-langscreen-floor-subprecision",
"why": "the version's floor field must be able to EXPRESS the floor: a slide inside the last printed decimal moves no snapshot at all",
"package": "./internal/langscreen/",
"edits": [
{
"file": "internal/langscreen/langscreen.go",
"find": "const OnTargetFloor = 0.50",
"replace": "const OnTargetFloor = 0.504"
}
]
},
{
"id": "WB38-langscreen-boundary-flip",
"why": "«below the floor is off target» is the rule; a comparison that quietly becomes «at or below» changes verdicts and moves no constant",
"package": "./internal/langscreen/",
"edits": [
{
"file": "internal/langscreen/langscreen.go",
"find": "\tif share < OnTargetFloor {",
"replace": "\tif share <= OnTargetFloor {"
}
]
},
{
"id": "WB39-load-gate-scans-system-only",
"why": "the load gate must scan the WHOLE prompt file: a retired marker in the user tail or a few-shot block otherwise loads clean and fails inside Render, after the wave",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/render.go",
"find": "\tif err := CheckPlaceholders(canon); err != nil {",
"replace": "\tif err := CheckPlaceholders(t.System); err != nil {"
}
]
},
{
"id": "WB40-sticky-carry-disp-recomputed",
"why": "a sticky carry has no firing key of its own, so BOTH halves are inherited; recomputing the disposition from the row's own surface is the D16.2 upgrade in the other half's coat",
"package": "./internal/membank/",
"edits": [
{
"file": "internal/membank/memory.go",
"find": "Disp: carried.Disp, KeyTrusted: carried.KeyTrusted}",
"replace": "Disp: dispositionFor(e, text.NormalizeSourceKey(e.src)), KeyTrusted: carried.KeyTrusted}"
}
]
},
{
"id": "WB41-signed-set-keyed-on-disposition",
"why": "signature is a STATUS, not a confidence: a signed row that fired on a doubtful key is still the canon others yield to",
"package": "./internal/membank/",
"edits": [
{
"file": "internal/membank/memory.go",
"find": "\t\tif p.valid() && p.entry.status == \"approved\" && strings.TrimSpace(p.entry.dst) != \"\" {",
"replace": "\t\tif p.valid() && p.Disp == Confirmed && strings.TrimSpace(p.entry.dst) != \"\" {"
}
]
},
{
"id": "WB42-only-draft-yields-to-canon",
"why": "what yields to a signed canon is every UNSIGNED status, `auto` included — `auto` is what the miner writes, i.e. the row the rule exists to subordinate",
"package": "./internal/membank/",
"edits": [
{
"file": "internal/membank/memory.go",
"find": "\t\tif p.entry.status != \"approved\" && signedSrc[src] {",
"replace": "\t\tif p.entry.status == \"draft\" && signedSrc[src] {"
}
]
},
{
"id": "WB46-runner-reachable-stage-only",
"why": "the runner's eager client map must cover the models a GATE calls; a miss there is not a fallback, it is the run dying after the draft wave is paid for",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/runner.go",
"find": "\treturn r.Pipeline.ReachableModels()\n",
"replace": "\tvar out []string\n\tfor _, st := range r.Pipeline.Stages {\n\t\tout = append(out, st.ResolvedModel)\n\t}\n\treturn out\n"
}
]
},
{
"id": "WB47-flagged-clause-prints-rework",
"why": "the operator sentence's FLAGGED count must be the flagged count: it printed the rework count with the whole tree green, because both fixtures had them equal",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/volume.go",
"find": "re-attacks a flag)\", v.Flagged)",
"replace": "re-attacks a flag)\", v.Reworked)"
}
]
},
{
"id": "WB48-mined-rows-admitted-to-base-bank",
"why": "the DRAFT wave selects over the base bank (Source:mined excluded) — that is what makes «one re-payment» honest at the WIRE level and not only in the version hash",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/bankmaterialize.go",
"find": "\t\tif row.Source == \"mined\" {\n\t\t\thasMined = true\n\t\t\tcontinue\n\t\t}",
"replace": "\t\tif row.Source == \"mined\" {\n\t\t\thasMined = true\n\t\t}"
}
]
},
{
"id": "WB43-law-block-single-pass",
"why": "the law block must not depend on the input ORDER: a single pass that records signatures as it goes keeps whichever row arrived first, and passes every fixture because Select sorts the signed row to the front in production",
"package": "./internal/membank/",
"edits": [
{
"file": "internal/membank/memory.go",
"find": "\tsignedSrc := map[string]bool{}\n\tfor _, p := range injected {\n\t\tif p.valid() && p.entry.status == \"approved\" && strings.TrimSpace(p.entry.dst) != \"\" {\n\t\t\tsignedSrc[strings.TrimSpace(p.entry.src)] = true\n\t\t}\n\t}\n",
"replace": "\tsignedSrc := map[string]bool{}\n"
},
{
"file": "internal/membank/memory.go",
"find": "\t\tif p.entry.status != \"approved\" && signedSrc[src] {\n\t\t\tcontinue // an unsigned rendering yields to the signed canon of the same surface\n\t\t}",
"replace": "\t\tif p.entry.status == \"approved\" && strings.TrimSpace(p.entry.dst) != \"\" {\n\t\t\tsignedSrc[src] = true\n\t\t}\n\t\tif p.entry.status != \"approved\" && signedSrc[src] {\n\t\t\tcontinue // an unsigned rendering yields to the signed canon of the same surface\n\t\t}"
}
]
},
{
"id": "WB44-corpus-second-hardest-softened",
"why": "the corpus ledger must pin the POPULATION, not one extremum per axis: every hard specimen but the worst could otherwise be softened with every test green",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/testdata/offtarget-corpus.json",
"find": " \"id\": \"ca9277ac34ae\",\n \"label\": \"healthy\",\n \"source_script_runes\": 42,",
"replace": " \"id\": \"ca9277ac34ae\",\n \"label\": \"healthy\",\n \"source_script_runes\": 0,"
}
]
},
{
"id": "WB45-corpus-offtarget-side-drifts",
"why": "the empty band the 0.50 floor sits in has TWO sides: the off-target extremum was compared constant-to-constant, so the data could drift to 0.49 with every corpus test green and the floor would sit on top of a specimen",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/testdata/offtarget-corpus.json",
"find": " \"id\": \"33affac80ec5\",\n \"label\": \"off_target\",\n \"source_script_runes\": 0,\n \"total_runes\": 5990,\n \"letters\": 4690,\n \"target_script_letters\": 0,",
"replace": " \"id\": \"33affac80ec5\",\n \"label\": \"off_target\",\n \"source_script_runes\": 0,\n \"total_runes\": 5990,\n \"letters\": 4690,\n \"target_script_letters\": 2300,"
}
]
},
{
"id": "WB49-empty-canon-swallows-the-term",
"why": "a signed row with NO rendering orders nothing, so nothing may yield to it — otherwise the unsigned rendering is dropped in favour of a row that prints no line and the term leaves the law block entirely",
"package": "./internal/membank/",
"edits": [
{
"file": "internal/membank/memory.go",
"find": "\t\tif p.valid() && p.entry.status == \"approved\" && strings.TrimSpace(p.entry.dst) != \"\" {",
"replace": "\t\tif p.valid() && p.entry.status == \"approved\" {"
}
]
},
{
"id": "WB50-signed-set-untrimmed-src",
"why": "the signature set and the lookup must normalize the surface the same way; recorded untrimmed and looked up trimmed, the set silently stops matching and every unsigned row of that surface becomes law again",
"package": "./internal/membank/",
"edits": [
{
"file": "internal/membank/memory.go",
"find": "\t\t\tsignedSrc[strings.TrimSpace(p.entry.src)] = true",
"replace": "\t\t\tsignedSrc[p.entry.src] = true"
}
]
},
{
"id": "WB51-flag-reason-declared-elsewhere",
"why": "every FlagReason the engine declares must be RANKED; the exhaustiveness test used to read one file, so a reason declared anywhere else fell to the unknown bucket while the test still said «every declared reason is ranked»",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/status.go",
"find": "const severityUnknown = 9\n",
"replace": "const severityUnknown = 9\n\n// planted\nconst FlagPlantedElsewhere FlagReason = \"planted_elsewhere\"\n"
}
]
},
{
"id": "WB52-builder-hardcodes-the-target",
"why": "the classify input's target must come from the BOOK; a hard-coded target makes every book judged as the shipping pair, and no runner fixture translates into anything but Russian, so nothing else can see it",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/chunkrun.go",
"find": "\t\tTargetLang: r.Book.TargetLang,\n",
"replace": "\t\tTargetLang: \"ru\",\n"
}
]
},
{
"id": "WB53-builder-hardcodes-target-scripts",
"why": "the target's scripts must come from the BOOK's target: hard-coded, a →ja book is screened against Cyrillic and every correct chapter is off-target",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/chunkrun.go",
"find": "\t\tTargetScripts: lang.LangScripts(r.Book.TargetLang),\n",
"replace": "\t\tTargetScripts: lang.LangScripts(\"ru\"),\n"
}
]
},
{
"id": "WB54-builder-hardcodes-source-scripts",
"why": "the source's scripts must come from the RUN's compiled checkers: hard-coded to zh, the echo rule measures the wrong script for every other source language",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/chunkrun.go",
"find": "\t\tSourceScripts: r.checkers.SourceScripts(),\n",
"replace": "\t\tSourceScripts: lang.LangScripts(\"zh\"),\n"
}
]
},
{
"id": "WB56-labelled-preflight-skips-gates",
"why": "the LABELLED branch of CheckKeys must demand the keys of the models the gates call: it was pinned only by the reachable LIST, which is exactly the thing «a pin on the list is not a pin on the preflight» rejects",
"package": "./internal/config/",
"edits": [
{
"file": "internal/config/models.go",
"find": "\t\tfor _, mdl := range pipe.ReachableModels() {\n\t\t\tneeded[mdl] = struct{}{}\n\t\t}\n\t\treturn m.checkKeysFor(needed)",
"replace": "\t\tfor _, st := range pipe.Stages {\n\t\t\tneeded[st.ResolvedModel] = struct{}{}\n\t\t}\n\t\treturn m.checkKeysFor(needed)"
}
]
},
{
"id": "WB57-banknote-warning-loses-the-pack-arm",
"why": "the banknote warning fires when EITHER mining input is missing; keyed on the contrast artifact alone, a book with a pack and no contrast pays for a term table nobody reads and is told nothing",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/runner.go",
"find": "(r.pack == nil || r.Pipeline.Mining.ContrastPath == \"\")",
"replace": "(r.Pipeline.Mining.ContrastPath == \"\")"
}
]
},
{
"id": "WB58-banknote-warning-loses-the-contrast-arm",
"why": "the mirror arm: keyed on the pack alone, a book with a contrast artifact and no langpack pays for the same unread table in silence",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/runner.go",
"find": "(r.pack == nil || r.Pipeline.Mining.ContrastPath == \"\")",
"replace": "(r.pack == nil)"
}
]
},
{
"id": "WB59-banknote-warning-fires-on-a-read-open",
"why": "a $0 read path buys nothing, so warning there teaches an operator to ignore the line on the run where it costs money",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/runner.go",
"find": "\tif forWrite && r.Pipeline.Gates.Banknote.Enabled && (",
"replace": "\tif r.Pipeline.Gates.Banknote.Enabled && ("
}
]
},
{
"id": "WB60-volume-report-decided-after-reconcile",
"why": "the volume report is decided BEFORE reconcile trues the counters up: decided after, a run whose only work outside its grant was a carried unit that came back FLAGGED has Carried==0 and reports nothing at all — the one run that most needs the disclosure goes silent. ⚠ Run-filtered: this planting also strips the report from the DRAFT-ONLY path, which three neighbouring tests catch for a different reason (they lose the report entirely, not out of order). Unfiltered it would go red without proving anything about this pin. WB64 is the faithful both-paths form",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/waverun.go",
"find": "\tif scope.bound() {\n\t\tres.Volume = &scope.stop\n",
"replace": "\tif scope.bound() {\n"
},
{
"file": "internal/pipeline/waverun.go",
"find": "\tscope.reconcile(res.Chunks)\n\tr.Log.InfoContext(ctx, \"book run finished\", \"book\"",
"replace": "\tscope.reconcile(res.Chunks)\n\tif scope.bound() {\n\t\tres.Volume = &scope.stop\n\t}\n\tr.Log.InfoContext(ctx, \"book run finished\", \"book\""
}
],
"run": "TestTheVolumeReportIsAskedBeforeTheCountersAreTruedUp"
},
{
"id": "WB55-corpus-provenance-swapped",
"why": "the corpus digest must cover the ADDRESS a specimen was taken from, not only its counts: a corpus whose numbers are right and whose provenance is wrong is unreproducible in the one way that matters",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/testdata/offtarget-corpus.json",
"find": "\"provenance\": \"probe-4axes/arms/backups/20260902T075308Z.db#draft\",\n \"head\": \"Рассечение камня",
"replace": "\"provenance\": \"planted/not-the-address-it-came-from.db#draft\",\n \"head\": \"Рассечение камня"
}
]
},
{
"id": "WB61-builder-hardcodes-the-fixtures-own-pair",
"why": "a hard-code to the FIXTURE'S OWN pair is the hole a value-comparing test cannot see: the earlier pin asserted the builder's output against values chosen for one book, so it caught a hard-code to the shipping pair and would have sailed past a hard-code to the pair the test itself uses. Only «two books must answer differently» is unsatisfiable by any constant. ⚠ Run-filtered on purpose: a hard-code to `ja` also breaks twenty ru fixtures, so an unfiltered entry would go red without proving anything about THIS pin. The dangerous hard-code is the one to the SHIPPING pair (WB52), which nothing else sees",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/chunkrun.go",
"find": "\t\tTargetLang: r.Book.TargetLang,\n",
"replace": "\t\tTargetLang: \"ja\",\n"
}
],
"run": "TestClassifyInputForLeavesNoAxisUnset"
},
{
"id": "WB62-innocent-const-must-not-be-accused",
"expect": "survives",
"why": "THE BOUNDARY OF TestEveryFlagReasonIsRanked, recorded because the test used to cross it. An ordinary untyped string constant sitting in the FlagReason block is NOT a flag — Go types it as untyped string, inheriting nothing — and the walk must ignore it. An earlier version carried the previous spec's type forward and failed the test with a message accusing a documentation URL of being an unranked flag. A test that accuses the innocent is not enforcing its own sentence, so this planting MUST survive",
"package": "./internal/pipeline/",
"run": "TestEveryFlagReasonIsRanked",
"edits": [
{
"file": "internal/pipeline/disposition.go",
"find": "\tFlagSanitizerStripped FlagReason = \"sanitizer_stripped\"\n",
"replace": "\tFlagSanitizerStripped FlagReason = \"sanitizer_stripped\"\n\n\t// not a flag: a documentation pointer that happens to live in this block\n\tflagReasonDocURL = \"https://example.invalid/flags\"\n"
}
]
},
{
"id": "WB63-run-compiles-a-constant-source",
"why": "the run's declared SOURCE scripts must come from the book. This is the WRITER of the axis whose reader was pinned one commit earlier — pinning the reader alone left the whole axis decided by an unguarded line, and a constant here gives a ko→ru or ja→ru book the wrong declared source while the echo detector measures a script the book does not use",
"package": "./internal/pipeline/",
"run": "TestTheRunCompilesTheBooksOwnSourceScripts",
"edits": [
{
"file": "internal/pipeline/runner.go",
"find": "\t\tr.checkers.SetSourceScripts(lang.LangScripts(r.Book.SourceLang))\n",
"replace": "\t\tr.checkers.SetSourceScripts(lang.LangScripts(\"ja\"))\n"
}
]
},
{
"id": "WB64-volume-report-after-reconcile-on-both-paths",
"why": "the FAITHFUL form of the ordering defect: the decision moved after reconcile on BOTH the draft-only and the editor path, so no neighbour loses its report for an unrelated reason. Only a fixture whose single unit is carried AND flagged can tell the two orders apart, and until this entry existed the draft-only path had none",
"package": "./internal/pipeline/",
"run": "TestTheVolumeReportIsAskedBefore",
"edits": [
{
"file": "internal/pipeline/waverun.go",
"find": "\tif scope.bound() {\n\t\tres.Volume = &scope.stop\n",
"replace": "\tif scope.bound() {\n"
},
{
"file": "internal/pipeline/waverun.go",
"find": "\t\tscope.reconcile(res.Chunks)\n\t\tr.Log.InfoContext(ctx, \"book run finished (draft-only)\"",
"replace": "\t\tscope.reconcile(res.Chunks)\n\t\tif scope.bound() {\n\t\t\tres.Volume = &scope.stop\n\t\t}\n\t\tr.Log.InfoContext(ctx, \"book run finished (draft-only)\""
},
{
"file": "internal/pipeline/waverun.go",
"find": "\tscope.reconcile(res.Chunks)\n\tr.Log.InfoContext(ctx, \"book run finished\", \"book\"",
"replace": "\tscope.reconcile(res.Chunks)\n\tif scope.bound() {\n\t\tres.Volume = &scope.stop\n\t}\n\tr.Log.InfoContext(ctx, \"book run finished\", \"book\""
}
]
},
{
"id": "WB65-labelled-preflight-skips-the-hop",
"why": "a labelled run CALLS its escalation hop, and BuildClient never refuses an empty key — it only becomes a header. A preflight blind to the hop lets the book open, buy the draft wave and 401 at the escalation: the same late failure as the gates, one field over",
"package": "./internal/config/",
"run": "TestTheLABELLEDPreflightDemandsEveryCallersKeyToo",
"edits": [
{
"file": "internal/config/pipeline.go",
"find": "\t\tadd(st.ResolvedHop)\n",
"replace": ""
}
]
},
{
"id": "WB66-preflight-demands-the-configured-not-the-resolved-model",
"why": "routing is what a labelled book is FOR: the model in the yaml may not be the model that answers. A preflight that demands the CONFIGURED model passes a book whose RESOLVED model has no key, and the refusal moves from open time to the first draft call",
"package": "./internal/config/",
"run": "TestTheLABELLEDPreflightDemandsEveryCallersKeyToo",
"edits": [
{
"file": "internal/config/pipeline.go",
"find": "\t\tadd(st.ResolvedModel)\n",
"replace": "\t\tadd(st.Model)\n"
}
]
},
{
"id": "WB67-flag-reason-in-the-conversion-spelling",
"why": "`X = FlagReason(\"…\")` is as ordinary a declaration as `X FlagReason = \"…\"`, and a walk that reads only the spec's type is blind to it — exhibited as a pair, the typed spelling caught and the conversion spelling not",
"package": "./internal/pipeline/",
"run": "TestEveryFlagReasonIsRanked",
"edits": [
{
"file": "internal/pipeline/status.go",
"find": "const severityUnknown = 9\n",
"replace": "const severityUnknown = 9\n\n// planted\nconst FlagPlantedConv = FlagReason(\"planted_conv\")\n"
}
]
},
{
"id": "WF-length-bound",
"why": "row 271: a bank value rides verbatim inside the SYSTEM message of every paid call, so its length is a fence and not a nicety — lifting the bound lets one term become a document inside the block",
"package": "./internal/membank/",
"edits": [
{
"file": "internal/membank/wirefence.go",
"find": "\tif n := utf8.RuneCountInString(s); n > WireFieldMaxRunes {",
"replace": "\tif n := utf8.RuneCountInString(s); n > WireFieldMaxRunes && false {"
}
]
},
{
"id": "WF-control-ban",
"why": "row 271: a line feed in `dst` ENDS the line of the mapping and writes new lines into the system block — the ban on line-ending/reordering runes is the whole of the fix, and it must not be liftable while the battery stays green",
"package": "./internal/membank/",
"edits": [
{
"file": "internal/membank/wirefence.go",
"find": "\tcase unicode.IsControl(r):",
"replace": "\tcase unicode.IsControl(r) && false:"
}
]
},
{
"id": "WF-render-backstop",
"why": "the fence's LAST point: door and seed loader make it unreachable today, so only a planting can say whether the renderer still holds it for a writer added later",
"package": "./internal/membank/",
"edits": [
{
"file": "internal/membank/memory.go",
"find": "\t\tif WireUnfitRow(p.entry.src, p.entry.dst) {\n\t\t\tcontinue\n\t\t}\n\t\tline := p.entry.src + \" → \" + p.entry.dst",
"replace": "\t\tline := p.entry.src + \" → \" + p.entry.dst"
}
]
},
{
"id": "WF-door-refusal",
"why": "row 271: the user door is where a person finds out their correction cannot ride on the wire — without the refusal the term is accepted and then silently absent from every request",
"package": "./internal/membank/",
"edits": [
{
"file": "internal/membank/decisions.go",
"find": "\tif why := WireUnfitJoined(d.Src, d.Dst); why != \"\" {\n\t\treturn termKey{}, fmt.Errorf(\"%s\", why)\n\t}\n",
"replace": ""
}
]
},
{
"id": "WF-seed-refusal",
"why": "an operator's seed file is theirs to fix: dropping such a row on the way to the wire would leave a term they believe is in force absent from every paid call, with nothing said",
"package": "./internal/membank/",
"edits": [
{
"file": "internal/membank/memseed.go",
"find": "\t\tif reasons := WireUnfitReasons(t.Src, t.Dst); len(reasons) > 0 {",
"replace": "\t\tif reasons := WireUnfitReasons(t.Src, t.Dst); false && len(reasons) > 0 {"
}
]
},
{
"id": "WF-version-fold-scope",
"why": "the fence changes the WIRE for a book holding an unfit row, and a wire change the snapshot cannot see is a silent re-payment outside the consent contour (the editor-unverified/neuter class, a third time)",
"package": "./internal/membank/",
"edits": [
{
"file": "internal/membank/memory.go",
"find": "\t\tif WireUnfitRow(r.Src, r.Dst) {\n\t\t\thasUnfit = true\n\t\t}",
"replace": "\t\tif WireUnfitRow(r.Src, r.Dst) {\n\t\t\t_ = r\n\t\t}"
}
]
},
{
"id": "MS-latch-is-a-cancel",
"why": "row 277, THE NAMED ACCEPTANCE PLANTING: it restores the PRE-PACK world in one act — no waiting for headroom, and a refusal that cancels the wave — because that pair is what killed the calls already admitted and made a book produce nothing at any price (measured live 04.09, reproduced twice). ⚠ THE FIRST VERSION OF THIS ENTRY ADDED ONLY THE cancel() AND SURVIVED, and the reason is worth keeping: with the wait in place a refusal does not become terminal until the sky is empty, so by the time the latch fires there is nothing left in flight for a cancel to kill. The defect needs both halves; so does the planting that reproduces it.",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/stagerun.go",
"find": "\t\tif !settleCannotHelp(scope, committed, estimate, ceiling) {",
"replace": "\t\tif false && !settleCannotHelp(scope, committed, estimate, ceiling) {"
},
{
"file": "internal/pipeline/waverun.go",
"find": "\t\t\tr.events.ceilingReached(halt)\n\t\t\tlatchOnce.Do(func() { close(latched) })\n\t\t\treturn",
"replace": "\t\t\tr.events.ceilingReached(halt)\n\t\t\tlatchOnce.Do(func() { close(latched) })\n\t\t\tcancel()\n\t\t\treturn"
}
]
},
{
"id": "MS-wait-for-settle",
"why": "a refusal is not final while another call still holds a reservation: settle returns estimate-cost, so the headroom is still moving and re-asking is what turns a dead run into a delivered book",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/stagerun.go",
"find": "\t\tif !settleCannotHelp(scope, committed, estimate, ceiling) {",
"replace": "\t\tif false && !settleCannotHelp(scope, committed, estimate, ceiling) {"
}
]
},
{
"id": "MS-reserve-under-the-gate",
"why": "the admission and the in-flight counter must be ONE critical section: split, a worker that has committed its reservation but not yet recorded itself lets a refused sibling read zero in flight and declare the book finished while money is about to come back. ⚠ CATALOGUED AS A SURVIVOR, AND «SURVIVED» HERE DOES NOT MEAN «THE GUARANTEE HOLDS» — it means the tooling cannot ask the question. Reproducing the race needs the two critical sections interleaved on demand, which takes a hook in the scheduler this repository does not have; a sleep-based «proof» would pin a duration rather than the invariant. Read this green as «unverifiable by this instrument», never as a pin.",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/reservegate.go",
"find": "\tg.mu.Lock()\n\tdefer g.mu.Unlock()\n\tresv, verdict, err := s.Reserve(bookID, estimate, c)",
"replace": "\tresv, verdict, err := s.Reserve(bookID, estimate, c)\n\tg.mu.Lock()\n\tdefer g.mu.Unlock()"
}
],
"expect": "survives"
},
{
"id": "MS-cancelled-wait-is-not-money",
"why": "a wait ended by ctx cancellation is NOT a money stop: reported as one, a run somebody stopped publishes a ceiling event with a shortfall and the platform tells a person to add money that would change nothing",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/reservegate.go",
"find": "\tcase <-ctx.Done():\n\t\treturn waitAborted",
"replace": "\tcase <-ctx.Done():\n\t\treturn waitNothingInFlight"
}
]
},
{
"id": "MS-draft-stop-does-not-edit",
"why": "a money stop in the DRAFT wave must not start the edit wave: an unstarted member is found in draftByKey holding the zero value, so the editor is paid to edit a unit with a hole and then ships it",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/waverun.go",
"find": "\t\tr.reportEvicted(ctx, \"draft\")\n\t\treturn r.moneyStoppedResult(ctx, chunks, drafted, draftResults, editWave), err",
"replace": "\t\tr.reportEvicted(ctx, \"draft\")\n\t\t_ = drafted"
}
]
},
{
"id": "MS-shortfall-on-the-wire",
"why": "row 278: the missing amount died in the stderr of a transient unit — without it on the ceiling frame a buyer is told the run stopped and nothing about what would restart it",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/events.go",
"find": "\te.emit(runevents.TypeCeiling, runevents.Ceiling{Halted: true, Scope: halt.Scope, ShortfallMicroUSD: halt.ShortfallMicroUSD})",
"replace": "\te.emit(runevents.TypeCeiling, runevents.Ceiling{Halted: true, Scope: halt.Scope})"
}
]
},
{
"id": "MS-stream-version-bump",
"why": "the seam rule: a frame that gained a field must say so, or two streams differing in content claim one version — the constant's own comment records this exact miss, made once already",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/runevents/runevents.go",
"find": "const StreamVersion = \"1.3\"",
"replace": "const StreamVersion = \"1.2\""
}
]
},
{
"id": "MS-volume-ledger-on-a-money-stop",
"why": "VolumeStop's seven counters are a PLAN; a spend stop leaves them counting units that were admitted and never done — Delivered over-counts, LeftFresh under-counts, and at Left()==0 the run announces it reached the end of the book. ⚠ ITS FIRST PIN WAS VACUOUS and this entry SURVIVED it: the fixture granted no volume at all, so res.Volume was nil whatever the code did. Only a run that HAS a grant can have one wrongly attached.",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/waverun.go",
"find": "func (r *Runner) noteMoneyStop(ctx context.Context, res *BookResult) {\n\tres.Volume = nil",
"replace": "func (r *Runner) noteMoneyStop(ctx context.Context, res *BookResult) {"
}
]
},
{
"id": "PP-step-max-ignores-retries",
"why": "row 278: maxTokensForAttempt DOUBLES the budget on every regeneration and a refused RETRY does not degrade — a ceiling sized for attempt 0 admits a unit's first call and refuses its remedy on every resume forever",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/priceprojection.go",
"find": "\t\tfor escalations := 0; escalations <= p.maxRegen; escalations++ {",
"replace": "\t\tfor escalations := 0; escalations <= 0; escalations++ {"
}
]
},
{
"id": "PP-executor-sizing-shared",
"why": "reader and writer of one arithmetic: the projection reproduces the executor's output budget, and a projection that sized calls its own way would drift from the reservations the run actually makes, invisibly",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/priceprojection.go",
"find": "\t\tbase := r.baseMaxTokensFor(sp.st, sizing)",
"replace": "\t\tbase := sizing"
}
]
},
{
"id": "PP-structure-provenance",
"why": "an order phrased in chapters against a DETECTED cut is an order against a guess; collapsing the values hides which one the reader has. RE-AIMED by the chapter-structure pack: the three-value if/else it used to target was replaced by the winning path's witness, so the mutation now collapses the witness instead",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/chunk/ingest.go",
"find": "\tif len(chapters) < 2 {\n\t\treturn StructureNone\n\t}\n\treturn witness",
"replace": "\tif len(chapters) < 2 {\n\t\treturn StructureNone\n\t}\n\treturn StructureDeclared"
}
]
},
{
"id": "PP-price-reaches-status",
"why": "the surface a buyer's platform reads before deciding must answer the price question too — a projection that only the manifest carries leaves status blind exactly where the money decision is made",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/status.go",
"find": "\trep.Price, rep.Structure = r.readModelPrice(withText)",
"replace": "\t_ = withText"
}
]
},
{
"id": "PP-price-fallback-path",
"why": "the manifest is an ACCELERATOR, and an accelerator that changes the ANSWER is a second source of truth: without the fallback a book with no current sidecar reports no price at all, silently, on the surface a buyer's platform reads before deciding",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/manifest.go",
"find": "\tfull, err := withText()\n\tif err != nil || len(full) == 0 {\n\t\treturn nil, \"\"\n\t}\n\t_, bp := r.projectBook(r.pricePlanFor(), r.outputUnits(full))\n\treturn bp, r.cutStructure",
"replace": "\treturn nil, \"\""
}
]
},
{
"id": "MS-reservation-released-on-marshal-failure",
"why": "a reservation left behind is headroom the book paid for and cannot use, and since the stop now PUBLISHES the shortfall a leak makes the engine ask a person for more money than it needs. ⚠ CATALOGUED AS A SURVIVOR, and the argument is that the branch is UNREACHABLE rather than untested: it fires only if json.Marshal fails on llm.Usage, a struct of ints, which the encoding/json contract does not allow. No test can red it without faking the standard library, and the repair is kept because the money path must be correct on the paths nobody can reach as well as on the ones they can.",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/stagerun.go",
"find": "\t\tr.releaseReservation(ctx, resv)\n\t\tr.setJobStatus(ctx, job.ID, \"failed\")\n\t\treturn att, err\n\t}\n\t// Same as the billed-decode branch above: the burn walk's money is added, never replaced.\n\tatt.cumCost, att.runCost = burnedCost+cost, cost",
"replace": "\t\tr.setJobStatus(ctx, job.ID, \"failed\")\n\t\treturn att, err\n\t}\n\t// Same as the billed-decode branch above: the burn walk's money is added, never replaced.\n\tatt.cumCost, att.runCost = burnedCost+cost, cost"
}
],
"expect": "survives"
},
{
"id": "MS-two-error-slots",
"why": "a ceiling no longer cancels, so a run can latch on money and THEN break: sharing one slot lets whichever came first speak for both, and a first-wins ceiling makes a BROKEN run depart exit 4, which the platform records as `paused`",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/waverun.go",
"find": "\t\t\tmu.Lock()\n\t\t\tif haltErr == nil {\n\t\t\t\thaltErr = err\n\t\t\t}\n\t\t\tmu.Unlock()",
"replace": "\t\t\tmu.Lock()\n\t\t\tif firstErr == nil {\n\t\t\t\tfirstErr = err\n\t\t\t}\n\t\t\tmu.Unlock()"
}
]
},
{
"id": "MS-crash-outranks-the-wave-error",
"why": "a crashed process is not a pause and is not a graceful stop: routed behind the wave's own error it departs as the sibling's ceiling (exit 4) or cancellation (exit 5), and its stack is discarded",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/waverun.go",
"find": "\tif panicErr != nil {",
"replace": "\tif firstErr != nil {\n\t\treturn firstErr\n\t}\n\tif panicErr != nil {"
}
]
},
{
"id": "PP-fewshot-toggle-respected",
"why": "the projection must ask the EXECUTOR'S question (SystemFor + fewShotEnabled), not add the template's fields up: the shipped c1 editor has few_shot OFF while its template still carries the block, so summing it over-charges every edit call of every book on that arm — invisibly, because a price 20% too high looks exactly like a price",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/priceprojection.go",
"find": "\t\t\tsp.tplTokens = EstimateTokens(tpl.SystemFor(fewShotEnabled(st))) + EstimateTokens(tpl.User)",
"replace": "\t\t\tsp.tplTokens = EstimateTokens(tpl.System) + EstimateTokens(tpl.FewShot) + EstimateTokens(tpl.User)"
}
]
},
{
"id": "PP-source-rides-every-stage-that-asks",
"why": "the executor renders EVERY stage with RenderVars{Text, Draft}, and the shipped editor is BILINGUAL (D30.1) — dropping the source from a later stage's prompt under-states a unit's bill by roughly a sixth, in the direction that lets a platform sell a book for less than it costs",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/priceprojection.go",
"find": "\tif sp.carriesSource && !inputIsSource {",
"replace": "\tif false && sp.carriesSource && !inputIsSource {"
}
]
},
{
"id": "MS-source-double-charged",
"why": "the FIRST stage's input IS the source, so adding it again double-charges the draft call — the mirror error of dropping it, and it would raise the minimum purchase a platform demands",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/priceprojection.go",
"find": "\tif sp.carriesSource && !inputIsSource {",
"replace": "\tif sp.carriesSource {"
}
]
},
{
"id": "MS-wait-counter",
"why": "a test can only see the WAITING MECHANISM through a fact it leaves behind: without the counter the delivering-ceiling test asserts an outcome the run can reach without ever waiting — which is exactly how it passed on a fixture whose ceiling never refused anything",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/reservegate.go",
"find": "\t\tg.mu.Lock()\n\t\tg.waits++\n\t\tg.mu.Unlock()\n\t\treturn waitSettled",
"replace": "\t\treturn waitSettled"
}
]
},
{
"id": "PP-draft-priced-per-unit-not-per-chunk",
"why": "the wave driver fans the DRAFT over chunks and the EDIT over units: pricing the draft per unit charges the template and the injection once where the executor pays them per member, and sizes the largest single reservation from the whole unit instead of from one call — the number a platform sets its minimum purchase by",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/priceprojection.go",
"find": "\tfor _, m := range u.Members {\n\t\tdraftTokens += p.walkDraftCalls(m, func(sp stagePrice, srcTok, in, out int, inIsSource bool) {",
"replace": "\tfor _, m := range u.Members[:1] {\n\t\tm.Text = src\n\t\tdraftTokens += p.walkDraftCalls(m, func(sp stagePrice, srcTok, in, out int, inIsSource bool) {"
}
]
},
{
"id": "MS-optional-call-queues-for-headroom",
"why": "an optional call that queued for the last dollars turns «do not start anything new» into «the optional spends what the mandatory needed» — and the escalation hop holds escMu while it waits, blocking every other worker's escalation. The rule lives in the gate precisely so a test can watch it happen",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/reservegate.go",
"find": "\tif !mandatory {",
"replace": "\tif false && !mandatory {"
}
]
},
{
"id": "MS-terminal-branch-order",
"why": "the money ledger is attached whenever a ceiling was reached, and above the signature stop and the cancellation that branch swallows both: a bank-stop reports `failed` at exit 3 and a caught SIGTERM reports `failed` at exit 5. Two channels contradicting each other about one run is what this vocabulary exists to prevent — and re-ordering case arms is the edit a tidy-up makes without noticing",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/events.go",
"find": "\tcase errors.As(err, &sigStop):",
"replace": "\tcase err != nil && e.ceilingSaid:\n\t\te.emit(runevents.TypeFinished, runevents.Finished{Outcome: runevents.OutcomeFailed, Money: e.moneyLedger()})\n\tcase errors.As(err, &sigStop):"
}
]
},
{
"id": "PP-book-once-charge",
"why": "row 278: the terminology consolidation reads the WHOLE book's drafts once, so charging it per unit under-prices a short book exactly where the error hurts — and it is conditional on the gate AND the contrast key, the pair whose second half a deployment loses silently",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/priceprojection.go",
"find": "\tusd := g.Terminology.BudgetUSD",
"replace": "\tusd := 0.0"
}
]
},
{
"id": "PP-book-once-charged-per-unit",
"why": "the once-per-book charge added inside the unit loop is the very under-pricing inversion the field exists to prevent, only backwards: a long book would pay it a hundred times",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/priceprojection.go",
"find": "\t\tbp.ExpectedUSD += p.ExpectedUSD\n\t\tif step := r.stepMaxForUnit(plan, u, p); step > bp.StepMaxUSD {",
"replace": "\t\tbp.ExpectedUSD += p.ExpectedUSD + bp.BookOnceUSD\n\t\tif step := r.stepMaxForUnit(plan, u, p); step > bp.StepMaxUSD {"
}
]
},
{
"id": "MS-ceiling-frame-idempotent",
"why": "under several workers one stop is refused several times; a `ceiling` frame per refusal makes a reader count refusals where it means to count stops",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/events.go",
"find": "\tif already {\n\t\treturn\n\t}",
"replace": "\t_ = already"
}
]
},
{
"id": "PP-no-translator-stage-completion",
"why": "a pipeline whose first stage is not a translator has that stage DOING the translating: its completion is what the pair's fertility says a source of this shape produces, not the source's own token count. ⚠ THIS ENTRY SURVIVED ONCE AND THE SURVIVAL WAS THE FINDING: walkDraftCalls returned a draft size even when NO draft stage ran, so the fallback this mutation edits was DEAD CODE — a mutation cannot change a branch nothing reaches. The branch is live now, and the entry is what made it visible.",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/priceprojection.go",
"find": "\t\tin, out = up.PromptTokens, p.expectedDraftTokens(dense, sparse)",
"replace": "\t\tin, out = up.PromptTokens, up.PromptTokens"
}
]
},
{
"id": "DF-money-follows-the-ceiling-not-the-outcome",
"why": "acceptance F6/V2-4, found by BOTH verifiers independently: `Finished.money` follows «a ceiling was REACHED», not «the outcome word is ceiling» — the contract file said the latter, and a consumer in another zone building on either reading gets a different bug (money on `stopped`/`failed` is real; `ceiling` without seeded counters carries none)",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/events.go",
"find": "\tif !e.ceilingSaid || e.waves == nil {",
"replace": "\tif e.waves == nil {"
}
]
},
{
"id": "DF-old-sidecar-must-not-silence-the-price",
"why": "acceptance V2-3: `price` and `structure` are ADDITIVE so the document version deliberately did not move for them — a sidecar from the previous build passes version, counters and key, comes back «current» carrying no price, and the fallback the code itself calls the invariant never runs. The book then reports NO price at all, silently, on the surface a buyer's platform reads before deciding",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/manifest.go",
"find": "\tif m := r.loadManifest(); m != nil && m.Price != nil && m.Structure != \"\" {",
"replace": "\tif m := r.loadManifest(); m != nil {"
}
]
},
{
"id": "DF-engine-written-document-must-not-kill-the-run",
"why": "acceptance F8, widened: the mined delta AND the auto-bank are written by this engine from MODEL OUTPUT, and refusing such a document aborts a PAID run over our own answer while asking a person to hand-edit a file nobody authored. The operator's own seed keeps the refusal — that one is theirs to fix",
"package": "./internal/membank/",
"edits": [
{
"file": "internal/membank/memseed.go",
"find": "\t\t\tif engineWritten {",
"replace": "\t\t\tif false && engineWritten {"
}
]
},
{
"id": "DF-operator-seed-keeps-its-refusal",
"why": "the mirror of the split: dropping a row from the OPERATOR's seed would leave a term they believe is in force silently absent from every request — the refusal is what tells them",
"package": "./internal/membank/",
"edits": [
{
"file": "internal/membank/memseed.go",
"find": "func ParseBankSeed(name string, raw []byte) (BankSeed, error) {\n\treturn parseBankSeed(name, raw, false)",
"replace": "func ParseBankSeed(name string, raw []byte) (BankSeed, error) {\n\treturn parseBankSeed(name, raw, true)"
}
]
},
{
"id": "DF-classifier-budget-only-when-it-runs",
"why": "acceptance V2-5, and it is a class rather than a slip: `classify_types` gates the classifier PHASE, and the loader requires its budget be non-zero ONLY when that toggle is on — so charging the budget unconditionally bills a book for a pass that cannot happen ($1.00 of $2.00 on the shipped arm). ⚠ THE TEST OF THIS FUNCTION PINNED THE WRONG NUMBER: a gate defending the defect, which no review that reads green can catch",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/priceprojection.go",
"find": "\tif g.Terminology.ClassifyTypes {\n\t\tusd += g.Terminology.ClassifyBudgetUSD\n\t}",
"replace": "\tusd += g.Terminology.ClassifyBudgetUSD"
}
]
},
{
"id": "DF-input-identity-is-stated-not-counted",
"why": "acceptance V2-8: two token counts can coincide without being the same text — a pair whose fertility sits near 1.0 makes a draft the size of its source — and then a later stage that DOES receive the source stops being charged for it. Identity is a fact the caller has and the arithmetic does not",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/priceprojection.go",
"find": "\tif sp.carriesSource && !inputIsSource {",
"replace": "\tif sp.carriesSource && inputTokens != sourceTokens {"
}
]
},
{
"id": "DF-competition-order-loses-a-chapter",
"why": "REPLACES DF-declared-means-every-boundary, whose target (the V2-7 predicate) the chapter-structure pack deliberately deleted: with competing paths a stray form feed can no longer mis-label a cut, because there is no mixed case left to judge. The property that took its place is the ORDER: neutralise form feeds on a copy, detect on the copy. Detect first and a header sharing a line with the previous chapter's prose is invisible — the chapter vanishes while the label stays correct, so a test checking only Structure passes over the loss",
"package": "./internal/chunk/",
"edits": [
{
"file": "internal/chunk/ingest.go",
"find": "\tworking := strings.ReplaceAll(decoded, chapterSep, \"\\n\\n\")",
"replace": "\tworking := decoded"
}
]
},
{
"id": "DF-book-level-figure-is-a-forecast",
"why": "acceptance F3: the book-level part of the price is a BOUND the run will not exceed, and calling it money `paid once` in the same breath as the expected total makes a short book read as dearer per chapter than a long one — a wrong conclusion drawn from our sentence rather than from the number",
"package": "./cmd/tmctl/",
"edits": [
{
"file": "cmd/tmctl/render.go",
"find": "fmt.Fprintf(w, \"expected cost: $%.6f for the whole book (%d source chars)\\n\", p.ExpectedUSD, p.SourceChars)",
"replace": "fmt.Fprintf(w, \"expected cost: $%.6f for the whole book (%d source chars; $%.6f of it is book-level and paid once)\\n\", p.ExpectedUSD, p.SourceChars, p.BookOnceUSD)"
}
]
},
{
"id": "DF-no-book-level-spend-says-nothing",
"why": "acceptance F3, the other half: a configuration with no terminology phase prices no book-level spend, and printing a $0.000000 ceiling invents a bound on passes that never run",
"package": "./cmd/tmctl/",
"edits": [
{
"file": "cmd/tmctl/render.go",
"find": "\t\tif p.BookOnceUSD > 0 {",
"replace": "\t\tif true {"
}
]
},
{
"id": "DF-a-dropped-row-is-not-silent",
"why": "the authorship split trades a dead paid run for a dropped row — and a drop nobody can read is the worse half of that trade: a mined term vanishes from every request and an operator asking why has nothing to answer with",
"package": "./internal/membank/",
"edits": [
{
"file": "internal/membank/memseed.go",
"find": "\t\t\t\tbs.Dropped = append(bs.Dropped, t.Src)\n",
"replace": ""
}
]
},
{
"id": "EPUB-preamble-joins-chapter-one",
"why": "a spine document the table of contents does not mention (a title page, a foreword) must join chapter ONE, the mirror of the txt preamble rule. Dropping it loses book text silently: the chapter count stays right and the provenance stays right, only the words are gone (D39.205)",
"package": "./internal/chunk/",
"edits": [
{
"file": "internal/chunk/epubtoc.go",
"find": "\t\t\tpre = append(pre, i) // held back",
"replace": "\t\t\t_ = i // held back"
}
]
},
{
"id": "EPUB-service-pages-are-exactly-two-roles",
"why": "only the navigation document and the roles the book declares as toc/cover are excluded from the reading. Widening the rule deletes real chapters; narrowing it glues a text table of contents onto chapter one, which is the mass EPUB 2 case",
"package": "./internal/chunk/",
"edits": [
{
"file": "internal/chunk/epubtoc.go",
"find": "\tcase \"toc\", \"cover\":\n\t\treturn true",
"replace": "\tcase \"toc\":\n\t\treturn true"
}
]
},
{
"id": "TITLE-raw-follows-the-kept-index",
"why": "numbering is dense, so a chapter emptied by stripHeading takes no number. Selecting source titles by ordinal instead of by the chunker's own kept indices hands chapter N's title to chapter N+1, and nothing looks wrong because every chapter still has a title",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/manifest.go",
"find": "\t\tif i < len(doc.Titles) {\n\t\t\ttitle = doc.Titles[i]\n\t\t}",
"replace": "\t\tif len(out.titles) < len(doc.Titles) {\n\t\t\ttitle = doc.Titles[len(out.titles)]\n\t\t}"
}
]
},
{
"id": "EPUB-collapsed-targets-downgrade-the-provenance",
"why": "a book packing several chapters into ONE document with anchors declares more chapters than this package hands back, because it groups whole documents. Reporting that cut as `declared` puts the engine's own coarser answer out under the format's name — the same lie the spine used to tell, in a new place. The four-value vocabulary already has the true word for it: delimited",
"package": "./internal/chunk/",
"edits": [
{
"file": "internal/chunk/ingest.go",
"find": "\tif toc.collapsed > 0 {",
"replace": "\tif false && toc.collapsed > 0 {"
}
]
},
{
"id": "EPUB-service-role-at-a-point-keeps-the-document",
"why": "`<reference type=\"toc\" href=\"c2.xhtml#pos\"/>` says the table of contents BEGINS inside a document, not that the whole file is one. Excluding the file on that basis deletes whatever prose shares it, while the chapter count stays plausible and the provenance stays a confident `declared`. The form is in the owner's Kristoff EPUB today",
"package": "./internal/chunk/",
"edits": [
{
"file": "internal/chunk/ingest.go",
"find": "\t\tcase insideDoc:\n\t\t\tserviceInsideDoc++",
"replace": "\t\tcase insideDoc:\n\t\t\tservice[h] = \"toc\""
}
]
},
{
"id": "INGEST-every-count-reaches-the-operator",
"why": "the counts ARE the alarm this work ships instead of a validator, so one that reaches nobody is the mechanism missing rather than a small omission. Measured before the fix: 126 documents folded into 6 chapters printed zero bytes to stderr",
"package": "./internal/chunk/",
"edits": [
{
"file": "internal/chunk/ingest.go",
"find": "\tadd(\"documents_attached\", d.DocumentsAttached)",
"replace": "\t_ = d.DocumentsAttached"
}
]
},
{
"id": "EPUB-unresolved-counts-only-what-it-promises",
"why": "counting a target that resolved fine but landed on a service or non-linear document as `unresolved` makes every ordinary EPUB 2 report a broken table of contents. An alarm that fires on the normal case is one nobody reads — and it dies by being ignored, not by being switched off",
"package": "./internal/chunk/",
"edits": [
{
"file": "internal/chunk/epubtoc.go",
"find": "\t\tif docs[i].service || !docs[i].linear {\n\t\t\tcontinue",
"replace": "\t\tif docs[i].service || !docs[i].linear {\n\t\t\tout.unresolved++\n\t\t\tcontinue"
}
]
},
{
"id": "MANIFEST-key-carries-the-structure-grammar",
"why": "the key decides whether a stored manifest is still current. Leave the grammar out and a sidecar written under a DIFFERENT grammar keeps validating, handing a reader a chapter tree whose boundaries the engine no longer draws",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/manifest.go",
"find": "\t\tShippingWave: r.shippingWaveTag(), Structure: r.structure.Fingerprint(),",
"replace": "\t\tShippingWave: r.shippingWaveTag(), Structure: \"\","
}
]
},
{
"id": "TITLE-raw-epub-half-comes-from-the-label",
"why": "the EPUB half of title_raw had no test at all: removing label collection entirely left every chapter with an empty title and the battery green",
"package": "./internal/chunk/",
"edits": [
{
"file": "internal/chunk/epubtoc.go",
"find": "\t\t\t\t\t\tpending = href // the FIRST entry naming a document supplies its title",
"replace": "\t\t\t\t\t\t_ = href // the FIRST entry naming a document supplies its title"
}
]
},
{
"id": "EPUB-conservation-no-document-leaves-unaccounted",
"why": "the counts this reader keeps are observability; this is the guarantee. Every readable spine document is either excluded on purpose or lands in exactly one chapter — a document that quietly leaves the reading takes book text with it while the chapter total stays plausible and the provenance stays a confident `declared`. ⚠ It does NOT subsume a WRONG exclusion: an excluded document is accounted for, so the fragment defect (M-1) is caught by its own tests, not by this",
"package": "./internal/chunk/",
"edits": [
{
"file": "internal/chunk/epubtoc.go",
"find": "\t\tdefault:\n\t\t\tlast := &groups[len(groups)-1]\n\t\t\tlast.docs = append(last.docs, i)\n\t\t\tattached++",
"replace": "\t\tdefault:\n\t\t\tattached++"
}
]
},
{
"id": "TITLE-heading-belongs-to-the-chapter-not-the-edit-unit",
"why": "a chapter's title is restored on the CHAPTER's first chunk; an edit unit is a GROUP of chunks, so restoring it on each unit's first chunk prints «Глава 1» again in the middle of chapter 1 — in the very artifact `tmctl export` hands the platform. The two positions coincide on any chapter whose chunks share one unit, which is why the fixture pinning this asserts ≥2 units per chapter",
"package": "./internal/pipeline/",
"battery": true,
"edits": [
{
"file": "internal/pipeline/manifest.go",
"find": "\t\t\t\tif ch.ChunkIdx == 0 {\n\t\t\t\t\tch.Heading = c.Heading // only a chapter's first chunk carries the title (chunker.go)\n\t\t\t\t}",
"replace": "\t\t\t\tif i == 0 {\n\t\t\t\t\tch.Heading = c.Heading // only a chapter's first chunk carries the title (chunker.go)\n\t\t\t\t}"
}
]
},
{
"id": "TITLE-manifest-restores-the-heading-at-all",
"why": "the read path rebuilds chunks from the sidecar, and the title is the one field it must re-derive rather than read back. Drop the restore and every chapter arrives titleless: bookbuild then substitutes the chapter NUMBER, and the finished book ships «1», «2» where its chapter names belong",
"package": "./internal/pipeline/",
"battery": true,
"edits": [
{
"file": "internal/pipeline/manifest.go",
"find": "\t\t\t\tif ch.ChunkIdx == 0 {\n\t\t\t\t\tch.Heading = c.Heading // only a chapter's first chunk carries the title (chunker.go)\n\t\t\t\t}",
"replace": "\t\t\t\tif false {\n\t\t\t\t\tch.Heading = c.Heading // only a chapter's first chunk carries the title (chunker.go)\n\t\t\t\t}"
}
]
},
{
"id": "TITLE-export-reads-the-units-leader",
"why": "the export takes a unit's title from its LEADER, because only a chapter-opening chunk carries one. Read the last member instead and the title becomes \"\" on every multi-chunk unit: the export ships chapters with no name and ApplyHeading prepends nothing — a loss invisible to every assertion that lives on the cut",
"package": "./internal/pipeline/",
"battery": true,
"edits": [
{
"file": "internal/pipeline/export.go",
"find": "\tce.FinalText = chunk.ApplyHeading(u.Members[0].Heading, ce.FinalText)\n\tce.Heading = u.Members[0].Heading // the same literal, given apart (see the field)",
"replace": "\tce.FinalText = chunk.ApplyHeading(u.Members[len(u.Members)-1].Heading, ce.FinalText)\n\tce.Heading = u.Members[len(u.Members)-1].Heading // the same literal, given apart (see the field)"
}
]
},
{
"id": "TITLE-cut-puts-the-heading-on-the-chapters-first-chunk",
"why": "the chunker is where a chapter's title is PLACED, and everything downstream reads that placement by position. Put it on the chapter's last chunk instead and the manifest, which restores by position, hands the reader a title the cut never put there — while the chapter's opening unit ships nameless",
"package": "./internal/chunk/",
"battery": true,
"edits": [
{
"file": "internal/chunk/chunker.go",
"find": "\t\t\tchapterChunks[0].Heading = headingText // the chapter's first chunk carries the deterministic title",
"replace": "\t\t\tchapterChunks[len(chapterChunks)-1].Heading = headingText // the chapter's first chunk carries the deterministic title"
}
]
},
{
"id": "ORDER-the-bank-is-published-after-it-is-seeded",
"why": "the run-start read-out is the artifact a reader gets when a run dies before its first wave, and it is written from the STORE. Publish it before seedGlossary materialises the bank and it shows the PREVIOUS run's rows — on a first run, nothing at all — while every later boundary rewrites the file correctly, so the battery stays green and only a reader who opened the file at that moment ever sees it. bookrun.go carried 0 of the catalogue's entries before this one",
"package": "./internal/pipeline/",
"battery": true,
"edits": [
{
"file": "internal/pipeline/bookrun.go",
"find": "\tif err := r.seedGlossary(ctx); err != nil {\n\t\treturn nil, err\n\t}\n\t// The bank read-out (backlog row 125), at the FIRST boundary where a bank exists. Doing it here rather\n\t// than only at the stops means a book that never mines anything — or a run that dies before the first\n\t// wave — still leaves a readable bank behind, which is the state a reader has to be able to see.\n\tr.exportBank(ctx, \"run-start/seeded\")",
"replace": "\t// The bank read-out (backlog row 125), at the FIRST boundary where a bank exists. Doing it here rather\n\t// than only at the stops means a book that never mines anything — or a run that dies before the first\n\t// wave — still leaves a readable bank behind, which is the state a reader has to be able to see.\n\tr.exportBank(ctx, \"run-start/seeded\")\n\tif err := r.seedGlossary(ctx); err != nil {\n\t\treturn nil, err\n\t}"
}
]
},
{
"id": "ORDER-the-stop-holds-its-rows-before-it-publishes-them",
"why": "the signature stop refreshes the read-out so the signing screen sees the state as of THIS stop. The rows it presents reach the document through r.lastBankStopRows, so publishing before the assignment ships a document with an empty proposed section — the row-224 defect exactly, restored by a reordering of two adjacent lines",
"package": "./internal/pipeline/",
"battery": true,
"edits": [
{
"file": "internal/pipeline/mining.go",
"find": "\tr.lastBankStopRows = rows\n\t// The signature stop is the boundary the signing screen reads at (row 125): refresh the bank read-out\n\t// so the state behind the decisions is the state as of this stop, not as of the last run.\n\tr.exportBank(ctx, \"bank-mining/signature-stop\")",
"replace": "\t// The signature stop is the boundary the signing screen reads at (row 125): refresh the bank read-out\n\t// so the state behind the decisions is the state as of this stop, not as of the last run.\n\tr.exportBank(ctx, \"bank-mining/signature-stop\")\n\tr.lastBankStopRows = rows"
}
]
},
{
"id": "BANKSTOP-proposals-reach-the-read-out",
"why": "row 224: the stop refreshes the bank read-out precisely so the signing screen has something to read, and the bank half of that document is empty of mined rows by construction (they are written in the auto-continue branch). Drop the proposed section and the screen is back to reading «total 0, signed 0» beside a stop opened for 82 surfaces",
"package": "./internal/pipeline/",
"battery": true,
"edits": [
{
"file": "internal/pipeline/bankexport.go",
"find": "\t// The stop's rows ride along (row 224). r.lastBankStopRows is set in the stopping branch and nowhere\n\t// else, and a stopped run returns before every later boundary, so this is non-empty exactly at a\n\t// signature stop.\n\texp.Proposed = projectBankProposals(r.lastBankStopRows)",
"replace": "\t// The stop's rows ride along (row 224). r.lastBankStopRows is set in the stopping branch and nowhere\n\t// else, and a stopped run returns before every later boundary, so this is non-empty exactly at a\n\t// signature stop."
}
]
},
{
"id": "HEADING-ingest-and-chunker-answer-the-same-on-an-ordinary-header",
"why": "the chapter heading rule is spread over three predicates in two files and each half was pinned only by its own tests, which cannot see a DISAGREEMENT between them. Shrink the ingest's length guard and ordinary headers stop being cut as chapters while the chunker still reads them as headers — the book arrives as one chapter with its markers inside the prose, and every existing chunk test still passes because none of them ingests",
"package": "./internal/chunk/",
"battery": true,
"edits": [
{
"file": "internal/chunk/ingest.go",
"find": "const chapterHeaderMaxRunes = 60",
"replace": "const chapterHeaderMaxRunes = 6"
}
]
},
{
"id": "CLASSVOCAB-a-class-the-engine-keeps-must-be-named-in-the-pair-prompt",
"why": "the classifier's answer vocabulary is closed in Go and explained to the model ONLY by the pair's prompt, and an off-vocabulary reply is counted and dropped rather than refused. Add a class the engine will keep and no shipping prompt names it: the pass is paid for, the class never comes back, and nothing anywhere says so. ⚠ The pin lives in internal/pipeline (the canonical prompt form is implemented there) while the edit is in internal/terminology — the entry names the package of the PIN",
"package": "./internal/pipeline/",
"battery": true,
"edits": [
{
"file": "internal/terminology/classify.go",
"find": "var Types = map[string]bool{\"name\": true, \"place\": true, \"title\": true, \"term\": true}",
"replace": "var Types = map[string]bool{\"name\": true, \"place\": true, \"title\": true, \"term\": true, \"artifact\": true}"
}
]
},
{
"id": "BANKSTOP-proposals-belong-to-a-stop-and-to-no-other-boundary",
"why": "the read-out's `proposed` section means «these rows are waiting for a decision RIGHT NOW». It is safe to read that way only because r.lastBankStopRows is set in the stopping branch and nowhere else — a property held by one assignment and, until this entry, by prose. Set it in the auto-continue branch and every later boundary asks the signing screen to decide rows the run already banked unsigned",
"package": "./internal/pipeline/",
"battery": true,
"edits": [
{
"file": "internal/pipeline/mining.go",
"find": "\t\tr.exportBank(ctx, \"bank-mining/auto-continue\")",
"replace": "\t\tr.lastBankStopRows = rows\n\t\tr.exportBank(ctx, \"bank-mining/auto-continue\")"
}
]
},
{
"id": "TITLE-the-number-in-a-title-is-the-headers-not-the-ordinals",
"why": "a chapter carries TWO numbers — its ordinal (the key chunk_status is addressed by) and the number written in its own header — and they part company on any book whose chapters are not numbered consecutively, which is every book with a prologue or a skipped section. Re-deriving the stored title from the ordinal is silent on a consecutive fixture and moves the title on almost every chapter of a real one",
"package": "./internal/pipeline/",
"battery": true,
"edits": [
{
"file": "internal/pipeline/manifest.go",
"find": "\t\t\t\tif ch.ChunkIdx == 0 {\n\t\t\t\t\tch.Heading = c.Heading // only a chapter's first chunk carries the title (chunker.go)\n\t\t\t\t}",
"replace": "\t\t\t\tif ch.ChunkIdx == 0 && c.Heading != \"\" {\n\t\t\t\t\tch.Heading = \"Глава \" + strconv.Itoa(c.Number)\n\t\t\t\t}"
}
]
},
{
"id": "TITLE-the-built-book-carries-names-not-numbers",
"why": "the symptom this whole seam is named for, and the last hop of it: assembleBook substitutes the chapter NUMBER when the export carries no title, so a title lost anywhere upstream ships as «1», «2» in the finished book. Three positions above this are pinned; before this entry the hop a reader actually sees was prose",
"package": "./internal/pipeline/",
"battery": true,
"edits": [
{
"file": "internal/pipeline/export.go",
"find": "\tce.Heading = u.Members[0].Heading // the same literal, given apart (see the field)",
"replace": "\tce.Heading = \"\" // the same literal, given apart (see the field)"
}
]
},
{
"id": "TITLE-the-glued-heading-is-stripped-from-the-body",
"why": "the export GLUES the title onto the unit's text and the book writer prints it again as the chapter heading, so assembleBook strips the known prefix. Leave it on and every chapter of the finished book opens with its own title twice — no assertion downstream of the export could see it, because the export is byte-correct",
"package": "./internal/pipeline/",
"battery": true,
"edits": [
{
"file": "internal/pipeline/bookbuild.go",
"find": "\t\t\ttext = strings.TrimPrefix(text, ce.Heading+\"\\n\\n\")",
"replace": "\t\t\t_ = text"
}
]
},
{
"id": "ARM-an-arm-is-the-production-config-with-a-different-editor",
"why": "an editor swap-arm exists to isolate ONE variable, and three arm headers claimed exactly that while differing from production by two dozen keys — the bank contour among them — because the test that called itself the guard compared three fields by name. The planting drops a key the LOADER does not care about (a cache ttl), so only the whole-config comparison can see it: a key that quietly differs is a second variable the arm is isolating without saying so. ⚠ The catalogue had no entry in ./internal/config/ at all before this one",
"package": "./internal/config/",
"battery": true,
"edits": [
{
"file": "configs/pipeline-arm-glm.yaml",
"find": " cache_ttl: \"5m\"\n",
"replace": ""
}
]
},
{
"id": "BANKSTOP-the-sheet-carries-the-rows-own-frequency",
"why": "the frequency beside a proposal is what an owner weighs the term by, and it is the row's own count or it is nothing. Before 08.09 the parity assertion checked Freq only for `!= 0`, so a tenfold rescale in the fold published 120 occurrences for a term seen 12 times and left the package green",
"package": "./internal/pipeline/",
"battery": true,
"edits": [
{
"file": "internal/pipeline/bankexport.go",
"find": "\t\t\tFreq: row.Freq, Spread: row.Spread, Conventions: row.Conventions, Conf: row.Conf, Invented: row.Invented,",
"replace": "\t\t\tFreq: row.Freq * 10, Spread: row.Spread, Conventions: row.Conventions, Conf: row.Conf, Invented: row.Invented,"
}
]
},
{
"id": "BANKSTOP-kind-and-channel-are-not-exchangeable",
"why": "the fold RENAMES both (Type->Kind, Origin->Channel) and both are strings, so an exchange compiles and ships a sheet whose every row says its kind is `banknote` and its channel is `name`. Renamed neighbours of one type are the pair a hand-written comparison forgets",
"package": "./internal/pipeline/",
"battery": true,
"edits": [
{
"file": "internal/pipeline/bankexport.go",
"find": "\t\t\tSrc: row.Src, Dst: row.Dst, Kind: row.Type, Channel: row.Origin,",
"replace": "\t\t\tSrc: row.Src, Dst: row.Dst, Kind: row.Origin, Channel: row.Type,"
}
]
},
{
"id": "BANKSTOP-the-two-lists-answer-different-questions",
"why": "`contradicts` is what THIS RUN breaks, `bank_holds` is what the book already calls it — separate fields because they are separate decisions (mining.go says so where it fills them). Both are []string, so an exchange compiles; it is invisible against any fixture where both are empty, which is what the stop's fixture gave until its seed carried an unsigned row",
"package": "./internal/pipeline/",
"battery": true,
"edits": [
{
"file": "internal/pipeline/bankexport.go",
"find": "\t\t\tContradicts: row.Contradicts, BankHolds: row.BankHolds,",
"replace": "\t\t\tContradicts: row.BankHolds, BankHolds: row.Contradicts,"
}
]
},
{
"id": "BANKSTOP-an-invented-rendering-is-published-as-invented",
"why": "`invented` says no draft proposed this rendering — the class the type's own comment calls the one to read first. Forced false it is simply absent from the sidecar (omitempty), and the signing screen loses the flag that tells an owner to look",
"package": "./internal/pipeline/",
"battery": true,
"edits": [
{
"file": "internal/pipeline/bankexport.go",
"find": "\t\t\tFreq: row.Freq, Spread: row.Spread, Conventions: row.Conventions, Conf: row.Conf, Invented: row.Invented,",
"replace": "\t\t\tFreq: row.Freq, Spread: row.Spread, Conventions: row.Conventions, Conf: row.Conf, Invented: false,"
}
]
},
{
"id": "ARM-the-one-exemption-is-asserted-unused-not-merely-logged",
"why": "reasoning_max_tokens leaves the arm comparison only where the loader forces the value (pipeline.go:771, additive billing). Nothing runs an additive editor today, so the exemption never fires and its correctness is never exercised; widening the predicate makes it fire against every config, and before 08.09 the only trace of that would have been a log line on a green run",
"package": "./internal/config/",
"battery": true,
"edits": [
{
"file": "internal/config/armparity_test.go",
"find": "\treturn m.providerReasoning(model) == \"additive\"",
"replace": "\treturn m.providerReasoning(model) != \"\""
}
]
},
{
"id": "BANKSTOP-the-sheets-order-is-the-stops-ranking",
"why": "the section's own contract says its order IS the stop's ranking, so which row an owner reads first is information rather than layout. Nothing asserted it until 08.09: the fold's one-row fixture made order unobservable by construction, and every other assertion found its row by Src instead of by position, so a reversal shipped a sheet ranked backwards and left the package green",
"package": "./internal/pipeline/",
"battery": true,
"edits": [
{
"file": "internal/pipeline/bankexport.go",
"find": "\t\tout = append(out, p)\n\t}\n\treturn out\n}",
"replace": "\t\tout = append(out, p)\n\t}\n\tfor i, j := 0, len(out)-1; i < j; i, j = i+1, j-1 {\n\t\tout[i], out[j] = out[j], out[i]\n\t}\n\treturn out\n}"
}
]
},
{
"id": "BANKSTOP-nothing-consolidated-is-published-as-nothing",
"why": "Dst is \"\" when the role consolidated nothing — the field's comment says so in as many words — and that empty must reach the sheet. Substituting the source surface publishes 青茅山 -> 青茅山, a decision where none was made, in the one place whose whole purpose is to show what has yet to be decided. Invisible against any fixture whose rows all carry a rendering, which was every fixture in this package until 08.09",
"package": "./internal/pipeline/",
"battery": true,
"edits": [
{
"file": "internal/pipeline/bankexport.go",
"find": "\t\tout = append(out, p)",
"replace": "\t\tif p.Dst == \"\" {\n\t\t\tp.Dst = row.Src\n\t\t}\n\t\tout = append(out, p)"
}
]
},
{
"id": "BANKTRUTH-a-drop-names-its-holders-signature",
"why": "the drop an auto-bank key collision leaves calls its holder 'the signed' whatever the holder's status, and the operator signs a bank on the strength of that line. Every fixture in the package held the key with an APPROVED row, so the word was true of all of them and the lie was invisible",
"package": "./internal/pipeline/",
"run": "TestADropNamesItsHoldersSignature",
"battery": true,
"edits": [
{
"file": "internal/pipeline/mining.go",
"find": "membank.StatusLabel(prior.Status)",
"replace": "\"signed\""
}
]
},
{
"id": "BANKTRUTH-the-drop-headline-promises-a-signature",
"why": "the headline over the dropped rows promises 'the signed term wins' over a set of drops whose holders may every one of them be unsigned. It is the line an operator reads first and often the only one, because the per-row detail is a semicolon-joined tail",
"package": "./internal/pipeline/",
"run": "TestTheDropHeadlineDoesNotPromiseASignature|TestEveryOperatorMessageIsCatalogued",
"battery": true,
"edits": [
{
"file": "internal/pipeline/bankmaterialize.go",
"find": "in.remark(\"auto-bank rows dropped: their key is already held by a row gathered earlier (the holder wins, whatever its status; each drop below names the holder's signature)\",",
"replace": "in.remark(\"auto-bank rows dropped: their key is already held by a signed term (the signed term wins)\","
}
]
},
{
"id": "BANKTRUTH-a-sticky-carry-counted-as-judged",
"why": "the unsigned-wire denominator counts rows the chunk can be JUDGED on, which is narrower than the rows the model was shown: a sticky carry is in the injection block but its src is in the previous chunk. Counting it makes every pronominal chunk read as a channel nobody follows, and the follow RATIO then means something other than what four doc comments said it meant",
"package": "./internal/membank/",
"run": "TestTheUnverifiedDenominatorIsNotACountOfRowsShown",
"battery": true,
"edits": [
{
"file": "internal/membank/mempostcheck.go",
"find": "if p.Sticky { // sticky context is not expected in the output",
"replace": "if false { // sticky context is not expected in the output"
}
]
},
{
"id": "OPMSG-an-operator-message-reworded-off-the-catalogue",
"why": "an operator warning is a sentence somebody acts on, and the ones that rot are the ones nothing else reads: a message that STOPS a run is held by the test asserting the stop, a warning by nobody. The catalogue is what makes a wording change a reviewed diff instead of a silent one; this planting is the ordinary way it is defeated",
"package": "./internal/pipeline/",
"run": "TestEveryOperatorMessageIsCatalogued",
"battery": true,
"edits": [
{
"file": "internal/pipeline/seeding.go",
"find": "r.Log.WarnContext(ctx, \"voice profile windows leave chapters uncovered (deliberate is fine; a typo is not)\",",
"replace": "r.Log.WarnContext(ctx, \"voice profile windows leave chapters uncovered\","
}
]
},
{
"id": "SEAM-confidence-keyed-by-the-raw-surface",
"why": "the role's stated confidence is looked up by the candidate KEY. Keyed by the raw surface it silently takes the confidence of whichever candidate happens to key as that surface, or none — and every fixture in the module used simplified spellings, where key and surface are the same string and the choice cannot be wrong",
"package": "./internal/pipeline/",
"run": "TestEveryStopSheetFindingReachesTheRowItBelongsTo|TestTheStopSheetJoinIsNotFooledByTheRawSurface",
"battery": true,
"edits": [
{
"file": "internal/pipeline/mining.go",
"find": "if v, ok := t.Conf[c.Key]; ok {",
"replace": "if v, ok := t.Conf[c.Src]; ok {"
}
]
},
{
"id": "SEAM-self-contradiction-matched-by-the-raw-surface",
"why": "the run's own self-contradiction is matched to its sheet row by the candidate KEY. Matched by the raw surface, every traditional or katakana spelling loses its mark — the population the fold exists for, and the one no fixture had",
"package": "./internal/pipeline/",
"run": "TestEveryStopSheetFindingReachesTheRowItBelongsTo",
"battery": true,
"edits": [
{
"file": "internal/pipeline/mining.go",
"find": "if cf.Key == c.Key {",
"replace": "if cf.Key == c.Src {"
}
]
},
{
"id": "SEAM-bank-hold-matched-by-the-raw-surface",
"why": "the bank's existing rendering is matched to its sheet row by the candidate KEY, because that is the source consolidatedRows gives the proposal. Matched by the raw surface, a banknote candidate's mark goes to another row or nowhere",
"package": "./internal/pipeline/",
"run": "TestEveryStopSheetFindingReachesTheRowItBelongsTo|TestTheStopSheetJoinIsNotFooledByTheRawSurface",
"battery": true,
"edits": [
{
"file": "internal/pipeline/mining.go",
"find": "if cf.Src == c.Key {",
"replace": "if cf.Src == c.Src {"
}
]
},
{
"id": "SEAM-the-conflict-carries-the-raw-surface-as-its-key",
"why": "a consolidation conflict is FOUND by comparing candidate keys, so the key is what it must carry back. Carrying the raw surface instead re-introduces the two-sided key choice the ungrouped carrier was built to end, one file away from where it is read",
"package": "./internal/pipeline/",
"run": "TestEveryStopSheetFindingReachesTheRowItBelongsTo",
"battery": true,
"edits": [
{
"file": "internal/terminology/terminology.go",
"find": "out = append(out, ConsolidationConflict{Key: c.Key, Src: c.Src",
"replace": "out = append(out, ConsolidationConflict{Key: c.Src, Src: c.Src"
}
]
},
{
"id": "STATUSWRITE-the-pre-decided-skip-claims-the-other-writers-cause",
"why": "two different writers put a `skipped` row in chunk_status and which one fires is decided by the wave layout, not by anything the row records. The DETAIL each writes is the only durable trace of which path produced it — and the author of the pack that documented this named the wrong mechanism three times running",
"package": "./internal/pipeline/",
"run": "TestASkippedRowSaysWHICHWriterWroteIt",
"battery": true,
"edits": [
{
"file": "internal/pipeline/waverun.go",
"find": "detail := fmt.Sprintf(\"skipped: a member draft chunk of this edit unit was flagged (%s)\", flagReason)",
"replace": "detail := fmt.Sprintf(\"skipped: an upstream stage was flagged (%s)\", flagReason)"
}
]
},
{
"id": "STATUSWRITE-the-multi-stage-skip-claims-the-other-writers-cause",
"why": "the mirror of the entry above, on the writer that no fixture in the package reached until 08.09: breaking it survived the WHOLE package while breaking its sibling turned six tests red, so half of what the doc asserted had no witness at all",
"package": "./internal/pipeline/",
"run": "TestASkippedRowSaysWHICHWriterWroteIt",
"battery": true,
"edits": [
{
"file": "internal/pipeline/waverun.go",
"find": "detail := fmt.Sprintf(\"skipped: an upstream stage was flagged (%s)\", flagReason)",
"replace": "detail := fmt.Sprintf(\"skipped: a member draft chunk of this edit unit was flagged (%s)\", flagReason)"
}
]
},
{
"id": "BANKSHEET-the-tuple-skip-swallows-a-seed-rows-disagreement",
"why": "a proposal sharing a bank row's UNIQUE tuple is skipped only where it can LAND on that tuple. Over a row the owner wrote it never lands — the emission drops it — so the bank keeps its rendering and the disagreement is permanent. Unconditioned, the skip hides the commonest shape there is: a hand-written seed row takes the default window and no sense, and so does a banknote proposal",
"package": "./internal/pipeline/",
"run": "TestTheCommonestSeedShapeStillReachesTheSigningSheet",
"battery": true,
"edits": [
{
"file": "internal/membank/memseed.go",
"find": "if IsEngineUnsigned(b) && b.Src == c.Src && b.Sense == c.Sense",
"replace": "if b.Src == c.Src && b.Sense == c.Sense"
}
]
},
{
"id": "BANKSHEET-the-one-carrier-of-engine-unsigned-inverted",
"why": "three places have to agree on what counts as the ENGINE's own unsigned row — the emission's seed-surface guard, the paid path's filter and the bank's tuple skip — and they agree by sharing one predicate. Inverting it is what a second spelling of the rule would eventually amount to",
"package": "./internal/membank/",
"run": "TestConsolidationKeyConflicts|TestConsolidationTupleSkipMirrorsTheStoreKey",
"battery": true,
"edits": [
{
"file": "internal/membank/memseed.go",
"find": "return e.Source == \"mined\" && e.Status != \"approved\"",
"replace": "return e.Source == \"mined\" && e.Status == \"approved\""
}
]
},
{
"id": "MONEY-a-settled-candidate-is-paid-for-anyway",
"why": "the role and the classifier were being paid for surfaces the bank already settles and the emission then throws away. The filter is the saving; without it every counter in the report still reads clean, because nothing downstream can tell a question that was asked from one that was not",
"package": "./internal/pipeline/",
"run": "TestABankSettledCandidateIsNotPaidFor",
"battery": true,
"edits": [
{
"file": "internal/pipeline/terminologist.go",
"find": "\t\tif bankSettles(settled, c) {",
"replace": "\t\tif false && bankSettles(settled, c) {"
}
]
},
{
"id": "MONEY-the-filter-skips-a-candidate-whose-drafts-disagree",
"why": "the role is asked about banked surfaces ON PURPOSE: its answer is the mark that tells the owner the book already calls the term something else. Measured on the corpus, 366 of the 439 candidates the owner's seed holds had a draft that disagreed — so a filter that drops the disagreement half buys its saving by silencing them, and the sheet still looks complete",
"package": "./internal/pipeline/",
"run": "TestADisagreeingBankedCandidateIsStillPaidFor",
"battery": true,
"edits": [
{
"file": "internal/pipeline/terminologist.go",
"find": "\t\tif text.NormalizeTargetForm(v.Dst) != want {",
"replace": "\t\tif false && text.NormalizeTargetForm(v.Dst) != want {"
}
]
},
{
"id": "MONEY-the-filter-reads-a-bank-that-moves-between-runs",
"why": "the filter reads the SEED surfaces, not the whole bank. Reading the whole bank folds in the engine's own auto-bank rows, which this very run rewrites — so the candidate set differs between run one and run two and the bank moves with it. Measured consequence is bigger than the pass: the second run refuses at the edit wave with «what moved: memory_version», i.e. the already-paid EDIT checkpoints are invalidated and the run demands --resnapshot. ⚠ Only an AUTO-CONTINUING pair of runs can see it: a run that stops at the bank boundary writes no auto-bank, and the first version of this pin stopped and let the planting through",
"package": "./internal/pipeline/",
"run": "TestAResumeFindsItsCheckpointsAfterTheFilter",
"battery": true,
"edits": [
{
"file": "internal/pipeline/terminologist.go",
"find": "settled := bankSettledSurfaces(unsignedEngineSurfaces(r.glossaryRows()))",
"replace": "settled := bankSettledSurfaces(r.glossaryRows())"
}
]
},
{
"id": "MONEY-the-filter-copies-the-candidates-and-loses-their-mutations",
"why": "the classifier and the scorer MUTATE candidates in place, and the caller renders the sheet and the delta from the slice it passed in. Applying them to the filtered COPY instead leaves the sheet carrying heuristic types and stale rankings with every counter reading clean — the defect the filter's own first implementation had, invisible to every fixture in the package because they all run with the classifier off",
"package": "./internal/pipeline/",
"run": "TestTheClassifiersTypeStillReachesTheSheetThroughTheFilter",
"battery": true,
"edits": [
{
"file": "internal/pipeline/terminologist.go",
"find": "\t\tres.Reclassified = applyTypes(cands, classified)",
"replace": "\t\tres.Reclassified = applyTypes(paid, classified)"
}
]
},
{
"id": "MONEY-the-rescoring-is-applied-to-the-filtered-copy",
"why": "applyTypes and ScoreVariants are TWO in-place mutations of the candidates, and the caller renders the sheet from the slice it passed in. Pinning one leaves the other free: applied to the filtered copy, the re-scoring never reaches the sheet, and the row keeps a `conform` ranking factor the classification has just retired — a reason printed to the operator that is no longer true of the term. Measured 09.09: correct code gives no signals on that row, the planting gives [conform], and the whole package stays green",
"package": "./internal/pipeline/",
"run": "TestTheClassifiersTypeStillReachesTheSheetThroughTheFilter",
"battery": true,
"edits": [
{
"file": "internal/pipeline/terminologist.go",
"find": "\t\tfor i := range cands {\n\t\t\tterminology.ScoreVariants(&cands[i], opts)\n\t\t}",
"replace": "\t\tfor i := range paid {\n\t\t\tterminology.ScoreVariants(&paid[i], opts)\n\t\t}"
}
]
},
{
"id": "MONEY-the-one-time-cost-warning-reads-this-runs-own-checkpoints",
"why": "the warning about a one-time re-consolidation needs BOTH halves and each is knowable at only one moment: that the book had paid BEFORE this run, and that this run paid anyway. Asked after the passes, the probe sees the checkpoints THIS run just settled, so a fresh book paying for the first time is told it paid twice. That is the second viton of one bug — the version before it warned on every ordinary resume — and each shipped because its test asserted only silence, in a fixture where the firing branch was unreachable. ⚠ Two edits, and the second is not decoration: replacing the condition alone leaves paidBefore unused and the package does not compile, so the planting would report «nothing ran» — a mutation that cannot build is not a mutation that survived, but it is not a caught one either",
"package": "./internal/pipeline/",
"run": "TestTheOneTimeCostIsAnnouncedExactlyWhenItHappens",
"battery": true,
"edits": [
{
"file": "internal/pipeline/terminologist.go",
"find": "if res.BankSettled > 0 && run.fresh && paidBefore {",
"replace": "if paidNow, _ := r.Store.HasCheckpointForStage(r.Book.BookID, terminologyStageName); res.BankSettled > 0 && run.fresh && paidNow {"
},
{
"file": "internal/pipeline/terminologist.go",
"find": "\tpaidBefore, perr := r.Store.HasCheckpointForStage(r.Book.BookID, terminologyStageName)",
"replace": "\tpaidBefore, perr := r.Store.HasCheckpointForStage(r.Book.BookID, terminologyStageName)\n\t_ = paidBefore"
}
]
},
{
"id": "MONEY-the-filter-swallows-a-candidate-the-emission-would-have-emitted",
"why": "the drop is output-equivalent for the delta only because the filtered population is EXACTLY the one reverseSectionTerms drops: banknote-only candidates on a seed surface. Widen it to a mined candidate and the filter removes a term that would have reached the artifact the owner signs — money saved by losing a row. Every fixture that reached this filter carried a banknote candidate, so the condition was true of them by accident",
"package": "./internal/pipeline/",
"run": "TestTheSettledTestAnswersOnEachOfItsConditions",
"battery": true,
"edits": [
{
"file": "internal/pipeline/terminologist.go",
"find": "\tif c.Origin != terminology.OriginBanknote || len(c.Variants) == 0 {",
"replace": "\tif len(c.Variants) == 0 {"
}
]
},
{
"id": "MONEY-the-filter-does-not-read-the-seed-rows-aliases",
"why": "the emission's own guard indexes a seed row by its src AND its aliases, so a proposal named by an alias is dropped there. Indexing only the src here pays the role for exactly those proposals and then throws the answer away — the waste this filter exists to end, surviving in the population hardest to notice",
"package": "./internal/pipeline/",
"run": "TestTheSettledTestAnswersOnEachOfItsConditions",
"battery": true,
"edits": [
{
"file": "internal/pipeline/terminologist.go",
"find": "\t\tfor _, a := range e.Aliases {\n\t\t\tout[text.NormalizeSourceKey(a.Alias)] = e\n\t\t}",
"replace": "\t\t_ = e.Aliases"
}
]
},
{
"id": "MONEY-the-corrected-type-never-reaches-the-role",
"why": "the classifier is BOUGHT for the type field and that field travels to the role for the whole batch. The paid subset is rebuilt from the candidates AFTER the in-place passes precisely so the request carries the corrected type; drop the rebuild and the money is spent, the run prints reclassified=N, and the wire still says what the heuristic guessed. Third form of one root — a subset held as its own array — and the first two were both found after their own tests went green",
"package": "./internal/pipeline/",
"run": "TestTheClassifiersTypeStillReachesTheSheetThroughTheFilter",
"battery": true,
"edits": [
{
"file": "internal/pipeline/terminologist.go",
"find": "\t\tpaid = pickCandidates(cands, paidIdx)\n",
"replace": ""
}
]
},
{
"id": "MONEY-the-filter-does-not-fold-the-seed-surface",
"why": "the seed surfaces are indexed by their NORMALIZED key because that is what a candidate carries. Indexing the raw src instead makes the filter silently stop firing for every traditional or katakana spelling — and BankSettled then reads 0, which is indistinguishable from «there was nothing to skip»",
"package": "./internal/pipeline/",
"run": "TestTheFilterFoldsBothSidesTheWayProductionDoes",
"battery": true,
"edits": [
{
"file": "internal/pipeline/terminologist.go",
"find": "\t\tout[text.NormalizeSourceKey(e.Src)] = e",
"replace": "\t\tout[e.Src] = e"
}
]
},
{
"id": "MONEY-the-agreement-is-compared-byte-wise",
"why": "whether a draft AGREES with the bank is the money decision itself, and it is judged under the same target-form fold the vote is counted with. Compared byte-wise, a rendering differing only by case or ё reads as a disagreement and is paid for — the waste this filter exists to end, restored in the population nobody looks at",
"package": "./internal/pipeline/",
"run": "TestTheFilterFoldsBothSidesTheWayProductionDoes",
"battery": true,
"edits": [
{
"file": "internal/pipeline/terminologist.go",
"find": "\t\tif text.NormalizeTargetForm(v.Dst) != want {",
"replace": "\t\tif v.Dst != want {"
}
]
},
{
"id": "MONEY-the-saving-loses-its-denominator",
"why": "the saving is the one line a later shift greps to learn what the filter bought, and «12 skipped» is unreadable without «of 300». The keys are pinned directly rather than by the operator-message catalogue, which guards texts and says arguments are outside it — so without this planting the denominator could go to zero unnoticed",
"package": "./internal/pipeline/",
"run": "TestABankSettledCandidateIsNotPaidFor",
"battery": true,
"edits": [
{
"file": "internal/pipeline/terminologist.go",
"find": "\"book\", r.Book.BookID, \"skipped\", dropped, \"of_candidates\", len(cands), \"still_paid\", len(keptIdx),",
"replace": "\"book\", r.Book.BookID, \"skipped\", dropped, \"of_candidates\", 0, \"still_paid\", 0,"
}
]
},
{
"id": "SEAM-the-normalizer-stops-folding-and-the-fixture-does-not-notice",
"why": "the stop-sheet fixture claims its candidates are the population whose KEY differs from its SURFACE, and it asks the real normalizer whether they are. Its first version asserted that against two typed literals — and the fold it named did not exist — so a normalizer replaced by identity would have left it green while every traditional spelling stopped keying at all",
"package": "./internal/pipeline/",
"run": "TestEveryStopSheetFindingReachesTheRowItBelongsTo",
"battery": true,
"edits": [
{
"file": "internal/text/norm.go",
"find": "\t\tif m, ok := trad2simp[r]; ok {\n\t\t\tr = m\n\t\t}",
"replace": "\t\t_ = trad2simp"
}
]
},
{
"id": "BANKSHEET-a-row-nobody-was-asked-about-reads-as-undecided",
"why": "an empty dst on the signing sheet is the same glyph for four different facts: the role declined, no reply line covered the term, the budget did not reach it, and — since the already-banked filter — nobody was asked because there is nothing to decide. Three of those mean UNDECIDED and one means SETTLED, and the review ranking files all four together, so without the mark the owner cannot tell the row he can skip from the rows he must read",
"package": "./internal/pipeline/",
"run": "TestABankSettledCandidateIsNotPaidFor",
"battery": true,
"edits": [
{
"file": "internal/pipeline/mining.go",
"find": "\t\tif r.SettledByBank {\n\t\t\tb.WriteString(\" NOT ASKED(the bank already renders this surface and every draft agreed — nothing to decide)\")\n\t\t}\n",
"replace": ""
}
]
},
{
"id": "MONEY-the-one-time-cost-warning-drops-its-fresh-half",
"why": "the warning needs BOTH halves — that the book had paid BEFORE this run and that this run paid anyway — and dropping the second turns it into a claim of re-purchase on every ordinary resume, printed beside cost_usd=0.000000. It survived once already: the guard against it grepped the message's PROSE, and the prose had been reworded, so the substring occurred zero times in the module and the assertion could not fire. Both sides now read one structured key instead",
"package": "./internal/pipeline/",
"run": "TestAResumeFindsItsCheckpointsAfterTheFilter|TestTheOneTimeCostIsAnnouncedExactlyWhenItHappens",
"battery": true,
"edits": [
{
"file": "internal/pipeline/terminologist.go",
"find": "if res.BankSettled > 0 && run.fresh && paidBefore {",
"replace": "if res.BankSettled > 0 && paidBefore {"
}
]
},
{
"id": "BANKMONEY-the-run-total-drops-the-classifier",
"why": "the run's TOTAL is built from the terminologist's RENDER cost alone, and the classifier settles on its own cost axis under its own budget — so the figure an operator reads while deciding whether to keep paying is short by the whole classify phase. Measured on the live run of 08.09: two thirds of the terminology phase's money never reached the total. The pin compares the total against the ledger's own sum, on a fixture where the two phases deliberately cost DIFFERENT amounts, because the fake model bills a fixed price per call and equal costs would let the wrong addend pass",
"package": "./internal/pipeline/",
"run": "TestTheRunTotalIsThisRunsSpendIncludingTheClassifier",
"battery": true,
"edits": [
{
"file": "internal/pipeline/waverun.go",
"find": "\t\tres.TotalUSD += t.CostUSD + t.ClassifyCostUSD",
"replace": "\t\tres.TotalUSD += t.CostUSD"
}
]
},
{
"id": "BANKMONEY-the-two-bank-roles-share-one-position",
"why": "the bank roles are checkpointed under ONE synthetic stage at chapter 0 and number their batches in chunk_idx, so the classifier's batch 0 and the terminologist's batch 0 arrive at the same (chapter, chunk, stage) triple. Keyed on that triple alone the earlier of the two is filed as SUPERSEDED — money that bought nothing — and on the live run of 08.09 that was the classifier's $0.009013, the largest of the three ledger rows, reported to the operator as a loss while it was bought and used",
"package": "./internal/pipeline/",
"run": "TestTheLedgerSaysTheClassifierBoughtTheBank|TestTwoBankRolesInOneBatchAreTwoPositions",
"battery": true,
"edits": [
{
"file": "internal/pipeline/paidtail.go",
"find": "\tif u.Stage == terminologyStageName {\n\t\tp.role = u.Role\n\t}\n",
"replace": ""
}
]
},
{
"id": "BANKMONEY-the-role-column-leaves-the-ledger-query",
"why": "the decomposition can only tell the two bank roles apart if the role reaches it, and it reaches it through this SELECT. Dropping the column leaves every row's role empty, which is exactly the pre-fix collision with no visible cause — the struct still has the field and the code still reads it",
"package": "./internal/pipeline/",
"run": "TestTheLedgerSaysTheClassifierBoughtTheBank",
"battery": true,
"edits": [
{
"file": "internal/store/ledger.go",
"find": "SELECT j.chapter, c.chunk_idx, c.stage, c.role, c.model_requested",
"replace": "SELECT j.chapter, c.chunk_idx, c.stage, '' AS role, c.model_requested"
}
]
},
{
"id": "BANKMONEY-the-role-enters-every-position",
"why": "the OTHER side of the same fix, and the one that would land a second money change unannounced. A repair call carries its stage's REAL name and its own role (repair.go), so folding the role into every position separates a repair from the stage call it repairs and quietly moves that money out of `superseded`. The role belongs to the bank stage alone, where the triple is not an address",
"package": "./internal/pipeline/",
"run": "TestTheRoleSplitDoesNotMoveARepairsMoney",
"battery": true,
"edits": [
{
"file": "internal/pipeline/paidtail.go",
"find": "\tif u.Stage == terminologyStageName {\n\t\tp.role = u.Role\n\t}\n",
"replace": "\tp.role = u.Role\n"
}
]
},
{
"id": "BANKCOMPLETE-a-boundary-that-measured-nothing-claims-a-whole-bank",
"why": "the bank read-out is written at FIVE boundaries and the terminology pass runs at ONE, so a section published unconditionally answers «consolidated 0, unanswered 0» — which a consumer reads as «nothing is missing» — about a bank nobody looked at. This is the D39.202 class: the instrument answering its own question. The nil is the whole distinction",
"package": "./internal/pipeline/",
"run": "TestABoundaryThatMeasuredNothingSaysNothing",
"battery": true,
"edits": [
{
"file": "internal/pipeline/bankexport.go",
"find": "\tif t == nil {\n\t\treturn nil\n\t}\n\treturn &BankConsolidation{",
"replace": "\tif t == nil {\n\t\tt = &terminologyResult{}\n\t}\n\treturn &BankConsolidation{"
}
]
},
{
"id": "BANKCOMPLETE-a-classifier-cut-is-read-as-a-partial-bank",
"why": "the engine's own log warning fires on EITHER counter and said «PARTIALLY consolidated» on the run of 08.09, where the render pass was intact (batches_dropped=0) and only the classifier's budget cut a batch. Copying that rule into the projection makes a whole bank read as partial and sends an owner to re-buy renderings he already has — a false alarm built by the cure. The bank's completeness is the RENDER pass; the classifier's cut is the term TYPES and travels apart",
"package": "./internal/pipeline/",
"run": "TestAClassifierCutIsNotAnIncompleteBank",
"battery": true,
"edits": [
{
"file": "internal/pipeline/bankexport.go",
"find": "\t\tComplete: t.BatchesDropped == 0,",
"replace": "\t\tComplete: t.BatchesDropped == 0 && t.ClassifyBatchesDropped == 0,"
}
]
},
{
"id": "BANKCOMPLETE-the-read-out-stops-carrying-the-completeness",
"why": "the counters exist and the projection exists, and the artifact the signing screen is built from still does not carry them unless this line runs — which is precisely the state row 253(б) describes: the engine knowing and the reader not seeing",
"package": "./internal/pipeline/",
"run": "TestABankCutByABudgetSaysSoInTheReadOut",
"battery": true,
"edits": [
{
"file": "internal/pipeline/bankexport.go",
"find": "\texp.Consolidation = projectBankConsolidation(r.lastTerminology)\n",
"replace": ""
}
]
},
{
"id": "BANKCOMPLETE-the-stop-screen-is-handed-no-completeness",
"why": "the CLI renders what the stop hands it, so dropping the field on the stop leaves the screen able to print the state and never given one — and the owner reads THIS surface first, before either sidecar",
"package": "./internal/pipeline/",
"run": "TestTheSignatureStopCarriesTheCompletenessToTheScreen",
"battery": true,
"edits": [
{
"file": "internal/pipeline/waverun.go",
"find": "\t\t\tConsolidation: projectBankConsolidation(r.lastTerminology),\n",
"replace": ""
}
]
},
{
"id": "BANKCOMPLETE-the-never-asked-count-moves-under-the-stdout-cap",
"why": "a row the role was never asked about carries no rendering, so reviewRank sends it to 1000 — LAST — and the stdout table shows twenty rows: on any real book the whole class falls off the bottom. Leaving the per-row mark as the ONLY carrier makes the screen green on a narrow fixture and blind on a live one, which is the trap this surface was built around. ⚠ The first version of this entry swapped the summary and the table instead, and it SURVIVED — rightly: moving the line does not remove it, and a mutation that attacks nothing is a green record of a property nobody guards",
"package": "./cmd/tmctl/",
"run": "TestTheNeverAskedCountSurvivesTheStdoutCap",
"battery": true,
"edits": [
{
"file": "cmd/tmctl/render.go",
"find": "\tif c.NeverAsked > 0 {\n\t\t// The saving, and it is stated because an empty rendering in the table below is the same glyph as\n\t\t// «the role declined» and «the budget did not reach it» — three facts, one of which is good news.\n\t\tfmt.Fprintf(w, \" %d term(s) were NOT ASKED about: the bank already renders those surfaces and every \"+\n\t\t\t\"draft agreed — nothing to decide, and they are marked in the table and the full sidecar.\\n\", c.NeverAsked)\n\t}\n",
"replace": ""
}
]
},
{
"id": "BANKCOMPLETE-the-whole-bank-says-nothing",
"why": "a screen silent when the bank is whole makes its own silence carry meaning, and no reader can tell that silence from the screen not knowing — while «did not measure» is a THIRD state here, not a shade of complete. A pin that only asserts the alarm sounds stays green on a surface that has stopped saying anything in the good case",
"package": "./cmd/tmctl/",
"run": "TestTheSigningScreenSaysHowCompleteTheBankIs",
"battery": true,
"edits": [
{
"file": "cmd/tmctl/render.go",
"find": "\tcase c.Complete:\n\t\tfmt.Fprintf(w, \"Bank completeness: WHOLE — every render batch was bought (%d consolidated, %d declined, %d unanswered).\\n\",\n\t\t\tc.Consolidated, c.Declined, c.Unanswered)\n\tdefault:",
"replace": "\tcase c.Complete:\n\t\t_ = c.Consolidated\n\tdefault:"
}
]
},
{
"id": "BANKMONEY-the-run-total-reports-the-contours-cumulative-spend",
"why": "CostUSD is what the render phase paid THIS run; CumUSD is what the contour has cost since the book began, replayed checkpoints included at what they cost then. On a FIRST run the two are equal to the cent, so a total built from the wrong one is invisible there — and on a resume it reports money nobody spent, beside a ledger that did not move. The pin's second leg is a resume precisely because the first cannot tell them apart. ⛔ THE CATCHER MOVED ON 17.09 AND THE ENTRY DID NOT NOTICE — which is why the filter now names BOTH tests. The settled-basis pack split the original pin in two: its resume leg needs a budget with HEADROOM (so a re-asked batch can be bought and then replayed) while its first leg needs a budget that CUTS a batch (so the render and classify phases cost different amounts and the sum cannot be satisfied by the wrong addend), and with the basis in the tree those two requirements became arithmetically incompatible on one fixture. The resume leg — the ONLY leg that can tell CostUSD from CumUSD — moved to the second test, and this entry went on naming the first. It survived a full catalogue run and nothing cheaper would have seen it: the test was green, the split was reviewed, and the entry still pointed at a file that no longer holds the assertion",
"package": "./internal/pipeline/",
"run": "TestTheRunTotalIsThisRunsSpendIncludingTheClassifier|TestAReplayedBankContourIsFreeWhileItsCumulativeFigureRemembers",
"battery": true,
"edits": [
{
"file": "internal/pipeline/waverun.go",
"find": "\t\tres.TotalUSD += t.CostUSD + t.ClassifyCostUSD",
"replace": "\t\tres.TotalUSD += t.CumUSD + t.ClassifyCostUSD"
}
]
},
{
"id": "BANKCOMPLETE-the-signing-boundary-alone-publishes-nothing",
"why": "the read-out is refreshed at five boundaries and the signing screen is built from ONE of them — the signature stop. A section published everywhere EXCEPT there is green in every fixture that runs a book to completion, and absent in the only document an owner ever signs against. The pin reads the BYTES on disk at that boundary and checks as_of, so it cannot be satisfied by a later boundary's file",
"package": "./internal/pipeline/",
"run": "TestTheSigningBoundaryPublishesTheCompleteness",
"battery": true,
"edits": [
{
"file": "internal/pipeline/bankexport.go",
"find": "\texp.Consolidation = projectBankConsolidation(r.lastTerminology)",
"replace": "\tif at != \"bank-mining/signature-stop\" {\n\t\texp.Consolidation = projectBankConsolidation(r.lastTerminology)\n\t}"
}
]
},
{
"id": "BANKCOMPLETE-never-asked-is-fed-by-the-wrong-counter",
"why": "NeverAsked is the only counter of the six whose source is ZERO in every end-to-end fixture of this package, so a fold reading Declined into it stays green everywhere: the reflective guard only asks that a field be non-zero somewhere, and the screen's own fixtures build the struct by hand and never cross the seam. Distinct values per source are what make the wiring checkable at all",
"package": "./internal/pipeline/",
"run": "TestEachConsolidationCounterComesFromItsOwnSource",
"battery": true,
"edits": [
{
"file": "internal/pipeline/bankexport.go",
"find": "\t\tNeverAsked: t.BankSettled,",
"replace": "\t\tNeverAsked: t.Declined,"
}
]
},
{
"id": "BANKCOMPLETE-a-pass-that-asked-nothing-reports-bought-batches",
"why": "the already-banked filter can empty the paid set, and then NO batch was ever planned. «Every render batch was bought» is true of zero batches and reads as a report on work that happened — the D39.202 shape, committed by the surface built to remove it. Measured on a live fixture: the screen printed «WHOLE — every render batch was bought (0 consolidated, 0 declined, 0 unanswered)» about a pass that sent nothing and paid nothing",
"package": "./cmd/tmctl/",
"run": "TestTheSigningScreenSaysHowCompleteTheBankIs",
"battery": true,
"edits": [
{
"file": "cmd/tmctl/render.go",
"find": "\tcase c.Complete && c.Consolidated+c.Declined+c.Unanswered == 0:",
"replace": "\tcase false:"
}
]
},
{
"id": "TOCSEAM-the-declared-unreadable-toc-never-leaves-the-log",
"why": "a book that DECLARED a table of contents and whose bytes could not be read falls back to the spine and is sold by characters. The engine has counted that since row 312 and told only its own log, while the far side of the seam reads the manifest — so `structure: delimited` crossed with no way to tell «this book never had one» from «it had one and we could not read it». Dropping the field from the built document restores exactly that silence",
"package": "./internal/pipeline/",
"run": "TestTheManifestSaysADeclaredTableOfContentsCouldNotBeRead",
"battery": true,
"edits": [
{
"file": "internal/pipeline/manifest.go",
"find": "\t\t// Always set, never left nil: absent is reserved for a sidecar written before the field existed.\n\t\tTOCUnreadable: &tocUnreadable,\n",
"replace": ""
}
]
},
{
"id": "TOCSEAM-the-count-is-published-as-a-constant-zero",
"why": "the field can be present, well-typed and always zero — the shape that reads as «measured, nothing wrong» on every book, including the broken ones. The zero case cannot catch it (its answer IS zero), so only a fixture with a declared-and-unreadable table of contents can, and that is why the pin builds a real epub whose navigation document the archive does not carry",
"package": "./internal/pipeline/",
"run": "TestTheManifestSaysADeclaredTableOfContentsCouldNotBeRead",
"battery": true,
"edits": [
{
"file": "internal/pipeline/manifest.go",
"find": "\tm := r.buildManifest(ch, chunks, structure, tocUnreadable, before)",
"replace": "\tm := r.buildManifest(ch, chunks, structure, 0, before)"
}
]
},
{
"id": "BANKCOMPLETE-the-log-calls-a-classifier-cut-a-partial-bank",
"why": "one warning fired by EITHER counter said «this bank is PARTIALLY consolidated» on a run whose render pass was intact and whose classifier alone was cut (measured 08.09: batches_dropped=0, classify_batches_dropped=1, consolidated=29). That is a false alarm about the object an owner signs, and it made the engine contradict its own read-out, which reports the bank's completeness from the render pass alone. A pair of surfaces that argue with each other about one run is worse than either half",
"package": "./internal/pipeline/",
"run": "TestTheLogAndTheReadOutAgreeAboutWhatIsPartial",
"battery": true,
"edits": [
{
"file": "internal/pipeline/terminologist.go",
"find": "\tif res.BatchesDropped > 0 {\n\t\tr.Log.WarnContext(ctx, \"terminology: this bank is PARTIALLY consolidated",
"replace": "\tif res.BatchesDropped > 0 || res.ClassifyBatchesDropped > 0 {\n\t\tr.Log.WarnContext(ctx, \"terminology: this bank is PARTIALLY consolidated"
}
]
},
{
"id": "CUTCALL-everything-counts-as-delivered",
"why": "the money boundary is DELIVERY. Read as always-true it settles an estimate for a request that never left the process — a TLS handshake that hung, a dead host — which is the one case where «nothing was bought» is true by construction. That is the boundary inverted: paying for calls nobody received.",
"package": "./internal/pipeline/",
"run": "TestTheNineOutcomesOfACall",
"battery": true,
"edits": [
{
"file": "internal/llm/attemptcut.go",
"find": "\tif !tr.delivered(answered) {\n\t\treturn nil\n\t}",
"replace": "\tif false {\n\t\treturn nil\n\t}"
}
]
},
{
"id": "CUTCALL-nothing-counts-as-delivered",
"why": "the same boundary read as always-false: every delivered-and-cut call goes back to booking ZERO, which is the defect backlog row 360 measured at 2334% of an editor run. The pin has to fail on BOTH readings of one bit, or it is pinning the bit in one direction only.",
"package": "./internal/pipeline/",
"run": "TestTheNineOutcomesOfACall",
"battery": true,
"edits": [
{
"file": "internal/llm/attemptcut.go",
"find": "\tif !tr.delivered(answered) {\n\t\treturn nil\n\t}",
"replace": "\tif true {\n\t\treturn nil\n\t}"
}
]
},
{
"id": "CUTCALL-our-own-deadline-is-retried",
"why": "a call OUR deadline cut is still being generated by the provider; retrying it buys that generation a second time. The old code did exactly this because it judged truncation by SIZE, and a body our deadline cut is small.",
"package": "./internal/pipeline/",
"run": "TestTheNineOutcomesOfACall",
"battery": true,
"edits": [
{
"file": "internal/llm/attemptcut.go",
"find": "func (e *AttemptCutError) retryable() bool { return e.Cause == CutByConnection }",
"replace": "func (e *AttemptCutError) retryable() bool { return e.Cause != CutByParent }"
}
]
},
{
"id": "CUTCALL-a-self-cut-leaves-no-resolution",
"why": "THE THIRD LEAK, and the one that is invisible without this pin: without a resolved position the resume walks back to the provider and buys the call AGAIN through the resume door, so removing the retry alone would close the class halfway. Its test carries no money assertion on purpose — a red about the ledger here would be a right verdict for the wrong reason.",
"package": "./internal/pipeline/",
"run": "TestAfterASelfCutTheResumeCallsNobody",
"battery": true,
"edits": [
{
"file": "internal/pipeline/cutcall.go",
"find": "\tif cut.Cause == llm.CutBySelfDeadline {",
"replace": "\tif false && cut.Cause == llm.CutBySelfDeadline {"
}
]
},
{
"id": "CUTCALL-the-cut-costs-nothing",
"why": "the amount is the owners decision (D39.230 п.1): a call we cut is settled at the reservation estimate, not at zero. Booking zero understates the book against its own ceiling and hands the platform a margin it cannot measure.",
"package": "./internal/pipeline/",
"run": "TestTheNineOutcomesOfACall",
"battery": true,
"edits": [
{
"file": "internal/pipeline/cutcall.go",
"find": "func settleUSDForCutCall(estimate float64) float64 { return estimate }",
"replace": "func settleUSDForCutCall(estimate float64) float64 { return 0 }"
}
]
},
{
"id": "CUTCALL-a-stopped-run-leaves-no-mark",
"why": "the mark for a stopped position is what keeps a paid, unfinished chunk from reading as never started; inverting the stop test makes the guard mark everything EXCEPT a stop, which is the same silence in the mirror",
"package": "./internal/pipeline/",
"run": "TestTheNineOutcomesOfACall",
"battery": true,
"edits": [
{
"file": "internal/pipeline/cutcall.go",
"find": "\tif errors.Is(err, context.Canceled) && errors.As(err, &cut) {",
"replace": "\tif !errors.Is(err, context.Canceled) && errors.As(err, &cut) {"
}
]
},
{
"id": "CUTCALL-a-cancelled-mark-is-read-as-a-verdict",
"why": "`cancelled` records a STOP, not an answer. Served as a resolved verdict the resume re-does nothing, and the construction degenerates into its opposite — never re-doing anything that was interrupted — while every money assertion stays green.",
"package": "./internal/pipeline/",
"run": "TestTheNineOutcomesOfACall",
"battery": true,
"edits": [
{
"file": "internal/pipeline/disposition.go",
"find": "\tcase FlagCancelled, FlagRetryUnaffordable:\n\t\treturn false",
"replace": "\tcase FlagRetryUnaffordable:\n\t\treturn false"
}
]
},
{
"id": "CUTCALL-a-paid-cut-checkpoint-is-replayed-as-a-result",
"why": "a `cancelled`/`connection_lost` checkpoint records money and NO result. Replayed as a completion it hands the stage an empty answer it never received, and the interrupted work is silently never re-done.",
"package": "./internal/pipeline/",
"run": "TestTheNineOutcomesOfACall",
"battery": true,
"edits": [
{
"file": "internal/pipeline/disposition.go",
"find": "\treturn cp.FinishReason == cancelledFinish || cp.FinishReason == connectionLostFinish\n",
"replace": "\treturn false\n"
}
]
},
{
"id": "CUTCALL-the-redo-doubles-the-budget",
"why": "the re-done call must carry the budget the cut one was granted, and a REGENERATION after it must be ONE doubling and not two. Keyed on the attempt index instead of the doubling count, a burn followed by a truncated answer asks for FOUR times the base and reserves the money for it. ⚠ The simple case stopped proving this the day the burn walk moved inside runAttempt — the caller's index never advances for a burn, so both readings agree there and this mutation SURVIVED a green package. Only the compound sequence (burn → length → regenerate) separates them.",
"package": "./internal/pipeline/",
"run": "TestABurnFollowedByARegenerationDoesNotOverBuy",
"battery": true,
"edits": [
{
"file": "internal/pipeline/attemptladder.go",
"find": "\t\tmaxTokens := maxTokensForAttempt(lc.baseMaxTokens, run.doublings)",
"replace": "\t\tmaxTokens := maxTokensForAttempt(lc.baseMaxTokens, attempt)"
}
]
},
{
"id": "CUTCALL-a-stop-forgets-what-it-interrupted",
"why": "the FIRST cancellation exit. The retry loop used to return a bare ctx.Err() there, throwing away the only evidence that the stopped run had a request ON THE WIRE — so the runner could not settle a call it was never told about, and the position was left with no mark at all.",
"package": "./internal/llm/",
"run": "TestACancelledRunKeepsBothTruthsInOneError",
"battery": true,
"edits": [
{
"file": "internal/llm/httpllm.go",
"find": "\t\t\treturn zero, chainError(cancelledDuring(ctx.Err(), err), owedCut)",
"replace": "\t\t\treturn zero, ctx.Err()"
}
]
},
{
"id": "CUTCALL-a-non-2xx-becomes-a-purchase",
"why": "the status line is read BEFORE the bodys read error. Reversed, every 4xx/5xx whose small body happens to land on the deadline settles an estimate for a generation that never happened — the money boundary leaking through the one door that is supposed to be free.",
"package": "./internal/pipeline/",
"run": "TestANonTwoHundredIsNotAPurchase",
"battery": true,
"edits": [
{
"file": "internal/llm/httpllm.go",
"find": "\tif resp.StatusCode < 200 || resp.StatusCode >= 300 {\n\t\tretryable := retryableStatus(resp.StatusCode, data)",
"replace": "\tif false {\n\t\tretryable := retryableStatus(resp.StatusCode, data)"
}
]
},
{
"id": "CUTDEADLINE-the-deadline-is-a-constant-again",
"why": "attempt_s read as THE deadline rather than as its floor is the original defect: 240 s is what the vendor rate gives for the DRAFT, and it was carried to an editor budgeted at 16 000 with a doubling to 32 000 — a call that could not finish inside it at any real speed.",
"package": "./internal/llm/",
"run": "TestTheDeadlineClampsAtBothEnds",
"battery": true,
"edits": [
{
"file": "internal/llm/attemptcut.go",
"find": "\td := p.deriveDeadline(maxTokens)\n\tif d < p.AttemptTimeout {",
"replace": "\td := p.AttemptTimeout\n\tif d < p.AttemptTimeout {"
}
]
},
{
"id": "CUTDEADLINE-attempt-s-stops-being-a-floor",
"why": "attempt_s being a FLOOR is what let this land on every shipping config at once — no provider loses a second it has today. Without the clamp a fast declared floor SHORTENS an existing deadline, and calls that fit today start being cut and billed as estimates.",
"package": "./internal/llm/",
"run": "TestTheDeadlineClampsAtBothEnds",
"battery": true,
"edits": [
{
"file": "internal/llm/attemptcut.go",
"find": "\tif d < p.AttemptTimeout {\n\t\td = p.AttemptTimeout\n\t}",
"replace": "\tif false {\n\t\td = p.AttemptTimeout\n\t}"
}
]
},
{
"id": "CUTDEADLINE-an-unset-floor-divides-by-zero",
"why": "a config that omits tok_s_floor must wait the vendor default — too long, never not at all. A zero floor read literally makes the derived deadline meaningless and would cut every call the instant it went out, billing each one as an estimate.",
"package": "./internal/llm/",
"run": "TestAnUnsetOrBrokenFloorFallsBackToTheVendorDefault",
"battery": true,
"edits": [
{
"file": "internal/llm/attemptcut.go",
"find": "\tif floor <= 0 {\n\t\tfloor = defaultTokensPerSecFloor()\n\t}",
"replace": "\tif floor < 0 {\n\t\tfloor = defaultTokensPerSecFloor()\n\t}"
}
]
},
{
"id": "CUTMONEY-the-estimated-share-publishes-as-zero",
"why": "the machine-readable estimated pair beside committed_usd is the CONDITION the owners word came with, and the engine half of PD-441: without it the platform bills committed_usd and can say «at least this much» but never «at least X, up to Y».",
"package": "./internal/pipeline/",
"run": "TestTheNineOutcomesOfACall",
"battery": true,
"edits": [
{
"file": "internal/pipeline/paidtail.go",
"find": "\t\tif tok.PromptTokens == 0 && tok.CompletionTokens == 0 && tok.ReasoningTokens == 0 {",
"replace": "\t\tif false {"
}
]
},
{
"id": "CUTMONEY-every-paid-row-is-called-an-estimate",
"why": "the other side of the same field. Marking every paid row estimated satisfies every positive assertion in the table and publishes a figure that says nothing — the shape a disclosure fails in quietly.",
"package": "./internal/pipeline/",
"run": "TestTheNineOutcomesOfACall",
"battery": true,
"edits": [
{
"file": "internal/pipeline/paidtail.go",
"find": "\t\tif tok.PromptTokens == 0 && tok.CompletionTokens == 0 && tok.ReasoningTokens == 0 {",
"replace": "\t\tif true {"
}
]
},
{
"id": "CUTWARN-the-default-floor-notice-is-never-said",
"why": "a provider with no measured speed runs on the vendor default and may wait a quarter of an hour. That is legitimate and must never be a surprise: the notice is what makes a new provider usable as DATA rather than as a mystery.",
"package": "./internal/llm/",
"run": "TestTheFloorWarningIsSaidOnceAndOnlyWhenItApplies",
"battery": true,
"edits": [
{
"file": "internal/llm/attemptcut.go",
"find": "\tif c.profile.TokensPerSecFloor <= 0 && d > c.profile.AttemptTimeout {",
"replace": "\tif false {"
}
]
},
{
"id": "CUTWARN-the-notice-is-said-for-a-provider-that-does-not-need-it",
"why": "the silent half. A notice printed for a provider whose calls all fit inside its own attempt_s is a warning about nothing, and an operator learns to scroll past the line that was supposed to explain a fifteen-minute wait.",
"package": "./internal/llm/",
"run": "TestTheFloorWarningIsSaidOnceAndOnlyWhenItApplies",
"battery": true,
"edits": [
{
"file": "internal/llm/attemptcut.go",
"find": "\tif c.profile.TokensPerSecFloor <= 0 && d > c.profile.AttemptTimeout {",
"replace": "\tif c.profile.TokensPerSecFloor <= 0 {"
}
]
},
{
"id": "CUTWAIT-the-waiting-line-is-never-said",
"why": "with a deadline derived from the budget a call may legitimately run for a quarter of an hour, and one «calling model» line then leaves an operator watching a silence indistinguishable from a wedged process.",
"package": "./internal/pipeline/",
"run": "TestTheWaitSaysSoWhileItLastsAndIsSilentOtherwise",
"battery": true,
"edits": [
{
"file": "internal/pipeline/stagerun.go",
"find": "\tstopHeartbeat := r.logWaitingForProvider(ctx, st, ch, model, attempt, maxTokens)",
"replace": "\tstopHeartbeat := func() {}"
}
]
},
{
"id": "CUTWAIT-the-interval-ignores-the-wait-it-reports",
"why": "the heartbeat is paced off the wait the engine actually granted. Fixed instead of derived, the line exists only for calls longer than the constant — which is every call nobody can observe and no test can afford to watch.",
"package": "./internal/pipeline/",
"run": "TestTheHeartbeatIsPacedByTheWaitItReports",
"battery": true,
"edits": [
{
"file": "internal/pipeline/stagerun.go",
"find": "\tq := deadline / 4\n",
"replace": "\tq := deadline\n"
}
]
},
{
"id": "CUTCATALOG-a-long-waiting-provider-declares-nothing",
"why": "the catalogue gate is what makes «a provider the repository has never seen» work as DATA: one whose declared floors make its calls outgrow its own attempt_s must name either the speed it holds or how long we will wait. Dropped, the config says 240 s while the engine waits twenty minutes.",
"package": "./internal/config/",
"run": "TestAProviderThatWillWaitLongSaysSoInTheCatalog",
"battery": true,
"edits": [
{
"file": "configs/models.yaml",
"find": ", tok_s_floor: 50, queue_slack_s: 600, attempt_max_s: 1240 }",
"replace": " }"
}
]
},
{
"id": "CUTSEAM-the-estimated-pair-vanishes-on-a-clean-book",
"why": "the platform bills committed_usd from status --json and needs the estimated pair BESIDE it to say «≥ X, up to Y» instead of only «≥» (PD-441; the condition on D39.230 п.1). With omitempty the fields disappear exactly when the answer is «none of it was estimated», and a consumer cannot tell that from an engine too old to publish them — so a fully measured book reads as uncertain.",
"package": "./cmd/tmctl/",
"run": "TestStatusJSONPublishesTheEstimatedShareBesideCommitted",
"battery": true,
"edits": [
{
"file": "internal/pipeline/status.go",
"find": "\tEstimatedRows int `json:\"estimated_rows\"`\n\tEstimatedUSD float64 `json:\"estimated_usd\"`",
"replace": "\tEstimatedRows int `json:\"estimated_rows,omitempty\"`\n\tEstimatedUSD float64 `json:\"estimated_usd,omitempty\"`"
}
]
},
{
"id": "CUTFLAG-a-cut-chunk-is-the-mildest-thing-that-can-happen",
"why": "a flag with no entry in flagSeverity falls to severityUnknown, which is LAST — so a chapter whose worst problem is «we paid for a call, our own deadline cut it and the text is gone» would report any other flag as its worst. Measured on this very pack: both new flags landed there while the exhaustiveness gate stayed GREEN, because it could not read a FlagReason declared as a conversion of another package's constant (18 ranks against 16 constants it could see).",
"package": "./internal/pipeline/",
"run": "TestEveryFlagReasonIsRanked",
"battery": true,
"edits": [
{
"file": "internal/pipeline/status.go",
"find": "\tFlagDecodeError: 4,\n\tFlagAttemptTimeout: 4,\n",
"replace": "\tFlagDecodeError: 4,\n"
}
]
},
{
"id": "CUTFLAG-the-rank-gate-goes-blind-to-a-converted-constant",
"why": "the gate's own guard. A FlagReason whose value is a conversion of another package's constant has no literal to unquote, and the walk used to `continue` past it — a silent skip inside an exhaustiveness test, which is the very defect the test exists to catch, one level up. Removing the resolver must make it FAIL LOUD about the unreadable value, never go quiet again.",
"package": "./internal/pipeline/",
"run": "TestEveryFlagReasonIsRanked",
"battery": true,
"edits": [
{
"file": "internal/pipeline/flagseverity_test.go",
"find": "\t\"llm.CutBySelfDeadline\": FlagReason(llm.CutBySelfDeadline),\n",
"replace": ""
}
]
},
{
"id": "CUTCALL-a-word-is-enough-to-burn-a-paid-answer",
"why": "the finish_reason string shares a namespace with whatever a vendor prints — the adapter already normalises invented values like «sensitive» — so keying the burn on the word alone throws away a real translation that happened to arrive under one of our own names, and buys it again. A genuine burn is written by this engine and is always textless.",
"package": "./internal/pipeline/",
"run": "TestABurnIsMoneyWithoutAnAnswerAndNotJustAWord",
"battery": true,
"edits": [
{
"file": "internal/pipeline/disposition.go",
"find": "\tif cp.ResponseText != \"\" {\n\t\treturn false // a reply with content is an answer, whatever it calls its finish reason\n\t}\n",
"replace": ""
}
]
},
{
"id": "CUTVOLUME-a-stopped-position-is-counted-as-a-free-resume",
"why": "the volume planner asks «does this row resume without a provider call» with its own copy of the predicate. Not knowing about `cancelled`, it counts a unit whose last row is one as costing nothing — so a grant of ONE unit pays for two, and the volume report, which speaks only when something was carried, says nothing at all. Two copies of one question is how the disclosure went silent.",
"package": "./internal/pipeline/",
"run": "TestACancelledRowIsNotAFreeResume",
"battery": true,
"edits": [
{
"file": "internal/pipeline/volume.go",
"find": "\t\tif !resolvedForResume(&cs) {\n\t\t\treturn false\n\t\t}\n",
"replace": ""
}
]
},
{
"id": "CUTCALL-a-reply-that-outruns-our-own-write-books-zero",
"why": "net/http hands back a response before WroteRequest fires (Request.write defers it onto the write loop; roundTrip returns on the response channel), so a provider answering EARLY — which DeepSeek documents doing while a request waits to be scheduled — can have its 200 overtake our own callback while the request body still drains. Read as «not delivered» that call books $0 and is re-asked under the full attempt budget: the very leak this pack closes, entering through its own door.",
"package": "./internal/llm/",
"run": "TestAReplyThatOutrunsOurOwnWriteIsStillDelivered|TestDeliveryEvidenceIsWhatTheMoneyBitAsks",
"battery": true,
"edits": [
{
"file": "internal/llm/attemptcut.go",
"find": "\treturn t.wrote.Load() || (answered && t.firstByte.Load())",
"replace": "\treturn t.wrote.Load()"
}
]
},
{
"id": "CUTCALL-a-failed-write-counts-as-a-delivery",
"why": "`WroteRequest` fires with an ERROR when the write itself failed: the provider received nothing, generated nothing and owes nothing, so settling an estimate charges a reader for a call nobody got. The guard had no pin at all until an adversarial pass removed it and watched both packages stay green.",
"package": "./internal/llm/",
"run": "TestAFailedWriteIsNotADelivery",
"battery": true,
"edits": [
{
"file": "internal/llm/attemptcut.go",
"find": "\t\t\tif info.Err == nil {\n\t\t\t\tt.wrote.Store(true)\n\t\t\t}",
"replace": "\t\t\tt.wrote.Store(true)"
}
]
},
{
"id": "CUTCEILING-a-cancelled-run-reports-a-money-stop",
"why": "a run that is ENDING did not stop on money, whatever the ledger says at that instant. Paying for a cut call (D39.230 п.1) made this reachable: a stop commits every flying call's estimate, which can carry a book past its own ceiling, and the next worker then publishes a `ceiling` event with a shortfall. The platform lets that event survive any exit code, so it records `paused` and tells a person to add money for a run that person stopped themselves. Caught by the existing wait-cancellation pin only intermittently — the guard first sat at the top of the loop, and waitForSettle answers «nothing in flight» BEFORE it looks at the context, so a worker fell through it to the halt.",
"package": "./internal/pipeline/",
"run": "TestACancelledRunNeverReportsAMoneyStop",
"battery": true,
"edits": [
{
"file": "internal/pipeline/stagerun.go",
"find": "\t\tif ctx.Err() != nil {\n\t\t\t// Same as the aborted wait above, and through the SAME contract: nothing was called and nothing\n\t\t\t// broke, so a cancelled run leaves this position resumable rather than recording it as a failure\n\t\t\t// (backlog row 389). It is ROUTED rather than simply omitted so the family can be counted: every\n\t\t\t// site that might write the word goes through one function, and a reader enumerating them finds\n\t\t\t// no exceptions to explain.\n\t\t\tr.noteJobFailed(ctx, job.ID, ctx.Err())\n\t\t\treturn att, fmt.Errorf(\"pipeline: reserve $%.6f for %s/ch%d/chunk%d/%s: the run ended before the reservation was granted: %w\",\n\t\t\t\testimate, r.Book.BookID, ch.Chapter, ch.ChunkIdx, st.Name, ctx.Err())\n\t\t}\n",
"replace": ""
}
]
},
{
"id": "CUTCALL-a-stop-during-a-backoff-forgets-what-it-interrupted",
"why": "the SECOND cancellation exit. A run stopped during a retry backoff has a delivered, possibly billed attempt behind it — a cut connection, an undecodable 2xx — and a bare ctx.Err() there leaves the runner nothing to settle and the chunk no mark at all. Measured: a delivered connection_lost plus a stop inside the backoff booked $0 and wrote no chunk_status row. The window is the whole sleep, up to a minute on the shipping config, and it opens exactly where a flapping provider makes an operator reach for the stop.",
"package": "./internal/llm/",
"run": "TestAStopDuringABackoffKeepsTheEvidence",
"battery": true,
"edits": [
{
"file": "internal/llm/httpllm.go",
"find": "\t\t\treturn zero, chainError(cancelledDuring(ctx.Err(), lastErr), owedCut)",
"replace": "\t\t\treturn zero, ctx.Err()"
}
]
},
{
"id": "CUTMONEY-money-a-redrive-unaccounted-for-reads-as-measured",
"why": "a redrive DELETES the checkpoints of the stages it re-attacks and leaves their spend committed («after a redrive committed(spend) >= SUM(checkpoints), the safe direction», store/chunkstatus.go). Derived from the surviving rows alone the published estimate falls to zero, and the platform is told that money nobody can account for was MEASURED — the one direction this figure exists to prevent. Measured on a live redrive: committed unchanged at $0.001056, estimated dropped to $0.",
"package": "./internal/pipeline/",
"run": "TestMoneyWithNoCheckpointLeftIsStillAnEstimate",
"battery": true,
"edits": [
{
"file": "internal/pipeline/paidtail.go",
"find": "\tif gap := committedUSD - accounted; gap > 1e-9 {\n\t\trows, usd = rows+1, usd+gap\n\t}\n",
"replace": ""
}
]
},
{
"id": "CUTCALL-a-refusal-pays-when-the-reply-outruns-the-write",
"why": "the regression the early-200 fix introduced, and the more expensive direction of the same bit. A provider that REFUSES (401/403/413/quota-429) and resets while our body is still writing gives GotFirstResponseByte=true and a WRITE error, so http.Client.Do returns the write failure and the status line is never in our hands. Taking the response byte alone as proof of delivery paid an estimate for every one: measured 22 refusals in 25, one of them $0.80 for a request the provider declined — and the delivered-cut retry sent the whole body again.",
"package": "./internal/llm/",
"run": "TestARefusalIsNotAPurchaseEvenWhenTheReplyOutrunsTheWrite|TestDeliveryEvidenceIsWhatTheMoneyBitAsks",
"battery": true,
"edits": [
{
"file": "internal/llm/attemptcut.go",
"find": "\treturn t.wrote.Load() || (answered && t.firstByte.Load())",
"replace": "\treturn t.wrote.Load() || t.firstByte.Load()"
}
]
},
{
"id": "CUTVOLUME-a-retired-stage-costs-a-slot",
"why": "the per-row walk drops the stages this pipeline no longer runs — nothing will call them, so they cannot cost anything. Asking «does this row resume for free» BEFORE that drop makes a unit paid for a `cancelled` row of a retired stage, so an operator who edits the pipeline over a stopped run spends volume slots on calls that will never be made. Same error as the one this predicate fixed, in the opposite direction.",
"package": "./internal/pipeline/",
"run": "TestADroppedStageIsFreeEvenWhenItsRowSaysCancelled",
"battery": true,
"edits": [
{
"file": "internal/pipeline/volume.go",
"find": "\t\tvar cur string\n\t\tvar w wave",
"replace": "\t\tif !resolvedForResume(&cs) {\n\t\t\treturn false\n\t\t}\n\t\tvar cur string\n\t\tvar w wave"
}
]
},
{
"id": "CUTCALL-a-redirect-carries-delivery-to-the-next-hop",
"why": "`Do` spans the WHOLE redirect chain and the delivery trace does not reset between its legs, so the first leg reaching a redirector sets WroteRequest for good — and a second leg whose connect is REFUSED still looked delivered. Measured through the ledger: $0.001056 booked for a `connect: connection refused` that never put a byte on any wire, AfterHeaders true, zero bytes from the target. A stale `http://` in base_url is enough to trigger it; following the redirect at all also carries an Authorization header to a host nobody chose.",
"package": "./internal/llm/",
"run": "TestARedirectIsNotADelivery",
"battery": true,
"edits": [
{
"file": "internal/llm/httpllm.go",
"find": "\treturn &http.Client{Transport: base, CheckRedirect: doNotFollowRedirects}",
"replace": "\treturn &http.Client{Transport: base}"
}
]
},
{
"id": "CUTWAIT-the-waiting-line-claims-a-delivery-it-never-checked",
"why": "the runner cannot see the transport's trace, so «a call that has been delivered» was an assertion nobody had asked. On a request that never went out it printed eighteen times, telling the operator the opposite of what happened — the same defect as a flag naming the wrong cause (D39.93 п.2).",
"package": "./internal/pipeline/",
"run": "TestTheWaitSaysSoWhileItLastsAndIsSilentOtherwise",
"battery": true,
"edits": [
{
"file": "internal/pipeline/stagerun.go",
"find": "\"still waiting for the provider on a call in flight\"",
"replace": "\"still waiting for the provider on a call that has been delivered\""
}
]
},
{
"id": "CUTCALL-the-local-client-still-follows-redirects",
"why": "the redirect guard first went only on the cloud client, whose own comment says the local provider «passes its OWN no-proxy client, so it is untouched» — true of keepalive, and read as permission for redirects too. Both go through the same attempt() and the same delivery trace, so a leg whose connect is refused still looks delivered. Measured on the local client after the cloud one was fixed: an AttemptCutError for a `connect: connection refused` with two hops. The money is $0 there only because the local model is priced at zero; the behaviour is wrong either way.",
"package": "./internal/llm/",
"run": "TestARedirectIsNotADelivery",
"battery": true,
"edits": [
{
"file": "internal/llm/provider_local.go",
"find": "\treturn &http.Client{Transport: &http.Transport{Proxy: nil}, CheckRedirect: doNotFollowRedirects}",
"replace": "\treturn &http.Client{Transport: &http.Transport{Proxy: nil}}"
}
]
},
{
"id": "CUTWAIT-a-per-attempt-deadline-is-printed-as-the-whole-wait",
"why": "the heartbeat wraps client.Complete — the WHOLE retry chain — while the only deadline it can name is one ATTEMPT's. Under the key `of` that printed «waited=4s of=1s», a contradiction that reads as exactly the hung process the line exists to rule out; measured at 18 such lines in one run. The key `attempt` was a second half of the same: the transport logs an `attempt` of its own, and two different numbers under one name in one stream is a question an operator cannot answer.",
"package": "./internal/pipeline/",
"run": "TestTheWaitSaysSoWhileItLastsAndIsSilentOtherwise",
"battery": true,
"edits": [
{
"file": "internal/pipeline/stagerun.go",
"find": "\"stage_attempt\", attempt, \"waited\", time.Since(started).Round(time.Millisecond).String(),\n\t\t\t\t\t\"attempt_deadline\", r.Models.AttemptDeadline(model, maxTokens).String())",
"replace": "\"attempt\", attempt, \"waited\", time.Since(started).Round(time.Millisecond).String(),\n\t\t\t\t\t\"of\", r.Models.AttemptDeadline(model, maxTokens).String())"
}
]
},
{
"id": "CUTCALL-the-anthropic-client-carries-its-key-through-a-redirect",
"why": "the third client this package builds, and the one where the redirect is a CREDENTIAL leak rather than a money one: it sends `x-api-key`, and net/http strips only Authorization/Cookie/WWW-Authenticate across a host change. Measured: the redirect target received the key verbatim and the call returned a nil error. The adapter is deprecated with no live provider, but clients.go builds it for any config declaring `kind: anthropic`.",
"package": "./internal/llm/",
"run": "TestARedirectIsNotADelivery",
"battery": true,
"edits": [
{
"file": "internal/llm/provider_anthropic.go",
"find": "\t\thttp: &http.Client{CheckRedirect: doNotFollowRedirects},",
"replace": "\t\thttp: &http.Client{},"
}
]
},
{
"id": "CUTMONEY-the-operator-screen-drops-the-estimated-share",
"why": "the human twin of the status --json seam, and it had no pin at all — removing the block left both packages green while renderStatusHuman itself is 76% covered. It is the surface an operator reads before deciding whether to keep paying, and the number beside `committed` is what makes that figure a RANGE rather than a measurement (the condition attached to D39.230 п.1).",
"package": "./cmd/tmctl/",
"run": "TestStatusHumanShowsTheEstimatedShare",
"battery": true,
"edits": [
{
"file": "cmd/tmctl/render.go",
"find": "\tif rep.EstimatedRows > 0 {",
"replace": "\tif false {"
}
]
},
{
"id": "CUTCALL-a-stop-over-the-hop-leaves-no-mark",
"why": "the cancelled-position mark lived at the attempt loop's error return, and the escalation hop, the repair sub-step and the bank batches all leave runStage through OTHER returns. Measured by an acceptance verifier: a run stopped over the HOP settled the money and left chunk_status_rows=0 — the unmarked hole §4.2 forbids — while the resume made ZERO fresh calls because the hop addresses a fixed attempt 0 and the burned key there is hit forever.",
"package": "./internal/pipeline/",
"run": "TestAStopOverAnEscalationHopLeavesAMarkAndIsRedone",
"battery": true,
"edits": [
{
"file": "internal/pipeline/stagerun.go",
"find": "\tdefer func() {\n\t\tr.recordStoppedPosition(ctx, stoppedPosition{\n\t\t\tstage: st, chunk: ch, snapshotID: snapID, contentHash: contentHash,\n\t\t\tcumCostUSD: cumCost, attempts: attemptsMade, paidAttempts: lr.judged, inHand: last,\n\t\t\tfirstFlagReason: firstFlagReason,\n\t\t}, err)\n\t}()\n",
"replace": ""
}
]
},
{
"id": "CUTCALL-a-burned-key-is-spent-only-inside-the-loop",
"why": "walking over a burned key first lived in runStage's loop, leaving the three callers OUTSIDE it with a key burnt forever — the hop most visibly, since it addresses a fixed attempt 0. Moving the walk into runAttempt gives every caller the rule; putting it back into the loop alone re-opens «money spent, work never re-done» for the hop, the repair sub-step and the bank batches at once.",
"package": "./internal/pipeline/",
"run": "TestAStopOverAnEscalationHopLeavesAMarkAndIsRedone",
"battery": true,
"edits": [
{
"file": "internal/pipeline/stagerun.go",
"find": "\t\tif cp == nil || !burnedByCut(cp) {\n\t\t\tbreak\n\t\t}",
"replace": "\t\tif cp == nil || true {\n\t\t\tbreak\n\t\t}"
}
]
},
{
"id": "CUTCALL-a-cut-checkpoint-is-written-under-the-wrong-key",
"why": "§4.3's real claim: the resume finds the CHECKPOINT of a self-cut. The ordinary resume resolves from chunk_status before any render, so a pin that stops there proves the first door shut and says nothing about the second — an acceptance verifier planted this and it SURVIVED a green package. The torn-store fixture enters through the door the checkpoint exists for.",
"package": "./internal/pipeline/",
"run": "TestASelfCutResumesFromITSCHECKPOINTAndNotOnlyFromChunkStatus",
"battery": true,
"edits": [
{
"file": "internal/pipeline/cutcall.go",
"find": "\t\tRequestHash: c.reqHash, JobID: c.job.ID",
"replace": "\t\tRequestHash: c.reqHash + \"z\", JobID: c.job.ID"
}
]
},
{
"id": "CUTCALL-classify-forgets-what-a-cut-checkpoint-means",
"why": "a replayed cut checkpoint with no verdict falls through to «empty completion» — and `empty` is RETRYABLE, so the chunk is re-bought on a DOUBLED budget. The chunk_status door hides it: this mutation SURVIVED on a green package until a fixture reached the checkpoint path directly.",
"package": "./internal/pipeline/",
"run": "TestASelfCutResumesFromITSCHECKPOINTAndNotOnlyFromChunkStatus",
"battery": true,
"edits": [
{
"file": "internal/pipeline/disposition.go",
"find": "\tcase attemptTimeoutFinish:",
"replace": "\tcase attemptTimeoutFinish + \"-dead\":"
}
]
},
{
"id": "CUTCALL-a-delivered-cut-is-erased-by-a-later-terminal-status",
"why": "only the LAST error left the retry loop, so a chain that cut a delivered request and then met a terminal 4xx returned the status alone: the runner read «the request never went out», released the reservation and booked $0 for a generation the provider had made, leaving the position unmarked. Reachable in the ordinary way — a 400/401/403/413 on the retry after a broken socket.",
"package": "./internal/llm/",
"run": "TestADeliveredCutSurvivesATerminalStatusLaterInTheChain",
"battery": true,
"edits": [
{
"file": "internal/llm/httpllm.go",
"find": "\t\t\treturn zero, chainError(err, owedCut)",
"replace": "\t\t\treturn zero, err"
}
]
},
{
"id": "CUTCALL-the-delivery-count-is-not-carried",
"why": "a broken connection is worth one retry, so the provider is asked to generate TWICE while the store books ONE estimate — they share a key and spend is written only through a checkpoint. Under-counting is the ratified direction (D39.196 п.2а), but a SILENT under-count is what row 360 was opened about: the count is what makes the gap readable in the ledger row and the log.",
"package": "./internal/llm/",
"run": "TestABrokenConnectionAfterDeliveryIsRetriedOnceAndOnlyOnce",
"battery": true,
"edits": [
{
"file": "internal/llm/httpllm.go",
"find": "\t\t\t\tchainCuts = append(chainCuts, cut)\n",
"replace": ""
}
]
},
{
"id": "CUTMONEY-a-write-into-the-peers-window-is-taken-as-a-purchase",
"why": "`WroteRequest` says our bytes entered the peer's TCP window; it says NOTHING about the application behind it — a load balancer accepts while the backend never sees the request. Measured on a stopped run: 3 of 25 cancelled in-flight calls settled an estimate for a request no handler ever entered. On a non-streaming wire the only signal a provider's application acknowledged the request is a 2xx object reaching us, so money is drawn on that; delivery still drives RETRY. Charging a reader for a call nobody ran is the one direction the canon forbids (D39.196 п.2а).",
"package": "./internal/pipeline/",
"run": "TestAnAcceptedSocketThatNobodyReadCostsNothing",
"battery": true,
"edits": [
{
"file": "internal/llm/attemptcut.go",
"find": "\t\tBillable: answered && tr.afterHeaders(),",
"replace": "\t\tBillable: true,"
}
]
},
{
"id": "CUTMONEY-an-acknowledged-cut-stops-being-paid",
"why": "the other side of the same boundary: a call the provider DID acknowledge with a 2xx and then had cut short is exactly what row 360 was opened about, and booking zero for it takes the engine back to «No 2xx ever arrived: nothing was billed» — the comment that was false by construction on the shipping provider.",
"package": "./internal/pipeline/",
"run": "TestTheNineOutcomesOfACall",
"battery": true,
"edits": [
{
"file": "internal/llm/attemptcut.go",
"find": "\t\tBillable: answered && tr.afterHeaders(),",
"replace": "\t\tBillable: false,"
}
]
},
{
"id": "CUTKEEPALIVE-the-read-idle-bound-is-not-installed",
"why": "the h2 keepalive pair is the reason a long thinking-heavy call survives an idle proxy: with no DATA frame flowing, a PING is what keeps the socket open, and a dead connection then surfaces as a clean retryable transport error instead of a mid-generation RST that re-bills the call. Wiring the bound nowhere leaves the comment true and the transport bare.",
"package": "./internal/llm/",
"run": "TestTheKeepalivePairSitsOnTheTransportTheCloudClientBuilds",
"battery": true,
"edits": [
{
"file": "internal/llm/httpllm.go",
"find": "\th2.ReadIdleTimeout = h2ReadIdleTimeout\n",
"replace": ""
}
]
},
{
"id": "CUTBURN-the-paid-contract-ignores-the-burn",
"why": "with the burn ignored, ANY row at the key reads as paid — and the pre-gates then skip the budget check while the funnel, which cannot replay a burned row, goes and buys the work again outside every bound",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestABurnedRepairKeyDoesNotBuyARepairOutsideTheSubBudget|TestABurnedHopKeyDoesNotBuyAHopOutsideTheEscalationBudget|TestTheBankPaidProbeSeesThroughABurnedCheckpoint",
"edits": [
{
"file": "internal/pipeline/cutcall.go",
"find": "\t\tif !burnedByCut(cp) {\n",
"replace": "\t\tif cp != nil {\n"
}
]
},
{
"id": "CUTBURN-the-paid-contract-stops-at-the-first-key",
"why": "the funnel does not stop at a burned key — it walks to the next index at the same budget and buys there, so the answer to «already paid» often sits one index up. A probe that stops at the starting key hides a PAID, ANSWERED call, and the caller with no budget left discards work it already bought",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestAPaidHopBehindABurnedKeyStillReplaysFree|TestAPaidRepairBehindABurnedKeyStillReplaysFree|TestTheBankProbeFindsThePaidBatchBehindABurnedKey",
"edits": [
{
"file": "internal/pipeline/cutcall.go",
"find": "\t\tattempt++\n\t}\n}\n",
"replace": "\t\treturn false, nil\n\t}\n}\n"
}
]
},
{
"id": "CUTBURN-the-repair-pregate-asks-a-fixed-index",
"why": "the one definition of «already paid» exists so three pre-gates cannot drift apart; a site that goes back to asking a fixed attempt index answers a different question from the funnel and discards a paid repair",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestAPaidRepairBehindABurnedKeyStillReplaysFree",
"edits": [
{
"file": "internal/pipeline/repair.go",
"find": "\treturn r.paidAfterBurns(rst, model, snapID, ch, ordinal, maxTokens, msgs)\n",
"replace": "\tcp, err := r.Store.GetCheckpoint(RequestHash(r.attemptRequest(rst, model, snapID, ch, ordinal, maxTokens, msgs)))\n\treturn cp != nil && !burnedByCut(cp), err\n"
}
]
},
{
"id": "CUTBURN-the-escalation-pregate-asks-a-fixed-index",
"why": "same drift on the hop: a fixed index hides a paid, successful hop behind a burned key, and the exhausted escalation budget then throws that translation away on every resume",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestAPaidHopBehindABurnedKeyStillReplaysFree",
"edits": [
{
"file": "internal/pipeline/escalation.go",
"find": "\tmayHop, err := r.paidAfterBurns(st, st.ResolvedHop, snapID, ch, 0, hopMaxTokens, msgs)\n",
"replace": "\tfbCP, err := r.Store.GetCheckpoint(RequestHash(r.attemptRequest(st, st.ResolvedHop, snapID, ch, 0, hopMaxTokens, msgs)))\n\tmayHop := fbCP != nil && !burnedByCut(fbCP)\n"
}
]
},
{
"id": "CUTBURN-the-bank-pregate-asks-a-fixed-index",
"why": "same drift on the terminology batch, the site the other two were written from: a fixed index hides the batch the funnel already bought one index up, and the role sub-budget refuses to serve work it has paid for",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestTheBankProbeFindsThePaidBatchBehindABurnedKey",
"edits": [
{
"file": "internal/pipeline/terminologist.go",
"find": "\treturn r.paidAfterBurns(st, st.Model, snapID, ch, 0, maxTokens, msgs)\n",
"replace": "\tcp, err := r.Store.GetCheckpoint(RequestHash(r.attemptRequest(st, st.Model, snapID, ch, 0, maxTokens, msgs)))\n\treturn cp != nil && !burnedByCut(cp), err\n"
}
]
},
{
"id": "CUTKEEPALIVE-the-cloud-client-is-not-tuned-at-all",
"why": "the keepalive bounds are only worth their comment if the CLIENT THE ENGINE BUILDS carries them; a check written against a transport the test tuned itself passes even when the construction stopped tuning anything, which is exactly how the write bound's pin survived its own mutation",
"package": "./internal/llm/",
"run": "TestTheKeepalivePairSitsOnTheTransportTheCloudClientBuilds",
"battery": true,
"edits": [
{
"file": "internal/llm/httpllm.go",
"find": "\th2 := tuneHTTP2(base)\n",
"replace": "\tvar h2 *http2.Transport\n"
}
]
},
{
"id": "CUTBANK-admission-is-a-prefix-again",
"why": "an already-paid batch costs nothing and is admitted whatever the budget says, so a refused batch can sit in FRONT of batches that are free to serve; a prefix bound drops every paid batch behind the first refusal, buying nothing and losing a consolidated bank — while the loop's own comment promises they are admitted regardless",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestAnUnaffordableBatchDoesNotTakeThePaidBatchesBehindIt",
"edits": [
{
"file": "internal/pipeline/terminologist.go",
"find": "\t\t\tcontinue // this one cannot be afforded; the ones after it may still be free\n",
"replace": "\t\t\tbreak\n"
}
]
},
{
"id": "CUTCHAIN-the-exit-ranks-cuts-by-type-not-money",
"why": "the exit hands the caller ONE error; deciding which cut it carries by TYPE returns the ending cut whatever it cost, so a free cut nobody acknowledged erases the paid one behind it and the engine books $0",
"package": "./internal/llm/",
"battery": true,
"run": "TestAFreeCutLaterDoesNotMaskThePaidCutEarlier",
"edits": [
{
"file": "internal/llm/httpllm.go",
"find": "\t\tif errors.As(owed, &oc) && oc.Billable && !fc.Billable {\n",
"replace": "\t\tif errors.As(owed, &oc) && false {\n"
}
]
},
{
"id": "CUTCHAIN-the-owed-cut-is-joined-last",
"why": "errors.As hands back the FIRST match it meets walking the tree, so joining the free ending cut ahead of the paid owed one leaves the caller settling from the free one — the masking the branch exists to undo, restored by an argument order",
"package": "./internal/llm/",
"battery": true,
"run": "TestAFreeCutLaterDoesNotMaskThePaidCutEarlier|TestTheCancellationExitCarriesWhatTheChainOwes",
"edits": [
{
"file": "internal/llm/httpllm.go",
"find": "\t\t\treturn errors.Join(owed, final)\n",
"replace": "\t\t\treturn errors.Join(final, owed)\n"
}
]
},
{
"id": "CUTCHAIN-the-stop-exit-drops-what-is-owed",
"why": "a run stopped right after an attempt can have a paid cut behind it and an ordinary retryable in front; returning only «cancelled + the last error» leaves the runner nothing to settle and the position unmarked",
"package": "./internal/llm/",
"battery": true,
"run": "TestTheCancellationExitCarriesWhatTheChainOwes",
"edits": [
{
"file": "internal/llm/httpllm.go",
"find": "\t\t\treturn zero, chainError(cancelledDuring(ctx.Err(), err), owedCut)\n",
"replace": "\t\t\treturn zero, cancelledDuring(ctx.Err(), err)\n"
}
]
},
{
"id": "CUTCHAIN-a-plain-retryable-erases-the-paid-cut",
"why": "the chain can be billed for an attempt that is not the one whose error ends it; handing the caller only the terminal 503 books $0 for a generation the provider made",
"package": "./internal/llm/",
"battery": true,
"run": "TestAPaidCutSurvivesAPlainRetryableLaterInTheChain",
"edits": [
{
"file": "internal/llm/httpllm.go",
"find": "\treturn zero, chainError(fmt.Errorf(\"%s: exhausted %d attempts: %w\", name, profile.MaxAttempts, lastErr), owedCut)\n",
"replace": "\treturn zero, fmt.Errorf(\"%s: exhausted %d attempts: %w\", name, profile.MaxAttempts, lastErr)\n"
}
]
},
{
"id": "CUTROW-the-burn-money-is-overwritten",
"why": "the funnel walks past a burned key and buys the work again one index up; the row must carry BOTH the money that bought nothing and the money that bought the text. Overwriting the walk's total with the fresh call's cost puts chunk_status.cost_usd below SUM(checkpoints) for the position — money the book spent and the projection does not show",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestABurnedKeysMoneyReachesTheRow",
"edits": [
{
"file": "internal/pipeline/stagerun.go",
"find": "\tatt.cumCost, att.runCost = burnedCost+cost, cost\n",
"replace": "\tatt.cumCost, att.runCost = cost, cost\n"
}
]
},
{
"id": "CUTROW-the-hop-money-waits-for-the-verdict",
"why": "a hop that was CUT reports its cost and an error at the same time; adding the cost only on the success path leaves the deferred cancelled mark carrying the primary's money alone — measured at ledger 0.001176 against a row of 0.000120",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestAStoppedRunLeavesEveryRowMatchingItsOwnLedger",
"edits": [
{
"file": "internal/pipeline/stagerun.go",
"find": "\tcumCost += esc.fb.cumCost\n\trunCost += esc.fb.runCost\n\tanyFresh = anyFresh || esc.fb.freshCall\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif esc.attempted {\n\t\tescalated = true\n",
"replace": "\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif esc.attempted {\n\t\tcumCost += esc.fb.cumCost\n\t\trunCost += esc.fb.runCost\n\t\tanyFresh = anyFresh || esc.fb.freshCall\n\t\tescalated = true\n"
}
]
},
{
"id": "CUTROW-the-repair-money-waits-for-the-verdict",
"why": "same shape on the repair sub-step: a repair call the engine cut reports its cost together with the error, and the row is the only place that cost can land",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestAStoppedRunCarriesTheRepairsMoneyToTheRow",
"edits": [
{
"file": "internal/pipeline/repair.go",
"find": "\t\tres.CostUSD += att.runCost\n\t\tres.CumUSD += att.cumCost\n\t\tres.Fresh = res.Fresh || att.freshCall\n\t\tif err != nil {\n",
"replace": "\t\tif err != nil {\n"
}
]
},
{
"id": "CUTSTATE-a-stopped-position-decides-the-unit",
"why": "a cancelled row records a position the engine was stopped over: the work was never done and the resume re-does it and pays again. Reading it as a decided unit puts it in the extrapolation's denominator, so one stop makes the book look further along and cheaper than it is — and the re-bill consent threshold, min($0.50, 5% x projected), shrinks with it",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestAStoppedPositionIsNotADecidedUnit",
"edits": [
{
"file": "internal/pipeline/status.go",
"find": "\t\t\tif !resolvedForResume(&cs) {\n\t\t\t\tcontinue\n\t\t\t}\n",
"replace": ""
}
]
},
{
"id": "CUTROW-the-attempt-count-waits-for-the-verdict",
"why": "the deferred cancelled mark reports the attempt count beside money that was really paid; writing the count only after the error check leaves `attempts=0` on a position whose ledger says 0.001056 — a row that reports work nobody did, and the number an operator reads to tell «one call was cut» from «the position never started»",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestAStopOnAStagesFirstCallStillReportsAnAttempt",
"edits": [
{
"file": "internal/pipeline/attemptladder.go",
"find": "\t\tattempt = att.attempt\n\t\trun.attempts = attempt + 1\n\t\tif err != nil {\n\t\t\treturn run, err // infra failure; the caller's deferred mark reports what accumulated\n\t\t}\n",
"replace": "\t\tif err != nil {\n\t\t\treturn run, err // infra failure; the caller's deferred mark reports what accumulated\n\t\t}\n\t\tattempt = att.attempt\n\t\trun.attempts = attempt + 1\n"
}
]
},
{
"id": "CUTMONEY-response-bytes-alone-mean-payment",
"why": "a cut is billable only when the provider ACKNOWLEDGED the request with a reply; dropping the `answered` half makes response BYTES enough, so a broken proxy writing garbage — or any peer whose bytes arrive without a status line — books an estimate for a generation nobody made. This is the direction D39.196 п.2а forbids",
"package": "./internal/llm/",
"battery": true,
"run": "TestResponseBytesWithoutAReplyAreNotAPurchase",
"edits": [
{
"file": "internal/llm/attemptcut.go",
"find": "\t\tBillable: answered && tr.afterHeaders(),\n",
"replace": "\t\tBillable: tr.afterHeaders(),\n"
}
]
},
{
"id": "CUTSEV-cancelled-becomes-the-worst-problem",
"why": "the passport reports a chapter's WORST flag; `cancelled` is a state the next run erases, so ranking it above a durable finding hides the finding behind it. The exhaustiveness test proves only that every reason HAS a rank — the order itself was pinned by nothing",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestTheSeverityTableMeansWhatItsCommentsSay",
"edits": [
{
"file": "internal/pipeline/status.go",
"find": "\tFlagCancelled: 8,\n",
"replace": "\tFlagCancelled: 0,\n"
}
]
},
{
"id": "CUTSEV-the-paid-and-lost-pair-stops-ranking-together",
"why": "decode_error and attempt_timeout are the same thing to a reader — the chunk is lost and the money is spent — and the table says so in its own comment; splitting them makes the passport call one of the two worse than the others for no reason a reader could act on",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestTheSeverityTableMeansWhatItsCommentsSay",
"edits": [
{
"file": "internal/pipeline/status.go",
"find": "\tFlagAttemptTimeout: 4,\n",
"replace": "\tFlagAttemptTimeout: 5,\n"
}
]
},
{
"id": "CUTSEV-an-unknown-reason-outranks-a-diagnosis",
"why": "a reason this build has never heard of — an older schema's row, or junk — must not out-rank a diagnosis the engine actually made; putting it first makes an unparsed string the headline of a chapter that has real findings",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestTheSeverityTableMeansWhatItsCommentsSay",
"edits": [
{
"file": "internal/pipeline/status.go",
"find": "const severityUnknown = 9\n",
"replace": "const severityUnknown = 0\n"
}
]
},
{
"id": "CUTCFG-a-cap-below-the-floor-loads-quietly",
"why": "the derivation clamps UP to attempt_s and then DOWN to attempt_max_s, so a cap below the floor wins: every call to that provider gets less time than the file declares, attempt_s stops being the FLOOR its doccomment calls it, and nothing logs the difference — the calls simply come back cut",
"package": "./internal/config/",
"battery": true,
"run": "TestACapBelowTheFloorIsRefusedAtLoad",
"edits": [
{
"file": "internal/config/models.go",
"find": "\tif t.AttemptMaxS > 0 && t.AttemptMaxS < t.AttemptS {\n",
"replace": "\tif false {\n"
}
]
},
{
"id": "CUTCFG-the-timeout-check-is-not-wired-in",
"why": "the relation check exists and nothing calls it — the shape this pack has removed twice already, a guard living in the reader's head and not in the code",
"package": "./internal/config/",
"battery": true,
"run": "TestACapBelowTheFloorIsRefusedAtLoad",
"edits": [
{
"file": "internal/config/models.go",
"find": "\t\tvalidateTimeouts(bad, name, p.Timeouts)\n",
"replace": ""
}
]
},
{
"id": "CUTCFG-a-measured-speed-floor-is-deleted",
"why": "a speed floor is the p10 of that provider's own request_log over hundreds of rows; deleting the line returns the provider to the vendor default, which is within two percent of the measured value — nothing breaks, the measurement is simply gone, and the catalogue gate cannot see it because a deleted line and a never-declared field are the same zero",
"package": "./internal/config/",
"battery": true,
"run": "TestEveryDeclaredDeadlineKnobStaysDeclared",
"edits": [
{
"file": "configs/models.yaml",
"find": " timeouts: { attempt_s: 240, max_attempts: 3, backoff_cap_s: 60, tok_s_floor: 35 }\n",
"replace": " timeouts: { attempt_s: 240, max_attempts: 3, backoff_cap_s: 60 }\n"
}
]
},
{
"id": "CUTCOUNT-deliveries-counts-cuts-again",
"why": "the ledger line beside a cut says «the provider was asked N times; ONE estimate is booked for all of them» — the only place the gap between what was generated and what was billed is visible. Counting the CUTS instead of the DELIVERIES makes it understate a mixed chain: a 503 is an answer, so the peer read the request",
"package": "./internal/llm/",
"battery": true,
"run": "TestTheDeliveryCountCountsDeliveriesNotCuts",
"edits": [
{
"file": "internal/llm/httpllm.go",
"find": "\t\t\t\tcc.Deliveries = askedToGenerate\n",
"replace": "\t\t\t\tcc.Deliveries = deliveredCutSeen\n"
}
]
},
{
"id": "CUTLINE-the-tail-splits-across-rows",
"why": "errors.Join separates its members with a newline, and an engine error carrying both a cut and what ended the chain is such a join; without collapsing it one table row prints as two and breaks the alignment of everything under it",
"package": "./cmd/tmctl/",
"battery": true,
"run": "TestTheOperatorTailIsOneLineAndKeepsTheNoteThatMatters",
"edits": [
{
"file": "cmd/tmctl/render.go",
"find": "\ts = strings.Join(strings.Fields(s), \" \")\n",
"replace": ""
}
]
},
{
"id": "CUTLINE-the-note-goes-back-to-the-end",
"why": "the operator's column is bounded at 120 bytes and the transport error in front of the note is routinely longer, so a note appended at the end reaches nobody — and it is the only place the gap between what the provider generated and what the ledger booked is visible",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestTheAskedNTimesNoteReachesTheReader",
"edits": [
{
"file": "internal/pipeline/cutcall.go",
"find": "\treturn fmt.Sprintf(\"[the provider was asked %d times; %s] %s\", deliveries, booked, err.Error())\n",
"replace": "\treturn fmt.Sprintf(\"%s [the provider was asked %d times; %s]\", err.Error(), deliveries, booked)\n"
}
]
},
{
"id": "CUTLINE-the-note-claims-money-that-was-not-booked",
"why": "on a cut the provider never acknowledged, nothing is booked; a line saying «ONE estimate is booked for all of them» beside a $0 row is a sentence a reader has to disbelieve before they can use it, and this is the one line where the generated-versus-billed gap is visible",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestTheAskedNTimesNoteReachesTheReader",
"edits": [
{
"file": "internal/pipeline/cutcall.go",
"find": "\tif cost <= 0 {\n\t\tbooked = \"NOTHING is booked: the provider acknowledged none of them\"\n\t}\n",
"replace": ""
}
]
},
{
"id": "CUTCHAIN-the-stop-exit-drops-the-cancellation",
"why": "a stopped run must read as cancelled even when the attempt in flight failed of its own accord — the exit code (5, not 1) and the `stopped` the stream publishes both hang off it. The attempt's own error knows nothing about the context, so only this exit can carry it out; the wire fixture beside this one cannot see the loss, because there the attempt's error is itself a parent-cancelled cut and carries the cancellation on its own",
"package": "./internal/llm/",
"battery": true,
"run": "TestTheStopExitStillReadsAsCancelledWhenTheAttemptDidNot",
"edits": [
{
"file": "internal/llm/httpllm.go",
"find": "\t\t\treturn zero, chainError(cancelledDuring(ctx.Err(), err), owedCut)\n",
"replace": "\t\t\treturn zero, chainError(err, owedCut)\n"
}
]
},
{
"id": "CUTEXIT-a-stop-stops-mapping-to-five",
"why": "the three cut causes share one Go type and two of them are ordinary failures while the third is a person pressing stop; a mapping that stops telling them apart reports an operator's stop as an engine failure — and the number is what a runbook and the platform's stream both branch on",
"package": "./cmd/tmctl/",
"battery": true,
"run": "TestTheCutErrorTypeKeepsItsExitCode",
"edits": [
{
"file": "cmd/tmctl/main.go",
"find": "\tcase errors.Is(err, context.Canceled):\n\t\treturn 5\n",
"replace": ""
}
]
},
{
"id": "CUTDEADLINE-the-vendor-budget-moves",
"why": "every provider without its own measured floor derives its attempt deadline from this pair; a budget four times too generous makes the deadline four times too SHORT, so calls the provider is still generating get cut by us — and since this pack a self-cut the provider acknowledged is PAID FOR. Five of the eight catalogued providers run on this default, and the formula test cannot see the change: both of its sides read these same constants, so a corruption moves the expectation with the result",
"package": "./internal/llm/",
"battery": true,
"run": "TestTheVendorsPublishedPairIsWhatTheVendorPublishes",
"edits": [
{
"file": "internal/llm/attemptcut.go",
"find": "\tvendorHourlyTokenBudget = 128000\n",
"replace": "\tvendorHourlyTokenBudget = 512000\n"
}
]
},
{
"id": "CUTDEADLINE-the-vendor-window-moves",
"why": "the other half of the same pair: a window of a minute instead of an hour makes every derived deadline sixty times too long, and a run that looks hung is the only place it shows",
"package": "./internal/llm/",
"battery": true,
"run": "TestTheVendorsPublishedPairIsWhatTheVendorPublishes",
"edits": [
{
"file": "internal/llm/attemptcut.go",
"find": "\tvendorBudgetWindow = time.Hour\n",
"replace": "\tvendorBudgetWindow = time.Minute\n"
}
]
},
{
"id": "CUTMARK-the-stop-is-judged-by-the-first-cause",
"why": "the retry chain hands up the cut with the strongest MONEY claim, which is deliberately the earlier paid break when the later one is free — so a run a person stopped arrives carrying a cause that is not «stopped». A guard reading that first cause decides a stop is not a stop and returns in silence: the money is settled, the position gets no row, and the export shows a gap nobody can explain. §4.2 forbids a hole with no mark at any moment",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestAStopBehindAPaidBreakStillMarksThePosition",
"edits": [
{
"file": "internal/pipeline/cutcall.go",
"find": "\tif errors.Is(err, context.Canceled) && errors.As(err, &cut) {\n",
"replace": "\tif errors.As(err, &cut) && cut.Cause == llm.CutByParent {\n"
}
]
},
{
"id": "CUTCOUNT-only-the-newest-cut-is-stamped",
"why": "the count is a property of the CHAIN, and chainError deliberately hands up an EARLIER cut when that is the one that owes money — carrying a number frozen at its birth. A chain that cut once and was then answered two 503s delivered three times and would report one, under-stating the very gap the ledger line exists to show; the later deliveries are not cuts, so nothing in the error tree knows about them",
"package": "./internal/llm/",
"battery": true,
"run": "TestAnOlderCutCarriesTheChainsFinalDeliveryCount",
"edits": [
{
"file": "internal/llm/httpllm.go",
"find": "\t\tdefer func() {\n\t\t\tfor _, cc := range chainCuts {\n\t\t\t\tcc.Deliveries = askedToGenerate\n\t\t\t}\n\t\t}()\n",
"replace": ""
}
]
},
{
"id": "CUTCOUNT-an-undelivered-attempt-counts-as-asking",
"why": "an attempt whose request never left asked nobody and bought nothing; counting it says the engine bought a generation it did not, in the one line where the generated-versus-billed gap is published — and it is the direction D39.196 п.2а forbids",
"package": "./internal/llm/",
"battery": true,
"run": "TestAnUndeliveredAttemptIsNotCountedAsAsking",
"edits": [
{
"file": "internal/llm/httpllm.go",
"find": "\t\tif deliveredAttempt(resp, err) {\n\t\t\taskedToGenerate++\n\t\t}\n",
"replace": "\t\taskedToGenerate++\n"
}
]
},
{
"id": "CUTROW-the-estimate-is-not-disclosed",
"why": "the ratified estimate is charged on ONE condition — that the row says it is an estimate (D39.230 п.1). A silent $0.001056 is indistinguishable from a provider-reported cost, and the owner's word does not apply to a row that does not disclose. The table of nine outcomes cannot see this: its column reads the CHECKPOINT's usage, not request_log.estimated",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestTheCutRowPublishesItsEstimateAndItsGap",
"edits": [
{
"file": "internal/pipeline/cutcall.go",
"find": "\trl.Estimated, rl.EstTokens = cost > 0, r.estOutTokens(c.chunk.Text)\n",
"replace": "\trl.Estimated, rl.EstTokens = false, 0\n"
}
]
},
{
"id": "CUTROW-the-gap-is-not-published",
"why": "the provider was asked more than once and ONE estimate is booked for all of them; the row is the only place that under-count is published, and a silent gap is what row 360 was opened about",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestTheCutRowPublishesItsEstimateAndItsGap",
"edits": [
{
"file": "internal/pipeline/cutcall.go",
"find": "\t\trl.Err = cutErrLine(err, cut.Deliveries, cost)\n",
"replace": ""
}
]
},
{
"id": "STOP-cut-does-not-blind-an-earlier-verdict",
"why": "chunk_status is keyed (book, chapter, chunk, stage) and the stop mark is an UPSERT, so a run cut over a position that ALREADY held a verdict replaced it with flagged(cancelled) and an EMPTY final_hash — the only pointer to text a previous run bought and the export ships. Measured before the guard: ok / final_hash=770e5563 / $0.001820 became cancelled / \"\" / $0 while the checkpoint holding the prose stayed on disk, and the export shipped an empty chapter where it had shipped text (backlog row 375). Reachable through the re-pin route; the redrive route cannot reach it, because ResetChunkStages deletes the row and its checkpoints first",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestACutOverAPositionThatAlreadyShippedTextKeepsIt|TestACutOverAVirginPositionStillMarksIt",
"edits": [
{
"file": "internal/pipeline/cutcall.go",
"find": "\t} else if prev != nil && resolvedForResume(prev) {",
"replace": "\t} else if prev != nil && resolvedForResume(prev) && false {"
}
]
},
{
"id": "STOP-a-cut-by-a-person-is-not-a-failed-job",
"why": "a call a person cut was healthy when they cut it and the resume re-does it at the same budget, so `failed` — the read-model's word for a position that BROKE — sends whoever reads the jobs table hunting for a defect that is not there (backlog row 389; this is the site a stop actually travels through, and not one of the two the row names). The control pinned beside it keeps the word where it is true: a socket that dies on its own still records `failed`",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestAStoppedPositionIsNotRecordedAsFailed|TestABrokenSocketIsStillRecordedAsFailed",
"edits": [
{
"file": "internal/pipeline/stagerun.go",
"find": "\tif errors.Is(cause, context.Canceled) {\n\t\treturn\n\t}\n\tr.setJobStatus(ctx, jobID, \"failed\")",
"replace": "\tr.setJobStatus(ctx, jobID, \"failed\")"
}
]
},
{
"id": "STOP-the-spend-line-closure-cannot-reach-the-emitter",
"why": "the spend-line closure runs INSIDE the store's write transaction while the emitter's mutex is held ACROSS store writes, so taking that mutex from the closure closes a lock cycle — and it does not look like a deadlock from outside: the store's 10-second op timeout breaks it, and the symptom is `ensure job: context deadline exceeded` in tests that have nothing to do with the change (measured at thirteen, backlog row 387). The closure captures values so the receiver is not in scope at all; this plant puts it back",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestTheSpendLineClosureCannotReachTheEmitter",
"edits": [
{
"file": "internal/pipeline/events.go",
"find": "\t\t\tlog.Error(\"could not render the spend event; the settle proceeds without it (the counter is cumulative — the next one carries the total again)\", \"err\", err)",
"replace": "\t\t\tlog.Error(\"could not render the spend event; the settle proceeds without it (the counter is cumulative — the next one carries the total again)\", \"err\", err, \"run\", e.runID)"
}
]
},
{
"id": "C-consistency-count-becomes-presence",
"why": "the whole point of the book measure is that it COUNTS renderings instead of asking whether one is present; capping the count at 1 turns it back into the post-check's question and every partial-coverage verdict silently disappears",
"package": "./internal/membank/",
"edits": [
{
"file": "internal/membank/memconsistency.go",
"find": "\t\tn++\n\t\ti += matched",
"replace": "\t\tif n == 0 {\n\t\t\tn++\n\t\t}\n\t\ti += matched"
}
],
"battery": true
},
{
"id": "C-consistency-never-fired-folded-into-absent",
"why": "a row whose source key never fired is not a judgement about that term in either direction; dropping the guard lets a rendering that merely SURFACED elsewhere — a common-noun dst away from its term — count as the term shipped correctly, which is how a never-fired row joins the denominator of terms that were actually judged",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/bookconsistency.go",
"find": "\t\tif t.Fired == 0 || t.Blocked {",
"replace": "\t\tif t.Blocked {"
}
],
"battery": true
},
{
"id": "C-consistency-split-loses-its-chapters",
"why": "«term X went out two ways» is unusable without the chapters; dropping the chapter that did NOT get the bank's rendering leaves the finding with nothing an editor can open",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/bookconsistency.go",
"find": "\t\tWithoutForm: sortedChapters(a.relaxed.withoutForm),",
"replace": "\t\tWithoutForm: nil,"
}
],
"battery": true
},
{
"id": "C-anchored-tolerance-loses-its-anchor",
"why": "the one-rune stem tolerance is safe ONLY because a window must contain a word that matched outright; without that anchor a single-word rendering claims it alone and «Синь» is found inside «синий» — the exact collapse data/target-ru.txt refuses the bare soft sign over",
"package": "./internal/membank/",
"edits": [
{
"file": "internal/membank/memconsistency.go",
"find": "\tanchor := false\n",
"replace": "\tanchor := true\n"
}
],
"battery": true
},
{
"id": "C-strict-column-stops-mirroring-the-postcheck",
"why": "the strict column is printed as «what the post-check itself would say», and it only means that while a stored decl form is matched literally there; stemming it makes the two columns a comparison of the instrument with itself",
"package": "./internal/membank/",
"edits": [
{
"file": "internal/membank/memconsistency.go",
"find": "\t\tcase !form.base && rule == matchStrict:\n\t\t\treturn false",
"replace": "\t\tcase false:\n\t\t\treturn false"
}
],
"battery": true
},
{
"id": "C-edit-wave-selection-not-recorded",
"why": "row 417: what the EDITOR was shown is recorded nowhere else — the unit merge overwrites the leader's draft row — so dropping this write restores the exact blindness the paid run of 11.09 hit on four terms",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/waverun.go",
"find": "\t\tif err := r.recordWaveSelection(editSnapshot, store.WaveEdit, unit.Chapter, unit.FirstChunkIdx, editSel); err != nil {",
"replace": "\t\tif err := error(nil); err != nil {"
}
],
"battery": true
},
{
"id": "C-wave-record-accumulates-instead-of-converging",
"why": "the wave record is re-derived on every run, so the upsert must REPLACE what a position's wave showed; summing into it instead makes the column count how many times the book was resumed, and a resumed book would read as one whose bank injected twice as much",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/store/glossary.go",
"find": "\t\t\tn_exact_hits = excluded.n_exact_hits,",
"replace": "\t\t\tn_exact_hits = wave_selection.n_exact_hits + excluded.n_exact_hits,"
}
],
"battery": true
},
{
"id": "C-projection-drops-conventions",
"why": "bank.json publishing `spread` beside a variants list of a different length with nothing naming it is what made two sessions file a non-existent defect; the field is the fix and must not silently revert",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/bankexport.go",
"find": "Conventions: row.Conventions,",
"replace": "Conventions: row.Spread,"
}
],
"battery": true
},
{
"id": "C-unsigned-deviations-hidden-behind-a-zero",
"why": "the report listed a chunk only when its CONFIRMED count was non-zero, so a fully unsigned bank printed a zero and named none of its eighteen deviations; restoring that condition hides them again",
"package": "./cmd/tmctl/",
"edits": [
{
"file": "cmd/tmctl/render.go",
"find": "\t\t\tif rs.NPostcheckMiss == 0 && rs.PostcheckDetail == \"\" {",
"replace": "\t\t\tif rs.NPostcheckMiss == 0 {"
}
],
"battery": true
},
{
"id": "C-reachability-check-decides-instead-of-screening",
"why": "the per-row reachability screen exists only to skip rows that cannot be in a span; it must be LOOSER than the rule that counts, or it decides. Dropping its near-stem arm makes an exact stem hit the condition for being counted at all, and every rendering the relaxed rule was built to recover is rejected before the counter ever sees it",
"package": "./internal/membank/",
"battery": true,
"edits": [
{
"file": "internal/membank/memconsistency.go",
"find": "\t\tfor st := range out.present {\n\t\t\tif stemmer.NearStems(st, f.stems[0]) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}",
"replace": "\t\t_ = f"
}
]
},
{
"id": "C-seam-feeds-the-shipped-text-as-its-own-source",
"why": "the ONE wire between the measure and a run decides which text is the source; fed the shipped text instead, no bank key can fire, every row falls into «never fired» and the report prints a clean bill of health from an instrument that looked at nothing — this passed the whole battery until the seam was pinned",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/quality.go",
"find": "\t\tcons.add(k.chapter, unitSource[k], normText)",
"replace": "\t\tcons.add(k.chapter, normText, normText)"
}
],
"battery": true
},
{
"id": "C-split-loses-its-within-chapter-half",
"why": "a term rendered two ways INSIDE one chapter is a reader meeting both forms on one page — the worse case; dropping the within-chapter arm leaves only the cross-chapter one and such a term reads as covered",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/bookconsistency.go",
"find": "\tcase len(v.withoutForm) > 0 || len(v.splitIn) > 0:",
"replace": "\tcase len(v.withoutForm) > 0:"
}
],
"battery": true
},
{
"id": "C-eaten-but-covered-row-inflates-the-control-line",
"why": "a row eaten by a longer key has no firings of its own, so without this it falls out of every bucket and subtraction files it under «key never fired in the source» — padding the one line that separates «the engine shipped the wrong thing» from «this term is not in the book», on any book with aliases",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/bookconsistency.go",
"find": "\t\tif a.firedUnbl == 0 && len(a.eatenCovered) > 0 && len(a.eatenIn) == 0 {",
"replace": "\t\tif false {"
}
],
"battery": true
},
{
"id": "C-one-clean-chapter-erases-an-eaten-case-elsewhere",
"why": "the eaten class is per-CHAPTER: a term rendered perfectly in one chapter and eaten with its canon lost in another must still report the second; gating it on the term having no firings at all lets one clean firing erase the finding this surface exists to publish",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/bookconsistency.go",
"find": "\t\tif len(a.eatenIn) > 0 {\n\t\t\tout.SuppressedSilent++",
"replace": "\t\tif len(a.eatenIn) > 0 && a.fired == 0 {\n\t\t\tout.SuppressedSilent++"
}
],
"battery": true
},
{
"id": "C-stem-tolerance-fires-without-a-stem-registry",
"why": "the tolerance is a relation on STEMS; on a target with no decl_suffix registry Stem is the identity, so ungating it turns the column into fuzzy prefix matching over raw words for every pair this repo does not yet have — the project's default review question answered wrongly and silently",
"package": "./internal/membank/",
"edits": [
{
"file": "internal/lang/stemmer.go",
"find": "\tif !s.Enabled() {\n\t\treturn false // no registry ⇒ no stems ⇒ nothing to be one rune away from\n\t}",
"replace": "\tif false {\n\t\treturn false\n\t}"
}
],
"battery": true
},
{
"id": "C-verdict-leaves-the-anchored-column",
"why": "the verdict rests on the ANCHORED column because no MACHINE-produced bank in this tree carries a single decl form (0 in every mined export, against 35-42 of ~50 in every hand seed) — so on the product's real path the stemmer has nothing to stem and the one-rune tolerance is the only thing that reaches an inflected rendering; taking the verdict from the safe column there reports drift that is not happening",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/bookconsistency.go",
"find": "\t\tv := a.relaxed.verdict()",
"replace": "\t\tv := a.primary.verdict()"
}
],
"battery": true
},
{
"id": "C-near-stem-admits-a-substitution-not-a-strip",
"why": "Stem truncates, so two stems of one word differ only in how much was stripped and the shorter must be a PREFIX of the longer; admitting a same-length pair that differs in its final rune is how «глав»/«глаз» got through — «глава рода Гуюэ» satisfied by «глаза рода Гуюэ», a false SILENCE on the column the verdict now rests on",
"package": "./internal/membank/",
"battery": true,
"edits": [
{
"file": "internal/lang/stemmer.go",
"find": "\tif len(y)-len(x) != 1 || len(x) < minStemRunes {\n\t\treturn false\n\t}\n\tfor i := range x {\n\t\tif x[i] != y[i] {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true",
"replace": "\tn := 0\n\tfor n < len(x) && n < len(y) && x[n] == y[n] {\n\t\tn++\n\t}\n\treturn n >= minStemRunes && len(x)-n <= 1 && len(y)-n <= 1"
}
]
},
{
"id": "Z-empty-remedy-fires-for-length-too",
"why": "the split is the whole pack: a truncated ANSWER must keep buying room (D2.3) and only an EMPTY one buys less thinking; dropping the flag test makes one remedy answer both failures again",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/attemptladder.go",
"find": "\t\t\tif cls.Reason == FlagEmpty && r.Pipeline.Retries.LowerEffortOnEmpty {",
"replace": "\t\t\tif r.Pipeline.Retries.LowerEffortOnEmpty {"
}
],
"battery": true
},
{
"id": "Z-lower-effort-ignores-the-knob",
"why": "the knob is what keeps every shipping config byte-identical; ignoring it lands the remedy switched ON for books nobody measured it for",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/attemptladder.go",
"find": "\t\t\tif cls.Reason == FlagEmpty && r.Pipeline.Retries.LowerEffortOnEmpty {",
"replace": "\t\t\tif cls.Reason == FlagEmpty {"
}
],
"battery": true
},
{
"id": "Z-lowered-attempt-doubles-the-budget-too",
"why": "the point of the remedy is LESS thinking at the SAME budget; doubling as well re-introduces the spend D39.86 falsified and makes the cheaper arm cost the same",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/attemptladder.go",
"find": "\t\t\t\t\teffort = lower\n\t\t\t\t\trun.regens++",
"replace": "\t\t\t\t\teffort = lower\n\t\t\t\t\trun.doublings++\n\t\t\t\t\trun.regens++"
}
],
"battery": true
},
{
"id": "Z-reduction-does-not-spend-the-retry-budget",
"why": "regens is the budget `regenerate_before_escalate` names; if a reduction does not spend it, a unit walks the whole ladder AND then doubles, buying calls the config never granted",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/attemptladder.go",
"find": "\t\t\t\t\teffort = lower\n\t\t\t\t\trun.regens++",
"replace": "\t\t\t\t\teffort = lower"
}
],
"battery": true
},
{
"id": "Z-ladder-steps-below-the-lowest-emitting-level",
"why": "below `low` lies switching a provider's thinking OFF, which arms the echo mine on dense CJK (D19.1 п.2) — a guardrailed decision a retry policy must never take on its own",
"package": "./internal/config/",
"edits": [
{
"file": "internal/config/models.go",
"find": "\tcase \"medium\":\n\t\tnext = \"low\"",
"replace": "\tcase \"medium\":\n\t\tnext = \"low\"\n\tcase \"low\":\n\t\tnext = \"off\""
}
],
"battery": true
},
{
"id": "Z-ladder-offered-where-the-level-never-reaches-the-wire",
"why": "under extra_body_disable the body carries thinking on/off and no level, so a step there is a byte-identical request at the same price — a second copy of the call that just failed",
"package": "./internal/config/",
"edits": [
{
"file": "internal/config/models.go",
"find": "\tif control != llm.ReasoningNone && control != llm.ReasoningEffortField {\n\t\treturn \"\", false\n\t}",
"replace": "\tif control == llm.ReasoningMandatory {\n\t\treturn \"\", false\n\t}"
}
],
"battery": true
},
{
"id": "Z-unset-effort-steps-down-where-a-floor-was-already-chosen",
"why": "with an off-switch available, `off` is a floor the capability itself chose; stepping from it claims a reduction that is not one and buys a call for nothing",
"package": "./internal/config/",
"edits": [
{
"file": "internal/config/models.go",
"find": "\t\tif control != llm.ReasoningNone {\n\t\t\treturn \"\", false\n\t\t}",
"replace": "\t\tif false {\n\t\t\treturn \"\", false\n\t\t}"
}
],
"battery": true
},
{
"id": "Z-subset-thinking-count-dropped-again",
"why": "the provider reports it on every reply and the adapter used to throw it away; that is why the one column able to say «thinking ate the budget» read 0 for the life of the project",
"package": "./internal/llm/",
"edits": [
{
"file": "internal/llm/provider_openai.go",
"find": "\t\tif rt, reported := resp.Usage.reasoningDetail(); reported {\n\t\t\tusage.ReasoningInCompletion = &rt\n\t\t}",
"replace": "\t\t_ = resp.Usage"
}
],
"battery": true
},
{
"id": "Z-subset-thinking-billed-a-second-time",
"why": "ledger.CostUSD prices CompletionTokens + ReasoningTokens; on a subset provider the thinking is already inside the completion, and surfacing it as money inflates every DeepSeek bill by the measured ~60%",
"package": "./internal/llm/",
"edits": [
{
"file": "internal/llm/provider_openai.go",
"find": "\t\t\tusage.ReasoningInCompletion = &rt",
"replace": "\t\t\tusage.ReasoningTokens = rt"
}
],
"battery": true
},
{
"id": "Z-absent-thinking-field-reads-as-a-measured-zero",
"why": "a provider that reported nothing and a call that did not think are different answers; spelling both 0 is the exact blindness the column was added to remove",
"package": "./internal/llm/",
"edits": [
{
"file": "internal/llm/httpllm.go",
"find": "\tif u.CompletionTokensDetails.ReasoningTokens == nil {\n\t\treturn 0, false\n\t}",
"replace": "\tif u.CompletionTokensDetails.ReasoningTokens == nil {\n\t\treturn 0, true\n\t}"
}
],
"battery": true
},
{
"id": "Z-telemetry-writes-a-zero-instead-of-no-answer",
"why": "the column is nullable ON PURPOSE; writing 0 for a row nobody asked makes every book already on disk claim its calls did not think",
"package": "./internal/store/",
"edits": [
{
"file": "internal/store/requestlog.go",
"find": "\t\trl.CompletionTokens, rl.ReasoningTokens, rl.ReasoningInCompletion,",
"replace": "\t\trl.CompletionTokens, rl.ReasoningTokens, 0,"
}
],
"battery": true
},
{
"id": "Z-price-substitution-reports-itself-as-the-answerer",
"why": "the basis is the only thing that separates «billed by the model that answered» from «billed by one that did not»; collapsing it silences the warning and the report legend at once",
"package": "./internal/ledger/",
"edits": [
{
"file": "internal/ledger/pricing.go",
"find": "\t\treturn mp, PriceByRequested",
"replace": "\t\treturn mp, PriceByAnswerer"
}
],
"battery": true
},
{
"id": "Z-thrown-away-total-counts-replayed-rows",
"why": "a replayed row bought nothing this run; counting it inflates both the waste and its share, and the line's whole value is that the share is arguable",
"package": "./cmd/tmctl/",
"edits": [
{
"file": "cmd/tmctl/render.go",
"find": "\tcase row.TMHit != 0, row.OK != 0:\n\t\treturn false",
"replace": "\tcase row.OK != 0:\n\t\treturn false"
}
],
"battery": true
},
{
"id": "Z-thrown-away-share-counts-replayed-rows",
"why": "the share is the argument, and a replayed row's money was already booked by the row it replays; counting it in the denominator makes a quarter of a book's spend read as a seventh",
"package": "./cmd/tmctl/",
"edits": [
{
"file": "cmd/tmctl/render.go",
"find": "\t\t\tif row.TMHit == 0 {\n\t\t\t\tpaid += row.CostUSD\n\t\t\t}",
"replace": "\t\t\tif true {\n\t\t\t\tpaid += row.CostUSD\n\t\t\t}"
}
],
"battery": true
},
{
"id": "Z-thinking-column-prints-zero-for-no-answer",
"why": "a provider that reported nothing and a call that did not think are different answers; a cell that spells both 0 re-creates in the report the exact blindness the column was added to remove",
"package": "./cmd/tmctl/",
"edits": [
{
"file": "cmd/tmctl/render.go",
"find": "\tif n == nil {\n\t\treturn \"?\"\n\t}",
"replace": "\tif n == nil {\n\t\treturn \"0\"\n\t}"
}
],
"battery": true
},
{
"id": "Z-thinking-column-collapses-a-measured-zero",
"why": "a provider that reported 0 has ANSWERED the question; spelling that answer the same way as silence is the exact blindness the column was added to remove, in the one place a reader meets it",
"package": "./cmd/tmctl/",
"edits": [
{
"file": "cmd/tmctl/render.go",
"find": "\tif n == nil {\n\t\treturn \"?\"\n\t}",
"replace": "\tif n == nil || *n == 0 {\n\t\treturn \"?\"\n\t}"
}
],
"battery": true
},
{
"id": "Z-thinking-column-defaults-old-rows-to-zero",
"why": "a DEFAULT on the new column makes every row of every book already on disk claim its call did not think — a claim nobody measured, about the very runs this column exists to explain",
"package": "./internal/store/",
"edits": [
{
"file": "internal/store/migrate.go",
"find": "\tALTER TABLE request_log ADD COLUMN reasoning_in_completion INTEGER;",
"replace": "\tALTER TABLE request_log ADD COLUMN reasoning_in_completion INTEGER NOT NULL DEFAULT 0;"
}
],
"battery": true
},
{
"id": "Z-waste-line-counts-calls-that-cost-nothing",
"why": "a transport failure that never reached a billed response writes ok=0 with cost_usd=0; counting it inflates the CALL count of a line whose whole subject is money, and prints a bucket the money side cannot explain",
"package": "./cmd/tmctl/",
"edits": [
{
"file": "cmd/tmctl/render.go",
"find": "\tcase row.CostUSD <= 0:\n\t\treturn false",
"replace": "\tcase false:\n\t\treturn false"
}
],
"battery": true
},
{
"id": "Z-waste-line-counts-answers-that-shipped",
"why": "a cosmetic sanitizer strip is not an ok verdict and its cleaned text IS exported; counting it says the reader paid for nothing when the reader got the text",
"package": "./cmd/tmctl/",
"edits": [
{
"file": "cmd/tmctl/render.go",
"find": "\tcase row.Degraded == string(pipeline.FlagSanitizerStripped):\n\t\treturn false",
"replace": "\tcase false:\n\t\treturn false"
}
],
"battery": true
},
{
"id": "Z-ladder-steps-to-a-word-the-loader-never-validated",
"why": "a step outside the neutral vocabulary reaches the wire from the retry path without ever passing the gate that word list exists to be; the vendor's own levels are unreachable from our config for exactly that reason",
"package": "./internal/config/",
"edits": [
{
"file": "internal/config/models.go",
"find": "\tcase \"high\":\n\t\tnext = \"medium\"",
"replace": "\tcase \"high\":\n\t\tnext = \"minimal\""
}
],
"battery": true
},
{
"id": "Z-running-report-hides-the-thinking-share",
"why": "the post-mortem reader learns after the money is spent; the operator watching a paid run is the one who can still act, and the stage line is where they look",
"package": "./cmd/tmctl/",
"edits": [
{
"file": "cmd/tmctl/render.go",
"find": "\t\t\tfmt.Fprintf(w, \" %-8s %-22s %-8s %-8s%s $%.6f (cum $%.6f) in=%d (cached=%d) out=%d+%d think=%s att=%d %dms finish=%s\\n\",\n\t\t\t\tst.Stage, st.Model, how, st.Disposition, flagSuffix(st.FlagReason),\n\t\t\t\tst.CostUSD, st.CumCostUSD,\n\t\t\t\tst.Usage.PromptTokens, st.Usage.CachedTokens,\n\t\t\t\tst.Usage.CompletionTokens, st.Usage.ReasoningTokens, thinkCell(st.Usage.ReasoningInCompletion),\n\t\t\t\tst.Attempts, st.LatencyMS, st.FinishReason)",
"replace": "\t\t\tfmt.Fprintf(w, \" %-8s %-22s %-8s %-8s%s $%.6f (cum $%.6f) in=%d (cached=%d) out=%d+%d att=%d %dms finish=%s\\n\",\n\t\t\t\tst.Stage, st.Model, how, st.Disposition, flagSuffix(st.FlagReason),\n\t\t\t\tst.CostUSD, st.CumCostUSD,\n\t\t\t\tst.Usage.PromptTokens, st.Usage.CachedTokens,\n\t\t\t\tst.Usage.CompletionTokens, st.Usage.ReasoningTokens,\n\t\t\t\tst.Attempts, st.LatencyMS, st.FinishReason)"
}
],
"battery": true
},
{
"id": "Z-shipping-config-can-turn-the-remedy-on-silently",
"why": "the gate stands over DATA, so the planting has to be data: one word in a shipping YAML turns an unmeasured spend on, and before this gate nothing in the tree went red for it — the pack's own report calls the landing INERT, which without a gate is a promise, not a property",
"package": "./internal/config/",
"battery": true,
"edits": [
{
"file": "configs/pipeline-c1.yaml",
"find": " regenerate_echo_before_escalate: 1",
"replace": " regenerate_echo_before_escalate: 1\n lower_effort_on_empty: true"
}
]
},
{
"id": "Z-lowering-warn-loses-its-levels",
"battery": true,
"why": "the asked-for effort lives in the request hash and nowhere else, so this WARN is the only place a run ever records WHICH level an attempt was bought at; the operator-message catalogue compares source literals and stays green when the fields go",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/attemptladder.go",
"find": "\t\t\t\t\t\t\"effort\", effort, \"next_effort\", lower, \"max_tokens\", maxTokens)",
"replace": "\t\t\t\t\t\t\"max_tokens\", maxTokens)"
}
]
},
{
"id": "Z-price-substitution-warn-silenced",
"battery": true,
"why": "the price basis is computed at settle and stored nowhere; silence it and the pack's claim «the live path warns» rests on a line that never sounds, with the catalogue gate still green",
"package": "./internal/pipeline/",
"edits": [
{
"file": "internal/pipeline/stagerun.go",
"find": "\tif basis.Substituted() {",
"replace": "\tif false && basis.Substituted() {"
}
]
},
{
"id": "Z-unnamed-bucket-prints-empty",
"battery": true,
"why": "a money line that counts a bucket and cannot name it gives the reader a number they have no way to ask about — the defect the first review found in this very line",
"package": "./cmd/tmctl/",
"edits": [
{
"file": "cmd/tmctl/render.go",
"find": "\t\t\treason = \"unnamed\"",
"replace": "\t\t\treason = \"\""
}
]
},
{
"id": "Z-thinking-share-marshals-on-every-call",
"battery": true,
"why": "Usage is serialised into every checkpoint; without omitempty a provider that reports nothing writes different bytes than before the field existed, breaking the byte-identity discipline its own comment claims",
"package": "./internal/llm/",
"edits": [
{
"file": "internal/llm/llm.go",
"find": "\tReasoningInCompletion *int `json:\",omitempty\"`",
"replace": "\tReasoningInCompletion *int"
}
]
},
{
"id": "Z-ladder-answers-for-a-model-it-never-saw",
"battery": true,
"why": "an unlisted slug resolves to the OpenAI-compat baseline, so the ladder would answer «step to low» for a model with no declared wire — and for the empty string, which is what a caller reaching for the wrong field hands over",
"package": "./internal/config/",
"edits": [
{
"file": "internal/config/models.go",
"find": "\tif _, known := m.Models[modelName]; !known {\n\t\treturn \"\", false\n\t}",
"replace": "\tif false {\n\t\treturn \"\", false\n\t}"
}
]
},
{
"id": "RETRYSTOP-a-refused-re-attack-leaves-no-mark",
"battery": true,
"why": "a ceiling that refuses the RE-ATTACK of an already-paid attempt used to leave the position with no chunk_status row at all, so the unit read `pending` — indistinguishable from one nobody had started — while its first attempt was paid for and on disk. Measured on this fixture before the branch existed: committed=$0.003640 with ONE row for the two units the run had touched (backlog row 291)",
"package": "./internal/pipeline/",
"run": "TestTheRefusedRetryLeavesTheUnitAMarkAndNotAnEmptyPosition",
"edits": [
{
"file": "internal/pipeline/cutcall.go",
"find": "\tif p.paidAttempts > 0 && errors.Is(err, errReserveCeiling) {\n\t\treturn stopMark{\n\t\t\treason: FlagRetryUnaffordable,\n\t\t\tdetail: ceilingStopDetail(p, err),\n\t\t\t// ⚠ ONE FEWER THAN `attempts`, AND THE BRANCH ABOVE DOES NOT SUBTRACT — the two stops differ\n\t\t\t// in exactly this. `attempts` is the index the loop is ON (attemptsMade = attempt + 1, set\n\t\t\t// before the error check), so for a cancelled call it counts the call that DID go out, while\n\t\t\t// here the index it counts bought nothing at all. What is left is every index this position\n\t\t\t// really consumed, burned keys included — the same thing the ok path's count includes, so a\n\t\t\t// row cut from `paidAttempts` instead would silently drop a burn this position paid for.\n\t\t\t//\n\t\t\t// ⚠ IT CANNOT GO NEGATIVE, and the reason is not local: `paidAttempts > 0` above means the loop\n\t\t\t// classified something, and the loop sets attemptsMade = attempt + 1 ≥ 1 before any error is\n\t\t\t// read (stagerun.go). A future shape that marked a position without that guarantee would have\n\t\t\t// to bring the floor with it.\n\t\t\tattempts: p.attempts - 1,\n\t\t\t// ⚠ BOTH MARKS CARRY IT, and the cancelled one did not until this pack: a position stopped over\n\t\t\t// its SECOND attempt has a first failure too, and the same blinding applied to it. One rule for\n\t\t\t// the two stop marks rather than a rule and an exception.\n\t\t\tfirstFlag: recoveredFirstFlag(p.firstFlagReason, FlagRetryUnaffordable),\n\t\t}, true\n\t}\n",
"replace": ""
}
]
},
{
"id": "RETRYSTOP-the-mark-is-keyed-on-the-attempt-count",
"battery": true,
"why": "the attempt COUNT includes the index the reservation was refused at (attemptsMade = attempt + 1, set before the error check) and the indices walked over burned keys — so keyed on it, the mark is written for a position that was never translated once, and a flagged row is an answer a resume serves: the unit goes terminal holding burned money and no text",
"package": "./internal/pipeline/",
"run": "TestACeilingRefusingAFreshAttemptLeavesNoRow|TestStopMarkForAsksWhetherAnythingWasEverBought",
"edits": [
{
"file": "internal/pipeline/cutcall.go",
"find": "\tif p.paidAttempts > 0 && errors.Is(err, errReserveCeiling) {",
"replace": "\tif p.attempts > 0 && errors.Is(err, errReserveCeiling) {"
}
]
},
{
"id": "RETRYSTOP-the-mark-is-keyed-on-the-money",
"battery": true,
"why": "«money was spent on this position» is the OTHER plausible reading of the predicate and it is wrong in one case that really happens: a stopped run leaves a BURNED key — money with no result — and nothing classified, so a mark keyed on cost invents a half-done unit out of a position whose only purchase produced nothing",
"package": "./internal/pipeline/",
"run": "TestStopMarkForAsksWhetherAnythingWasEverBought",
"edits": [
{
"file": "internal/pipeline/cutcall.go",
"find": "\tif p.paidAttempts > 0 && errors.Is(err, errReserveCeiling) {",
"replace": "\tif p.cumCostUSD > 0 && errors.Is(err, errReserveCeiling) {"
}
]
},
{
"id": "RETRYSTOP-the-mark-counts-the-refused-reservation",
"battery": true,
"why": "a refused reservation is not an attempt that happened: counting it puts a call that was never dialled into the row a person reads, and the row then disagrees with the checkpoints the money is summed from",
"package": "./internal/pipeline/",
"run": "TestTheRefusedRetryLeavesTheUnitAMarkAndNotAnEmptyPosition|TestStopMarkForAsksWhetherAnythingWasEverBought",
"edits": [
{
"file": "internal/pipeline/cutcall.go",
"find": "\t\t\tattempts: p.attempts - 1,",
"replace": "\t\t\tattempts: p.attempts,"
}
]
},
{
"id": "RETRYSTOP-the-money-mark-is-served-as-an-answer",
"battery": true,
"why": "`retry_unaffordable` is the one flag money CURES (D4: raise the ceiling, resume, the reader gets a good translation). Read as a resolved verdict, the resume serves it for $0 and never re-attacks — the unit is permanently degraded and the only way back is a redrive, which DELETES the checkpoints and re-buys attempt 0 as well",
"package": "./internal/pipeline/",
"run": "TestToppingUpByTheStatedShortfallFinishesTheUnit",
"edits": [
{
"file": "internal/pipeline/disposition.go",
"find": "\tcase FlagCancelled, FlagRetryUnaffordable:\n\t\treturn false",
"replace": "\tcase FlagCancelled:\n\t\treturn false"
}
]
},
{
"id": "RETRYSTOP-the-mark-borrows-the-cancelled-reason",
"battery": true,
"why": "nobody stopped that run by hand. A flag lying about its cause is forbidden in its own right (D39.93 п.2): `cancelled` sends an operator looking for a stop button that was never pressed, and hides the one remedy that works — topping up",
"package": "./internal/pipeline/",
"run": "TestTheRefusedRetryLeavesTheUnitAMarkAndNotAnEmptyPosition",
"edits": [
{
"file": "internal/pipeline/cutcall.go",
"find": "\t\t\treason: FlagRetryUnaffordable,",
"replace": "\t\t\treason: FlagCancelled,"
}
]
},
{
"id": "RETRYSTOP-the-detail-forgets-what-the-paid-attempt-answered",
"battery": true,
"why": "the reason column now says why the re-attack never happened, so what the PAID attempt came back as is on the row or nowhere: the WARN line carrying it dies with the process, and the next morning nobody can tell a truncation that needed a bigger budget from an empty reply that needed less thinking",
"package": "./internal/pipeline/",
"run": "TestTheRefusedRetryLeavesTheUnitAMarkAndNotAnEmptyPosition|TestStopMarkForAsksWhetherAnythingWasEverBought",
"edits": [
{
"file": "internal/pipeline/cutcall.go",
"find": "\treturn fmt.Sprintf(\"attempt %d was paid for and came back %s; %s refused to reserve the re-attack%s — raise the ceiling and the resume finishes this unit\",\n\t\tp.inHand.attempt, p.inHand.cls.Reason, ceiling, missing)",
"replace": "\treturn fmt.Sprintf(\"attempt %d was paid for; %s refused to reserve the re-attack%s — raise the ceiling and the resume finishes this unit\",\n\t\tp.inHand.attempt, ceiling, missing)"
}
]
},
{
"id": "RETRYSTOP-a-stop-that-states-no-shortfall-prints-a-zero",
"battery": true,
"why": "a day-scope refusal states no shortfall (the day ceiling sums every book in the store, so this book's committed figure is not the day's). Printed as «short by 0 micro-USD» it reads as «you are not short of anything», which is the opposite of what happened",
"package": "./internal/pipeline/",
"run": "TestStopMarkForAsksWhetherAnythingWasEverBought",
"edits": [
{
"file": "internal/pipeline/cutcall.go",
"find": "\tif shortfall > 0 {\n\t\tmissing = fmt.Sprintf(\", short by %d micro-USD\", shortfall)",
"replace": "\tif shortfall >= 0 {\n\t\tmissing = fmt.Sprintf(\", short by %d micro-USD\", shortfall)"
}
]
},
{
"id": "RETRYSTOP-the-money-mark-ranks-with-the-budget-symptom",
"battery": true,
"why": "`retry_unaffordable` IS a length/empty failure plus the fact that the remedy could not be bought. Ranked with them, a chapter whose unit died for lack of money reports «truncated» as its worst problem and sends a person to fix a budget formula instead of topping up",
"package": "./internal/pipeline/",
"run": "TestTheSeverityTableMeansWhatItsCommentsSay",
"edits": [
{
"file": "internal/pipeline/status.go",
"find": "\tFlagRetryUnaffordable: 4,",
"replace": "\tFlagRetryUnaffordable: 6,"
}
]
},
{
"id": "ECHOREC-a-superseded-echo-counts-as-recovered",
"battery": true,
"why": "«no longer the verdict» is not «recovered». A re-roll that came back with a DIFFERENT failure leaves first_flag_reason=cjk_artifact on a FLAGGED row that ships no text, and counted as a recovery the report claims we fixed an echo nobody fixed. Live rather than latent: regenerate_echo_before_escalate: 1 stands in all four shipping pipelines",
"package": "./internal/pipeline/",
"run": "TestASupersededEchoIsNotCountedAsRecovered",
"edits": [
{
"file": "internal/pipeline/quality.go",
"find": "\t\t\t\tdraftEcho++\n\t\t\t\tif shippedText(cs) {\n\t\t\t\t\tdraftEchoRecovered++\n\t\t\t\t}",
"replace": "\t\t\t\tdraftEcho++\n\t\t\t\tdraftEchoRecovered++"
}
]
},
{
"id": "STOPACC-the-account-names-one-cause-instead-of-asking-the-rule",
"battery": true,
"why": "the stopped-run account splits a book's rows into «answers the next run serves for $0» and «positions it re-does». Spelled as a reason NAME it is a second copy of pipeline.ResolvedForResume, and the day a second non-resolved reason existed (a retry whose money ran out) the copy counted a position the next run re-attacks among the ones WITH a verdict — an operator reading that is told the rest is served for $0 and that the book is further along than it is",
"package": "./cmd/tmctl/",
"run": "TestTheStoppedAccountCountsEveryPositionTheNextRunRedoes",
"edits": [
{
"file": "cmd/tmctl/render.go",
"find": "\t\tif !pipeline.ResolvedForResume(&cs[i]) {",
"replace": "\t\tif pipeline.FlagReason(cs[i].FlagReason) == pipeline.FlagCancelled {"
}
]
},
{
"id": "READERHOLE-the-stop-mark-tells-the-reader-to-wait-for-a-human",
"battery": true,
"why": "the withheld sentence tells the reader the fragment «требует проверки человеком» (langpacks/<target>/reader.txt). For a stop MARK — a call a person cut, a re-attack a ceiling refused — that is false: nothing is wrong with the fragment, it was paid for and not finished, and the next run does it. A reader acting on that sentence waits for a human who cannot help, and the operator's refusal text says the same thing about a unit that needs only money",
"package": "./internal/pipeline/",
"run": "TestTheReadersFileDoesNotSendThemToWaitForAHumanWhoCannotHelp",
"edits": [
{
"file": "internal/pipeline/bookbuild.go",
"find": "\t\t\tif FlagReason(ce.FlagReason).AnswersForResume() || ce.DroppedMembers > 0 {\n\t\t\t\tmark(words.HoleWithheld)\n\t\t\t} else {\n\t\t\t\tmark(words.HolePending)\n\t\t\t}\n",
"replace": "\t\t\tmark(words.HoleWithheld)\n"
}
]
},
{
"id": "READERHOLE-every-withheld-unit-becomes-merely-untranslated",
"battery": true,
"why": "the other direction of the same branch, and the one a careless fix produces: saying «ещё не переведён» about a REFUSAL or a contaminated output hides the only holes a human can actually do something about. The reader is then told to wait for a run that will never fix it",
"package": "./internal/pipeline/",
"run": "TestTheReadersFileDoesNotSendThemToWaitForAHumanWhoCannotHelp",
"edits": [
{
"file": "internal/pipeline/bookbuild.go",
"find": "\t\t\tif FlagReason(ce.FlagReason).AnswersForResume() || ce.DroppedMembers > 0 {\n\t\t\t\tmark(words.HoleWithheld)\n\t\t\t} else {\n\t\t\t\tmark(words.HolePending)\n\t\t\t}\n",
"replace": "\t\t\tmark(words.HolePending)\n"
}
]
},
{
"id": "RETRYSTOP-the-mark-forgets-the-echo-the-book-paid-for",
"battery": true,
"why": "the mark's own reason says why the PURCHASE did not happen, so what the paid attempt came back as lives in first_flag_reason or nowhere. Dropped, a draft that ECHOED and whose re-roll a ceiling refused stays in the echo metric's denominator and leaves its numerator: the echo rate FALLS on the very run that bought the echo — the 25.07 shape («echo_draft=0.0% of 20»), one column along, invisible to every other surface",
"package": "./internal/pipeline/",
"run": "TestAnEchoSomebodyPaidForStaysInTheMetricWhenTheMoneyRanOut|TestStopMarkForAsksWhetherAnythingWasEverBought",
"edits": [
{
"file": "internal/pipeline/cutcall.go",
"find": "\t\t\tfirstFlag: recoveredFirstFlag(p.firstFlagReason, FlagRetryUnaffordable),",
"replace": "\t\t\tfirstFlag: \"\","
}
]
},
{
"id": "RETRYSTOP-the-cancelled-mark-forgets-what-failed-first",
"battery": true,
"why": "the same column on the other stop mark: a run cut over a position's SECOND attempt has a first failure too, and without it that echo leaves the metric the same way. This half had no carrier at all before the pack — the cancelled mark never wrote the column",
"package": "./internal/pipeline/",
"run": "TestStopMarkForAsksWhetherAnythingWasEverBought",
"edits": [
{
"file": "internal/pipeline/cutcall.go",
"find": "\t\t\tfirstFlag: recoveredFirstFlag(p.firstFlagReason, FlagCancelled),",
"replace": "\t\t\tfirstFlag: \"\","
}
]
},
{
"id": "RETRYSTOP-a-redrive-buys-the-paid-attempt-again",
"battery": true,
"why": "a redrive RESETS its targets, and ResetChunkStages DELETES their checkpoints — including the one holding the already-paid text of attempt 0 behind a `retry_unaffordable` mark. Read as an ordinary flagged row, the operator's default gesture after a run full of flags buys that attempt a second time, while the resume needed only the re-attack. Before the mark existed the position had no row and a redrive could not reach it at all",
"package": "./internal/pipeline/",
"run": "TestARedriveDoesNotBuyThePaidAttemptAgain",
"edits": [
{
"file": "internal/pipeline/status.go",
"find": "\t\t\tif cs.Disposition == string(DispFlagged) && resolvedForResume(&cs) && sel.matches(cs) {",
"replace": "\t\t\tif cs.Disposition == string(DispFlagged) && sel.matches(cs) {"
}
]
},
{
"id": "RETRYSTOP-a-marked-unit-is-charged-a-grant-slot",
"battery": true,
"why": "the completeness test predicts «no provider call», and a stop mark is a position the next run RE-DOES for money. Counted as recorded, the unit skips the `carried` class and lands in `rework`, which TAKES a grant slot (granted()) and is queued behind fresh book — so a purchase of N chapters pays for a unit an earlier run already paid to START, which is exactly what the --max-units help text promises never happens",
"package": "./internal/pipeline/",
"run": "TestAMarkedUnitIsCarriedAndNotChargedAGrantSlot",
"edits": [
{
"file": "internal/pipeline/volume.go",
"find": "\tanswered, _, want := unitPositionsOnFile(u, rows, draftStages, editStages)\n\treturn answered == want",
"replace": "\t_, started, want := unitPositionsOnFile(u, rows, draftStages, editStages)\n\treturn started == want"
}
]
},
{
"id": "RETRYSTOP-the-wave-counter-reports-the-book-as-done",
"battery": true,
"why": "the wave counters are what the MONEY WIRE is made of (events.go beginWaves → moneyLedger → units_resolved/units_deferred). Counting a stop mark as a resolution makes the resume of a paused book publish «resolved 2, deferred 0» on a run that bought nothing and left the same hole — the buyer deciding whether to top up is told the book owes nothing. Measured before the guard: done 1→2 and deferred 1→0 between two identical stopped runs",
"package": "./internal/pipeline/",
"run": "TestTheWaveCountersDoNotTellTheBuyerTheBookIsDone",
"edits": [
{
"file": "internal/pipeline/status.go",
"find": "\t\tif cs.Disposition == string(DispFlagged) && !resolvedForResume(&cs) {\n\t\t\tcontinue\n\t\t}",
"replace": ""
}
]
},
{
"id": "RETRYSTOP-the-plaintext-export-calls-a-stop-mark-a-humans-problem",
"battery": true,
"why": "the third surface of one sentence: «not translated, flagged for a human» is false of a position that was paid for and not finished — no human has anything to check, the next run does it. The book writer and the stopped-run account were corrected first and this banner kept saying the opposite in the same file",
"package": "./cmd/tmctl/",
"run": "TestThePlaintextExportDoesNotCallAStopMarkAHumansProblem",
"edits": [
{
"file": "cmd/tmctl/render.go",
"find": "\t\t\tcase !pipeline.FlagReason(ce.FlagReason).AnswersForResume() && ce.DroppedMembers == 0:",
"replace": "\t\t\tcase false:"
}
]
},
{
"id": "ECHOREC-the-editors-own-echo-leaves-the-metric",
"battery": true,
"why": "the edit counter sees an editor echo only while it is still the row's VERDICT. Without the second arm, an echo a re-roll RECOVERED is invisible (older), and an echo whose re-roll a ceiling refused leaves the numerator while its mark row stays in `editRows` — so the edit echo RATE FALLS on the run that just paid for an editor echo. Measured on that shape: cost_usd=0.001820 with echo_edit_units=0",
"package": "./internal/pipeline/",
"run": "TestTheEDITORsOwnEchoStaysCountableWhenTheMoneyRanOut",
"edits": [
{
"file": "internal/pipeline/quality.go",
"find": "\t\t\tcase cs.FirstFlagReason == string(FlagCJKArtifact):\n\t\t\t\teditEcho++\n\t\t\t\tif shippedText(cs) {\n\t\t\t\t\teditEchoRecovered++\n\t\t\t\t}\n\t\t\t}",
"replace": "\t\t\t}"
}
]
},
{
"id": "READERHOLE-a-lost-member-is-promised-back-by-the-next-run",
"battery": true,
"why": "a c-lite unit can carry a PERMANENTLY flagged member (its text is gone whatever the next run buys) together with a stop mark on the stage that would have assembled it. «Paid for and NOT done — the next run re-does it» is then a half-truth that hides the half a human has to act on, and the gap marker is not printed either",
"package": "./cmd/tmctl/",
"run": "TestThePlaintextExportDoesNotCallAStopMarkAHumansProblem",
"edits": [
{
"file": "cmd/tmctl/render.go",
"find": "\t\t\tcase !pipeline.FlagReason(ce.FlagReason).AnswersForResume() && ce.DroppedMembers == 0:",
"replace": "\t\t\tcase !pipeline.FlagReason(ce.FlagReason).AnswersForResume():"
}
]
},
{
"id": "READERHOLE-the-reader-is-promised-a-member-no-purchase-returns",
"battery": true,
"why": "the same half-truth in the reader's own file: «ещё не переведён» about a unit whose member is permanently flagged promises a next run that cannot bring that text back. The withheld phrase asks for a human, which is what the lost member needs",
"package": "./internal/pipeline/",
"run": "TestTheReadersFileDoesNotSendThemToWaitForAHumanWhoCannotHelp",
"edits": [
{
"file": "internal/pipeline/bookbuild.go",
"find": "\t\t\tif FlagReason(ce.FlagReason).AnswersForResume() || ce.DroppedMembers > 0 {",
"replace": "\t\t\tif FlagReason(ce.FlagReason).AnswersForResume() {"
}
]
},
{
"id": "READERHOLE-the-operator-is-told-only-the-cheerful-half",
"battery": true,
"why": "the build's refusal text is what the person who can ACT reads. A unit can be «paid for and not done» AND short a member for good; told only the first half he tops up, resumes, and the build refuses again with a different hole. The drop count was not even on the withheld hole record, so this surface could not ask the question the other two had learned",
"package": "./internal/pipeline/",
"run": "TestTheOperatorsRefusalTellsHimBothHalves",
"edits": [
{
"file": "internal/pipeline/bookbuild.go",
"find": "\t\t\tcase h.Dropped > 0:",
"replace": "\t\t\tcase false:"
}
]
},
{
"id": "ECHOREC-a-recovered-echo-loses-its-recovery-when-the-strip-ships-it",
"battery": true,
"why": "the recovery question is «did the ROW produce text», not «is the row ok». Keyed on the ok verdict alone it loses a real cure: the hop's answer can come back with a cosmetic leak, which the sanitizer strips and SHIPS (final_hash points at the derived export), so an echo that was genuinely fixed reports as none — on the three shipping pipelines where the sanitizer gate is on",
"package": "./internal/pipeline/",
"run": "TestARecoveredEchoIsReportedAsRecoveredOnBothStages",
"edits": [
{
"file": "internal/pipeline/quality.go",
"find": "func shippedText(cs store.ChunkStatus) bool { return cs.FinalHash != \"\" }",
"replace": "func shippedText(cs store.ChunkStatus) bool { return cs.Disposition == string(DispOK) }"
}
]
},
{
"id": "ECHOREC-the-editors-recovered-subset-leaves-the-report",
"battery": true,
"why": "the FIELD echo_edit_recovered is what keeps the widened numerator readable: the counter now counts an echo the editor made whatever happened next, so a book that recovered one reports echo_edit=1 with nothing saying it cost the book nothing. Attacks the subset, not the surface that prints it — the operator's own line is ECHOHEAD-* in ./cmd/tmctl/",
"package": "./internal/pipeline/",
"run": "TestARecoveredEchoIsReportedAsRecoveredOnBothStages",
"edits": [
{
"file": "internal/pipeline/quality.go",
"find": "\t\t\t\tif shippedText(cs) {\n\t\t\t\t\teditEchoRecovered++\n\t\t\t\t}",
"replace": ""
}
]
},
{
"id": "ECHOHEAD-the-editors-recovered-share-leaves-the-operators-line",
"battery": true,
"why": "the line the operator reads is the surface the recovered split exists for, and it had no catcher at all: mutating editRecovered away left ./cmd/tmctl/ green end to end. Without the clause he reads «echo edit=2 (25.0%)» over a book whose editor echo was cured and whose prose shipped clean",
"package": "./cmd/tmctl/",
"run": "TestTheOperatorsEchoLineCarriesBothRecoveredShares",
"edits": [
{
"file": "cmd/tmctl/render.go",
"find": "\tif q.EchoEditRecovered > 0 {\n\t\teditRecovered = fmt.Sprintf(\", %d recovered\", q.EchoEditRecovered)\n\t}",
"replace": ""
}
]
},
{
"id": "ECHOHEAD-the-drafts-recovered-share-leaves-the-operators-line",
"battery": true,
"why": "the translator half of the same line, unpinned since it was built (the pack that copied its numerator to the editor copied the gap too). Without it a book whose every draft echo the escalation fixed reads «echo draft=4 (50.0%)» — a rate that looks like live breakage and cost nothing beyond the wasted primary call",
"package": "./cmd/tmctl/",
"run": "TestTheOperatorsEchoLineCarriesBothRecoveredShares",
"edits": [
{
"file": "cmd/tmctl/render.go",
"find": "\tif q.EchoDraftRecovered > 0 {\n\t\trecovered = fmt.Sprintf(\", %d recovered by escalation\", q.EchoDraftRecovered)\n\t}",
"replace": ""
}
]
},
{
"id": "ECHOHEAD-the-editors-slot-prints-the-drafts-share",
"battery": true,
"why": "two stages, two shares, one line: a writer that fills the editor's slot from the draft counter tells the operator the EDITOR recovered what the translator did. Caught only by a fixture where one stage recovered and the other did not, which is why the pin carries that table rather than a single all-non-zero case",
"package": "./cmd/tmctl/",
"run": "TestOneStagesRecoveryDoesNotFillTheOtherStagesSlot",
"edits": [
{
"file": "cmd/tmctl/render.go",
"find": "\tif q.EchoEditRecovered > 0 {\n\t\teditRecovered = fmt.Sprintf(\", %d recovered\", q.EchoEditRecovered)\n\t}",
"replace": "\teditRecovered = recovered"
}
]
},
{
"id": "ECHOHEAD-a-recovered-clause-is-printed-at-zero",
"battery": true,
"why": "the clause must be ABSENT when nothing was recovered, or the report tells the operator a book recovered echoes it never had — the mirror of the defect and the reason the pin carries a zero control at all",
"package": "./cmd/tmctl/",
"run": "TestTheRecoveredSharesAreAbsentWhenNothingWasRecovered",
"edits": [
{
"file": "cmd/tmctl/render.go",
"find": "\tif q.EchoEditRecovered > 0 {",
"replace": "\tif q.EchoEditRecovered >= 0 {"
}
]
},
{
"id": "ECHOHEAD-the-totals-line-swaps-its-two-counters",
"battery": true,
"why": "«with a final-stage row» and «with export text» are the two halves of the money question — how many positions the book has spent on versus how many a reader can open — and a stop mark is exactly the unit where they differ. Swapped, the headline reports the book as more finished than it is",
"package": "./cmd/tmctl/",
"run": "TestTheOperatorsEchoLineCarriesBothRecoveredShares",
"edits": [
{
"file": "cmd/tmctl/render.go",
"find": "q.TotalUnits, q.ProcessedUnits, q.TextUnits)",
"replace": "q.TotalUnits, q.TextUnits, q.ProcessedUnits)"
}
]
},
{
"id": "ECHOHEAD-a-draft-recovered-clause-is-printed-at-zero",
"battery": true,
"why": "the mirror of the editor's zero case, and the catalogue under-recorded what the pin already guards: printed at zero the translator half tells the operator a book recovered echoes it never had. Both halves of one line, both plantings, or the next reader of the catalogue believes one covers two",
"package": "./cmd/tmctl/",
"run": "TestTheRecoveredSharesAreAbsentWhenNothingWasRecovered",
"edits": [
{
"file": "cmd/tmctl/render.go",
"find": "\tif q.EchoDraftRecovered > 0 {",
"replace": "\tif q.EchoDraftRecovered >= 0 {"
}
]
},
{
"id": "ECHOREC-the-edit-arm-shrinks-to-the-final-stage",
"battery": true,
"why": "the edit arm counts the edit WAVE, not the final stage, and `waveStages` puts every non-translator stage in that wave — a pipeline declaring `select`+`edit` has an echo row that is not the unit's last word. Narrowed to the final stage the metric loses the editor echo of every multi-stage edit wave, and the loss is invisible on the one-stage fixtures the rest of the package uses. ⚠ The narrowing is ANDed onto the set test rather than replacing it: dropping the set's only use makes `editStageNames` declared-and-not-used, the mutant does not build, and the tool reports NOTHING RAN — an unmeasured entry, which is worse than a surviving one",
"package": "./internal/pipeline/",
"run": "TestACuredEchoOnAMidEditStageIsStillCuredWhenTheUnitDiesLater",
"edits": [
{
"file": "internal/pipeline/quality.go",
"find": "case editStageNames[cs.Stage] && inManifest[k]:",
"replace": "case editStageNames[cs.Stage] && cs.Stage == r.finalStageName() && inManifest[k]:"
}
]
},
{
"id": "ECHOREC-the-editors-recovery-stops-asking-whether-anything-shipped",
"battery": true,
"why": "the mirror of ECHOREC-a-superseded-echo-counts-as-recovered on the arm that had only the positive half of its guard: with the gate gone every superseded editor echo counts as cured, so a run whose re-roll a CEILING refused reports «echo edit=1 (100.0%), 1 recovered» over a book nobody cured anything in — the inversion of the defect the clause was built for. Measured before the pin existed: dropping the gate left the whole package green",
"package": "./internal/pipeline/",
"run": "TestTheEDITORsOwnEchoStaysCountableWhenTheMoneyRanOut",
"edits": [
{
"file": "internal/pipeline/quality.go",
"find": "\t\t\t\teditEcho++\n\t\t\t\tif shippedText(cs) {\n\t\t\t\t\teditEchoRecovered++\n\t\t\t\t}",
"replace": "\t\t\t\teditEcho++\n\t\t\t\teditEchoRecovered++"
}
]
},
{
"id": "RETRYSTOP-a-redrive-resets-the-stop-mark-beside-its-target",
"battery": true,
"why": "the redrive's STAGE LIST is the second half of the guard that keeps a stop mark out of a redrive's radius, and the state it guards is reachable in ONE run: on a c-lite unit the leader's draft is refused (a verdict) while the edit, keyed on the same leader chunk, stops on a ceiling-refused re-attack. With the mark in the list, redriving the refused draft deletes the edit's checkpoints — its PAID attempt 0 — so when the draft is refused again the resume buys that attempt a second time instead of replaying it for $0",
"package": "./internal/pipeline/",
"run": "TestARedriveOfAVerdictDoesNotResetTheStopMarkBesideIt",
"edits": [
{
"file": "internal/pipeline/status.go",
"find": "\t\t\tif cs.Disposition == string(DispSkipped) ||\n\t\t\t\t(cs.Disposition == string(DispFlagged) && resolvedForResume(&cs)) {",
"replace": "\t\t\tif cs.Disposition == string(DispSkipped) ||\n\t\t\t\tcs.Disposition == string(DispFlagged) {"
}
]
},
{
"id": "BANK-silent-target-guard-never-runs",
"why": "the whole preflight: a target with no injection rows renders both bank blocks into zero bytes with no error, so the run buys its bank roles, stops for a signature and injects nothing",
"package": "./internal/pipeline/",
"run": "TestABankItsTargetCannotStateRefusesBeforeItIsBought",
"battery": true,
"edits": [
{
"file": "internal/pipeline/runner.go",
"find": "\t\tif err := r.checkInjectionTexts(logger); err != nil {",
"replace": "\t\tif err := error(nil); err != nil {"
}
]
},
{
"id": "BANK-silent-target-guard-fires-on-a-read-open",
"why": "a $0 read buys nothing, so a book must stay inspectable on a host that cannot run it (D20.4); the guard is write-path only, like the two refusals beside it",
"package": "./internal/pipeline/",
"run": "TestABankItsTargetCannotStateRefusesBeforeItIsBought",
"battery": true,
"edits": [
{
"file": "internal/pipeline/runner.go",
"find": "\tif forWrite {\n\t\tif err := r.checkInjectionTexts(logger); err != nil {",
"replace": "\tif true {\n\t\tif err := r.checkInjectionTexts(logger); err != nil {"
}
]
},
{
"id": "BANK-silent-target-editor-key-dropped",
"why": "the editor's block needs its own header row; without it the editor is handed a bare list of renderings with nothing saying what they are, and the refusal stops naming the row an author must add",
"package": "./internal/pipeline/",
"run": "TestABankItsTargetCannotStateRefusesBeforeItIsBought",
"battery": true,
"edits": [
{
"file": "internal/pipeline/chunkrun.go",
"find": "\troleEditor: {lang.InjectionKeyGlossaryHeader, lang.InjectionKeyEditorHeader},",
"replace": "\troleEditor: {lang.InjectionKeyGlossaryHeader},"
}
]
},
{
"id": "BANK-silent-target-seed-door-closed",
"why": "the injection is built from bank ROWS, not from the gate: a book with a seed and the terminology gate OFF injects exactly as silently as one with the gate on",
"package": "./internal/pipeline/",
"run": "TestABankItsTargetCannotStateRefusesBeforeItIsBought",
"battery": true,
"edits": [
{
"file": "internal/pipeline/injectionpreflight.go",
"find": "\tcase r.Book.GlossarySeed != \"\":",
"replace": "\tcase false:"
}
]
},
{
"id": "BANK-silent-target-store-door-closed",
"why": "the auto-bank a PREVIOUS run left in the store is a door no config file mentions — the gate is a run-local knob, the rows in the store are not",
"package": "./internal/pipeline/",
"run": "TestABankItsTargetCannotStateRefusesBeforeItIsBought",
"battery": true,
"edits": [
{
"file": "internal/pipeline/injectionpreflight.go",
"find": "\tif len(rows) > 0 {",
"replace": "\tif false {"
}
]
},
{
"id": "BANK-silent-target-delta-door-closed",
"why": "the owner's mined-delta is DERIVED beside book.yaml, so a config check cannot see it; its rows reach the wire like any other",
"package": "./internal/pipeline/",
"run": "TestABankItsTargetCannotStateRefusesBeforeItIsBought",
"battery": true,
"edits": [
{
"file": "internal/pipeline/injectionpreflight.go",
"find": "\t\treturn \"the owner's mined-delta \" + r.Book.MinedDelta + \" holds signed rows\", true",
"replace": "\t\treturn \"the owner's mined-delta \" + r.Book.MinedDelta + \" holds signed rows\", false"
}
]
},
{
"id": "BANK-silent-target-banknote-door-closed",
"why": "the banknote channel feeds the same bank; a run with it on and nothing else still builds rows nobody can be told about",
"package": "./internal/pipeline/",
"run": "TestABankItsTargetCannotStateRefusesBeforeItIsBought",
"battery": true,
"edits": [
{
"file": "internal/pipeline/injectionpreflight.go",
"find": "\tcase r.Pipeline.Gates.Banknote.Enabled:",
"replace": "\tcase false:"
}
]
},
{
"id": "BANK-silent-target-completeness-is-blind",
"why": "MissingKeys is the completeness predicate; blind, it reports nothing missing and a half-authored target passes the guard that exists to stop it",
"package": "./internal/lang/",
"run": "TestAPartialInjectionSetIsVisibleToTheGuard",
"battery": true,
"edits": [
{
"file": "internal/lang/embedded.go",
"find": "\t\tif !t.Authored(k) {",
"replace": "\t\tif false {"
}
]
},
{
"id": "BANK-injection-unknown-key-reads-as-authored",
"why": "a key no parser accepts must never read as authored, or a guard asking for a row the file cannot carry passes forever",
"package": "./internal/lang/",
"run": "TestTheInjectionKeysAreOneVocabulary",
"battery": true,
"edits": [
{
"file": "internal/lang/embedded.go",
"find": "\treturn known && fld.get(t) != \"\"",
"replace": "\treturn !known || fld.get(t) != \"\""
}
]
},
{
"id": "BANK-gender-gap-never-reported",
"why": "a half-authored gender set silently drops the owner's own directive (D39.254 п.3) from every row of the missing sex; the warning is the only thing that says so",
"package": "./internal/lang/",
"run": "TestAPartialInjectionSetIsVisibleToTheGuard",
"battery": true,
"edits": [
{
"file": "internal/lang/embedded.go",
"find": "\tif len(gaps) == len(genderDirectiveKeys) {",
"replace": "\tif len(gaps) > 0 {"
}
]
},
{
"id": "BANK-prose-decline-is-banked-as-canon",
"why": "«не термин» passes every other check — well formed, not an echo, in the target's own script — and is banked as the book's canon, reaching the editor as law byte-identically to a signed row",
"package": "./internal/terminology/",
"run": "TestAProseDeclineLandsInTheDeclineBucketAndNotInTheBank",
"battery": true,
"edits": [
{
"file": "internal/terminology/terminology.go",
"find": "\t\tif declined != nil && declined(dst) {",
"replace": "\t\tif false && declined != nil && declined(dst) {"
}
]
},
{
"id": "BANK-prose-decline-counted-as-a-broken-line",
"why": "a decline is a DECISION and must land where the sentinel lands (present, empty rendering); counted as a bad line it reads as «the role said nothing», and the next mechanism routes it to the wrong place",
"package": "./internal/terminology/",
"run": "TestAProseDeclineLandsInTheDeclineBucketAndNotInTheBank",
"battery": true,
"edits": [
{
"file": "internal/terminology/terminology.go",
"find": "\t\tif declined != nil && declined(dst) {\n\t\t\tout[key] = \"\"",
"replace": "\t\tif declined != nil && declined(dst) {\n\t\t\tst.Bad++"
}
]
},
{
"id": "BANK-prose-decline-not-counted",
"why": "the count is what tells an operator the pair's prompt lost its sentinel format; without it a role answering in prose looks exactly like one using the sentinel",
"package": "./internal/terminology/",
"run": "TestAProseDeclineLandsInTheDeclineBucketAndNotInTheBank",
"battery": true,
"edits": [
{
"file": "internal/terminology/terminology.go",
"find": "\t\t\tst.DeclinedByPhrase++",
"replace": ""
}
]
},
{
"id": "BANK-letterless-answer-is-banked",
"why": "«90» is two runes with no bracket and no dash, so wellFormedLemma passes it and the answer-language screen is silent on a field with no letters; past both it is stamped status:draft and injected as canon",
"package": "./internal/terminology/",
"run": "TestARenderingWithNoLettersReadsAsUnansweredNotAsCanon",
"battery": true,
"edits": [
{
"file": "internal/terminology/terminology.go",
"find": "\t\tif !hasLetter(dst) {",
"replace": "\t\tif false {"
}
]
},
{
"id": "BANK-letterless-rule-refuses-digits",
"why": "the test is the ABSENCE of letters, not the presence of digits: numbers are legitimate inside a name or a series, and refusing them costs the bank real rows it paid for",
"package": "./internal/terminology/",
"run": "TestARenderingWithNoLettersReadsAsUnansweredNotAsCanon",
"battery": true,
"edits": [
{
"file": "internal/terminology/terminology.go",
"find": "\t\tif !hasLetter(dst) {",
"replace": "\t\tif !hasLetter(dst) || strings.ContainsAny(dst, \"0123456789\") {"
}
]
},
{
"id": "BANK-letterless-lines-not-named",
"why": "a bare count cannot tell a budget-truncated reply from a model answering in numbers; the refused lines are named so the first live one can be read",
"package": "./internal/terminology/",
"run": "TestARenderingWithNoLettersReadsAsUnansweredNotAsCanon",
"battery": true,
"edits": [
{
"file": "internal/terminology/terminology.go",
"find": "\t\t\tst.NoLetters++",
"replace": ""
}
]
},
{
"id": "BANK-decline-match-is-a-substring",
"why": "a substring match turns any rendering containing the phrase into a decline: the term leaves the bank, the book loses a canon row it PAID for, and a bank role has no retry to recover it (row 438)",
"package": "./internal/lang/",
"run": "TestTheDeclineMatchIsTheWholeFieldAndFoldsTheShapesAModelWrites",
"battery": true,
"edits": [
{
"file": "internal/lang/declinephrases.go",
"find": "\treturn d.folded[foldDeclinePhrase(dst)]",
"replace": "\tfor p := range d.folded {\n\t\tif strings.Contains(strings.ToLower(dst), p) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false"
}
]
},
{
"id": "BANK-decline-fold-keeps-the-quoting",
"why": "the phrase is authored by a human and the field is written by a model: a row authored «не термин» must still match «„Не термин.“», or the registry only fires on the one shape nobody writes",
"package": "./internal/lang/",
"run": "TestTheDeclineMatchIsTheWholeFieldAndFoldsTheShapesAModelWrites",
"battery": true,
"edits": [
{
"file": "internal/lang/declinephrases.go",
"find": "\ts = strings.Trim(s, `\"'«»“”„‘’()[]{}`)",
"replace": ""
}
]
},
{
"id": "BANK-decline-any-target-rows-ignored",
"why": "a model that drifts into English declines in English even in a →ru book; the any-target rows exist for that drift and a target-only lookup silently drops them",
"package": "./internal/lang/",
"run": "TestTheDeclineMatchIsTheWholeFieldAndFoldsTheShapesAModelWrites",
"battery": true,
"edits": [
{
"file": "internal/lang/declinephrases.go",
"find": "\town, anyTarget := rows[key], rows[declineAnyTarget]",
"replace": "\town, anyTarget := rows[key], map[string]bool(nil)"
}
]
},
{
"id": "BANK-decline-registry-ships-a-phrase",
"why": "the registry lands EMPTY on purpose and the emptiness lives in DATA, where no gate but this one can see it — the class backlog rows 433 and 435 record twice",
"package": "./internal/lang/",
"run": "TestTheDeclineRegistryShipsEmpty",
"battery": true,
"edits": [
{
"file": "internal/lang/bankdata/decline-phrases.txt",
"find": "# entered when its population has been MEASURED on bought material, not when it sounds right.",
"replace": "# entered when its population has been MEASURED on bought material, not when it sounds right.\nru\tне термин"
}
]
},
{
"id": "BANK-role-loses-the-letterless-count",
"why": "the role's own result is what the stop and the report read; a counter that stops at the parser tells nobody",
"package": "./internal/pipeline/",
"run": "TestADeclineAndGarbageLandInDifferentBuckets",
"battery": true,
"edits": [
{
"file": "internal/pipeline/terminologist.go",
"find": "\t\tres.NoLetters += st.NoLetters",
"replace": ""
}
]
},
{
"id": "BANK-role-is-not-wired-to-the-registry",
"why": "«the registry is empty» and «the role was never given a registry» are the same behaviour while the shipped registry has no rows, and must not be the same STATE: one is a decision, the other a bug nothing could see",
"package": "./internal/pipeline/",
"run": "TestAProseDeclineNeverBecomesTheBooksCanon",
"battery": true,
"edits": [
{
"file": "internal/pipeline/runner.go",
"find": "\tr.declinedByPhrase = lang.DeclinePhrasesFor(book.TargetLang).Match",
"replace": ""
}
]
},
{
"id": "BANK-contest-counts-the-spread-not-the-conventions",
"why": "«Море истинной ци» and «море истинной ци» are ONE decision written two ways; a predicate on the raw spread sends a normalization nit to a second paid model",
"package": "./internal/terminology/",
"run": "TestThePreCallContestReadsDisagreementAndNotVolume",
"battery": true,
"edits": [
{
"file": "internal/terminology/contested.go",
"find": "\tout := Contest{Conventions: c.Conventions()}",
"replace": "\tout := Contest{Conventions: c.Spread()}"
}
]
},
{
"id": "BANK-contest-dominance-arm-inverted",
"why": "the dominance arm settles a contest the drafts already won by a margin; inverted it settles exactly the contests that ARE close and routes the agreed ones to a second opinion",
"package": "./internal/terminology/",
"run": "TestThePreCallContestReadsDisagreementAndNotVolume",
"battery": true,
"edits": [
{
"file": "internal/terminology/contested.go",
"find": "\tif o.MaxLeaderShare > 0 && out.LeaderShare > o.MaxLeaderShare {",
"replace": "\tif o.MaxLeaderShare > 0 && out.LeaderShare < o.MaxLeaderShare {"
}
]
},
{
"id": "BANK-contest-unsupported-reads-as-agreement",
"why": "a candidate no draft rendered is not agreement; a router that read it so would send the least-evidenced rows down the cheapest path",
"package": "./internal/terminology/",
"run": "TestThePreCallContestReadsDisagreementAndNotVolume",
"battery": true,
"edits": [
{
"file": "internal/terminology/contested.go",
"find": "\t\tout.Unsupported = true",
"replace": ""
}
]
},
{
"id": "BANK-contest-no-chunk-count-reads-as-dominance",
"why": "renderings with nothing behind them are not a dominant leader; calling that dominance settles every such contest silently",
"package": "./internal/terminology/",
"run": "TestThePreCallContestReadsDisagreementAndNotVolume",
"battery": true,
"edits": [
{
"file": "internal/terminology/contested.go",
"find": "\t\tout.LeaderShare = 0\n",
"replace": "\t\tout.LeaderShare = 1\n"
}
]
},
{
"id": "BANK-stop-contest-selects-a-row-nobody-asked-about",
"why": "a row the bank settled has no answer to doubt; selecting it puts the cheapest rows at the head of the queue for a second PAID opinion",
"package": "./internal/pipeline/",
"run": "TestThePostCallContestNeverSelectsARowNobodyAnswered",
"battery": true,
"edits": [
{
"file": "internal/pipeline/stopcontest.go",
"find": "\tif r.SettledByBank {\n\t\treturn out\n\t}",
"replace": ""
}
]
},
{
"id": "BANK-stop-contest-reads-a-missing-confidence-as-zero",
"why": "«the role said nothing» and «the role said it was 0 % sure» are opposite rows; merged, every silent reply becomes the most urgent one",
"package": "./internal/pipeline/",
"run": "TestThePostCallContestNeverSelectsARowNobodyAnswered",
"battery": true,
"edits": [
{
"file": "internal/pipeline/stopcontest.go",
"find": "\tif o.UseConf && r.Conf >= 0 && r.Conf <= o.MaxConf {",
"replace": "\tif o.UseConf && r.Conf <= o.MaxConf {"
}
]
},
{
"id": "BANK-stop-table-reader-skips-what-it-cannot-read",
"why": "a reader that skips an unknown line returns a SHORT table, and every share computed from it is wrong by an invisible amount",
"package": "./internal/pipeline/",
"run": "TestTheStopTableCanBeReadBackIntoTheRowsThatWroteIt",
"battery": true,
"edits": [
{
"file": "internal/pipeline/bankstopparse.go",
"find": "\t\t\treturn nil, fmt.Errorf(\"line %d: unrecognised field line %q\", line, text)",
"replace": "\t\t\tcontinue"
}
]
},
{
"id": "BANK-stop-table-reader-ignores-the-declared-count",
"why": "the banner's count is the file's own control on itself: without it a truncated evidence file reads as a complete one",
"package": "./internal/pipeline/",
"run": "TestTheStopTableCanBeReadBackIntoTheRowsThatWroteIt",
"battery": true,
"edits": [
{
"file": "internal/pipeline/bankstopparse.go",
"find": "\tif declared != len(rows) {",
"replace": "\tif false && declared != len(rows) {"
}
]
},
{
"id": "BANK-variant-label-parse-drops-the-chunk-count",
"why": "the chunk counts behind each rendering are what every disagreement number is computed from; zeroed, the drafts look unanimous",
"package": "./internal/pipeline/",
"run": "TestTheStopTableCanBeReadBackIntoTheRowsThatWroteIt",
"battery": true,
"edits": [
{
"file": "internal/pipeline/mining.go",
"find": "\tv.Dst, v.Chunks = s[:i], n",
"replace": "\tv.Dst, v.Chunks = s[:i], 0"
}
]
},
{
"id": "BANK-variant-label-parse-accepts-a-foreign-string",
"why": "a string this engine never wrote must be refused, not read as a rendering with nothing behind it",
"package": "./internal/pipeline/",
"run": "TestTheStopTableCanBeReadBackIntoTheRowsThatWroteIt",
"battery": true,
"edits": [
{
"file": "internal/pipeline/mining.go",
"find": "\ti := strings.LastIndex(s, \" ×\")\n\tif i <= 0 {\n\t\treturn BankStopVariant{}, false\n\t}",
"replace": "\ti := strings.LastIndex(s, \" ×\")\n\tif i <= 0 {\n\t\tv.Dst = s\n\t\treturn v, true\n\t}"
}
]
},
{
"id": "BANK-probe-counts-a-settled-row-as-a-candidate",
"why": "the settled filter runs BEFORE the first paid call, so a row it removed is neither a candidate at the role's input nor a row the role answered; counted on the pre-call side alone it dilutes every share on that side",
"package": "./cmd/tmbankprobe/",
"run": "TestARowTheBankSettledIsInNeitherDenominator",
"battery": true,
"edits": [
{
"file": "cmd/tmbankprobe/main.go",
"find": "\tpreCall = len(s.rows) - settled",
"replace": "\tpreCall = len(s.rows)"
}
]
},
{
"id": "BANK-probe-folds-the-answer-into-the-compared-input",
"why": "the §4.4 comparison asks whether a row's INPUT changed where its decision changed; fold the consolidated rendering into the input and the answer is «it changed» for 100 % of the population, by construction, with nothing red",
"package": "./cmd/tmbankprobe/",
"run": "TestTheComparedInputNeverCarriesTheAnswer",
"battery": true,
"edits": [
{
"file": "cmd/tmbankprobe/passes.go",
"find": "\ts := fmt.Sprintf(\"type=%s origin=%s freq=%d drafts=[%s] evidence=[%s]\",\n\t\tr.Type, r.Origin, r.Freq, strings.Join(parts, \" | \"), strings.Join(r.Evidence, \"; \"))",
"replace": "\ts := fmt.Sprintf(\"dst=%s type=%s origin=%s freq=%d drafts=[%s] evidence=[%s]\",\n\t\tr.Dst, r.Type, r.Origin, r.Freq, strings.Join(parts, \" | \"), strings.Join(r.Evidence, \"; \"))"
}
]
},
{
"id": "BANK-stop-table-reader-breaks-on-a-paragraph-break",
"why": "a source KWIC window spanning a paragraph break carries the chunker's «\\n\\n» verbatim, so the sheet holds an EMPTY LINE INSIDE a context; read as a row boundary it makes one term unreadable and the whole measurement impossible",
"package": "./internal/pipeline/",
"run": "TestTheStopTableCanBeReadBackIntoTheRowsThatWroteIt",
"battery": true,
"edits": [
{
"file": "internal/pipeline/bankstopparse.go",
"find": "\t\t\tif nxt, ok := nextNonBlank(lines, i+1); cur != nil && len(cur.Contexts) > 0 && ok && !opensRow(nxt) {",
"replace": "\t\t\tif nxt, ok := nextNonBlank(lines, i+1); false && cur != nil && len(cur.Contexts) > 0 && ok && !opensRow(nxt) {\n\t\t\t\t_, _ = nxt, ok"
}
]
},
{
"id": "BANK-stop-table-reader-splits-a-list-item-in-two",
"why": "the writer joins evidence with «, » and the miner writes «related to mined X, Y» as ONE item; a reader that split on the separator returns more items than the run had, silently, with the row count still matching",
"package": "./internal/pipeline/",
"run": "TestTheStopTableCanBeReadBackIntoTheRowsThatWroteIt",
"battery": true,
"edits": [
{
"file": "internal/pipeline/bankstopparse.go",
"find": "\t\t\tcur.Evidence = whole(strings.TrimPrefix(body, \"evidence: \"))",
"replace": "\t\t\tcur.Evidence = strings.Split(strings.TrimPrefix(body, \"evidence: \"), \", \")"
}
]
},
{
"id": "BANK-stop-contest-zero-value-is-an-active-arm",
"why": "an opts struct that declares «no defaults live here» may not have a zero value with behaviour: with a «-1 disables» sentinel a caller who filled nothing selected every row whose reply stated 0 % — the most urgent rows on the sheet",
"package": "./internal/pipeline/",
"run": "TestThePostCallContestNeverSelectsARowNobodyAnswered",
"battery": true,
"edits": [
{
"file": "internal/pipeline/stopcontest.go",
"find": "\tif o.UseConf && r.Conf >= 0 && r.Conf <= o.MaxConf {",
"replace": "\tif o.MaxConf >= 0 && r.Conf >= 0 && r.Conf <= o.MaxConf {"
}
]
},
{
"id": "LADDER-bank-role-gets-no-ladder",
"why": "the whole pack: a bank batch the engine itself judged truncated or empty must be re-asked at a doubled budget. Pinned to zero, the role goes back to one call and a dropped verdict — 42 terms of 66 with no machine type on the cold run, two paid batches, and every counter an operator reads saying the pass was clean",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestATruncatedBankBatchIsAskedAgainAtADoubledBudget",
"edits": [
{
"file": "internal/pipeline/terminologist.go",
"find": "regens: r.Pipeline.Gates.Terminology.Regenerate}",
"replace": "regens: 0}"
}
]
},
{
"id": "LADDER-bank-rung-escapes-the-phase-budget",
"why": "a rung is a purchase the pass's pre-flight never planned, so without the phase's own admission it is bounded by nothing but the BOOK ceiling: a phase told to spend at most budget_usd doubles its way past it and no counter says so",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestARungTheRoleBudgetCannotAffordIsNotBought",
"edits": [
{
"file": "internal/pipeline/terminologist.go",
"find": "\t\tafford, maxRegens = budget.admitStep, budget.regens",
"replace": "\t\tafford, maxRegens = nil, budget.regens"
}
]
},
{
"id": "LADDER-pre-flight-and-rungs-count-different-money",
"why": "the pre-flight and the ladder must book against ONE running number. Given a tracker of its own, the pre-flight's plan is invisible to the rungs, so the phase can plan every first attempt AND buy every re-ask out of the same budget twice over",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestARungTheRoleBudgetCannotAffordIsNotBought",
"edits": [
{
"file": "internal/pipeline/terminologist.go",
"find": "\t\tif !budget.admit(want) {",
"replace": "\t\tif !(&roleBudget{limit: plan.budgetUSD, committed: spent}).admit(want) {"
}
]
},
{
"id": "LADDER-healthy-reply-keeps-climbing",
"why": "a GOOD answer must end the walk. ⚠ TWO EDITS, AND THE REASON IS THE VOCABULARY: for THIS property neither guard is load-bearing alone. Removing `if cls.ok() { break }` is a no-op because an ok reply's reason is in neither the retryable set nor the echo case, so the loop reaches its own break; relaxing retryable() is a no-op for an ok reply because the ok break fires first. Together they let a perfectly good bank reply take the regeneration branch: a second call per batch on every book forever, invisible in any counter that reports only what was consolidated. ⛔ Do NOT read this as «retryable() is redundant» — it is load-bearing for a DIFFERENT property (D2.2, a deterministic flag must not be re-bought on the same model), which LADDER-retryable-gate-lets-a-deterministic-flag-re-buy measures.",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestAHealthyBankTableIsNeverAskedAgain",
"edits": [
{
"file": "internal/pipeline/attemptladder.go",
"find": "\t\tif cls.ok() {\n\t\t\tbreak\n\t\t}",
"replace": "\t\tif false {\n\t\t\tbreak\n\t\t}"
},
{
"file": "internal/pipeline/attemptladder.go",
"find": "\t\tif cls.Reason.retryable() && run.regens < lc.maxRegens {",
"replace": "\t\tif run.regens < lc.maxRegens {"
}
]
},
{
"id": "LADDER-unusable-batch-not-counted",
"why": "a batch still flagged after every rung the phase could buy is the fact that separates «the model could not answer» from «the money ran out»; without the counter both are the same silence in the summary",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestARungTheRoleBudgetCannotAffordIsNotBought",
"edits": [
{
"file": "internal/pipeline/terminologist.go",
"find": "\t\tif !lr.last.cls.ok() {\n\t\t\trun.unusable++",
"replace": "\t\tif !lr.last.cls.ok() {\n\t\t\t_ = lr"
}
]
},
{
"id": "LADDER-refused-rung-not-reported",
"why": "a bank cut short by its own sub-budget must be distinguishable from one the model simply could not answer: the operator's action differs (raise the budget, or look at the model), and only this counter carries the difference",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestARungTheRoleBudgetCannotAffordIsNotBought",
"edits": [
{
"file": "internal/pipeline/terminologist.go",
"find": "\t\t\trun.stepsRefused++",
"replace": "\t\t\t_ = lr"
}
]
},
{
"id": "LADDER-classify-answer-share-loses-its-denominator",
"why": "«answered» without «asked» is a number with no meaning: the cold run printed classify_batches_dropped=0 over 42 unanswered terms, and the share is what tells money never spent from terms bought and unanswered",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestTheBankPassNamesItsAnswerShare",
"edits": [
{
"file": "internal/pipeline/terminologist.go",
"find": "\t\tasked += len(b)",
"replace": "\t\t_ = b"
}
]
},
{
"id": "BANKKEY-batch-ordinal-leaves-the-purchase-key",
"why": "the batch ordinal is a field of the request hash, so shifting it re-addresses every bank checkpoint an existing book holds and buys the whole pass again at unchanged text. No test in this package asserted the VALUE of that key before the golden",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestTheBankPassBuysAtThePinnedKey",
"edits": [
{
"file": "internal/pipeline/terminologist.go",
"find": "\t\tch := chunk.Chunk{Chapter: 0, ChunkIdx: i}\n\t\tlr, aerr := r.runBankAttempt",
"replace": "\t\tch := chunk.Chunk{Chapter: 0, ChunkIdx: i + 1}\n\t\tlr, aerr := r.runBankAttempt"
}
]
},
{
"id": "BANKKEY-the-ladder-starts-at-attempt-one",
"why": "attempt 0 is where every already-paid checkpoint lives, for the stage and for the bank role alike; starting the walk one index higher re-buys the entire corpus of paid work while every behavioural test still passes, because the answers are the same answers",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestTheBankPassBuysAtThePinnedKey",
"edits": [
{
"file": "internal/pipeline/attemptladder.go",
"find": "\tfor attempt := 0; ; attempt++ {",
"replace": "\tfor attempt := 1; ; attempt++ {"
}
]
},
{
"id": "BANKKEY-bank-reply-floor-moves-the-budget",
"why": "a bank call's output budget is part of its purchase key, and the reply floor is a term of it; moving it by one token re-keys every bank checkpoint in every book. The first draft of the golden could not see this at all — its messages were short enough that MinMaxTokens dominated and the formula never entered the key",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestBankBatchPurchaseKeyValueIsPinned",
"edits": [
{
"file": "internal/pipeline/terminologist.go",
"find": "const terminologyReplyFloor = 256",
"replace": "const terminologyReplyFloor = 257"
}
]
},
{
"id": "LADDER-admission-forgets-the-paid-probe",
"why": "an admission that does not first ask «is this rung already paid for?» refuses rungs the book HAS bought. roleBudget starts each pass at everything the phase has ever spent, so a long-lived book drifts into exactly that state — and the cost is not money (a replay is free) but the REPAIR: the pass serves the truncated reply again and the bank silently loses the terms the second rung had recovered ⚠ Spelled `paid && false` rather than `false`: the latter leaves `paid` declared and unused, so the package does not build and the harness reports «nothing ran» — an UNMEASURED record, which closes the question without asking it.",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestAnAlreadyBoughtRungIsNeverLostToTheBudget",
"edits": [
{
"file": "internal/pipeline/attemptladder.go",
"find": "\tif paid {\n\t\treturn step, true // an answer the store already holds: no money moves, so no rule applies\n\t}",
"replace": "\tif paid && false {\n\t\treturn step, true // an answer the store already holds: no money moves, so no rule applies\n\t}"
}
]
},
{
"id": "LADDER-retryable-gate-lets-a-deterministic-flag-re-buy",
"why": "D2.2: only length/empty may be re-attacked on the same model — everything else (refusal, content filter, echo, off-language, excision) is deterministic, so a same-model retry re-produces the failure and bills for it. Without the retryable() test every such flag buys one extra call at a doubled budget BEFORE the escalation hop, on every shipping pipeline (all four set regenerate_before_escalate: 1). ⚠ The catcher is a STAGE fixture, not a bank one: the bank roles reach neither a deterministic flag nor a second rung in the bank fixtures, so a single-test probe of this edit reports SURVIVED while the package is red ⚠ WHICH ASSERTION SPEAKS: the failure lands on runner_test.go's «edit must be skipped after an excision flag, calls=2» — the extra same-model call is what the editor-skip assertion sees first. The line that NAMES this record's subject («excision_suspect is non-retryable — exactly one attempt») is the assertion below it and now fires too, because both were made Errorf; before that every assertion in the block was Fatalf and the first one stopped the test. A right verdict whose text names the wrong mechanism sends the reader to fix the editor instead of the guard.",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestRunnerCoverageGateFlagsExcision",
"edits": [
{
"file": "internal/pipeline/attemptladder.go",
"find": "\t\tif cls.Reason.retryable() && run.regens < lc.maxRegens {",
"replace": "\t\tif run.regens < lc.maxRegens {"
}
]
},
{
"id": "LADDER-book-ceiling-on-a-later-rung-discards-the-paid-reply",
"why": "a hole the LADDER opened: before it, a bank batch was one call and a ceiling refusing it meant nothing had been bought, so stopping without keeping anything was the whole truth. With a ladder the ceiling can refuse rung ONE — and rung zero is by then paid for, classified, and holding whatever lines the model emitted before it was cut (four terms of twenty-two on the cold run). Dropping it settles the money and discards the answer, and the batch reads to every counter as one nobody called. ⚠ The BOOK ceiling arrives as an ERROR, not as the phase sub-budget's refusal, so the two paths agree only by hand",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestABookCeilingOnALaterRungKeepsWhatTheEarlierOneBought",
"edits": [
{
"file": "internal/pipeline/terminologist.go",
"find": "\t\t\t\tif lr.judged > 0 {\n\t\t\t\t\trun.texts[i], run.ran[i] = lr.last.text, true\n\t\t\t\t\trun.unusable++\n\t\t\t\t}",
"replace": "\t\t\t\tif false {\n\t\t\t\t\trun.texts[i], run.ran[i] = lr.last.text, true\n\t\t\t\t\trun.unusable++\n\t\t\t\t}"
}
]
},
{
"id": "Z-shipping-config-can-turn-the-bank-re-ask-off-silently",
"why": "the ONE money knob this pack lands ENABLED, attacked where the decision actually lives — in the shipping DATA. gates.terminology.regenerate: 1 is what makes the engine re-ask a bank batch it has itself judged truncated or empty; at zero the verdict is computed and dropped again, terms keep the draft heuristic type, and a type is what FORCES a transliteration, so the loss ships into every chapter the term occurs in. Nothing else in a run goes red for it: the cold run printed consolidated=66, dropped=0, unanswered=0 over 42 terms with no machine type. ⛔ THE EDIT IS THE CONFIG, NOT THE GO: the pin stands over DATA, so a mutation of code would measure emptiness — the sibling Z-shipping-config-can-turn-the-remedy-on-silently is attacked the same way, and taking its pin's FORM without its PLANTING is exactly the gap this entry closes",
"package": "./internal/config/",
"battery": true,
"run": "TestShippingPipelinesRegenerateBankRoles",
"edits": [
{
"file": "configs/pipeline-c1.yaml",
"find": " regenerate: 1",
"replace": " regenerate: 0"
}
]
},
{
"id": "BASIS-fp-hashes-what-the-drafts-merely-guessed",
"why": "the fingerprint's TRIGGER, attacked where money is. Draft variants, freq and since_ch all reach the role's prompt and all three move between purchases for reasons that are not new knowledge about the term — model noise, a cap, a re-cut. Hashing any of them turns ordinary variation into a re-purchase of the whole bank out of a LIFETIME per-book ceiling whose exhaustion is permanent (row 356). Nothing else goes red for it: the run still consolidates, the sheet still renders, only the bill grows",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestBasisFingerprintIgnoresWhatTheRoleMerelyGUESSED",
"edits": [
{
"file": "internal/pipeline/bankbasis.go",
"find": "fmt.Fprintf(h, \"width\\x00%d\\x1e\", width)",
"replace": "fmt.Fprintf(h, \"width\\x00%d\\x1e\", width)\n\t\tfmt.Fprintf(h, \"freq\\x00%d\\x1e\", c.Freq)"
}
]
},
{
"id": "BASIS-fp-reads-the-subset-shown-to-the-model",
"why": "the property the whole fingerprint SHAPE exists for. KWIC is capped and takes the FIRST occurrences, and a stratified selection is already a backlog row (449): built over that subset, the fingerprint moves for every book on earth the day anyone turns kwic_per_term or lands the new selection, and each move re-buys a bank. Built over EVERY occurrence it moves only when the source around the surface moves",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestBasisFingerprintIgnoresWhatTheRoleMerelyGUESSED",
"edits": [
{
"file": "internal/pipeline/bankbasis.go",
"find": "for _, w := range terminology.EvidenceWindows(nsource, c.Key, width) {",
"replace": "for _, w := range c.KWIC {"
}
]
},
{
"id": "BASIS-evidence-windows-capped-like-KWIC",
"why": "the same property one layer down, in the pure function. A cap here makes an edit past the third occurrence invisible to the fingerprint, so the engine keeps serving a decision whose evidence has moved — the failure direction that costs quality rather than money, and the one no counter would show. ⚠ THE EDIT IS IN internal/terminology AND THE CATCHER IS IN internal/pipeline, so the entry names the CATCHER's package — the harness runs the test filter there. Pointed at the edited package instead, the filter matches no test and the entry asserts nothing: which is exactly how it was first written, and how tmmutate's own rotted-entry guard caught it",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestBasisFingerprintReadsEveryOccurrenceNotTheFirstFew",
"edits": [
{
"file": "internal/terminology/evidence.go",
"find": "\t\tout = append(out, strings.TrimSpace(string(runes[lo:hi])))",
"replace": "\t\tif len(out) < 3 {\n\t\t\tout = append(out, strings.TrimSpace(string(runes[lo:hi])))\n\t\t}"
}
]
},
{
"id": "BASIS-fp-forgets-the-signed-rows-it-depends-on",
"why": "the book's own law changing under a settled term. CanonConflicts fires on strict containment of a SIGNED source; with the canon out of the hash a signature on a relative leaves the fingerprint unmoved, the term is served from memory, and the rendering decided BEFORE the owner's act keeps shipping. The Canon half is hashed separately so the re-purchase can name its cause instead of arriving as «the source moved»",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestBasisFingerprintNamesTheSignedRowsItDependsOn",
"edits": [
{
"file": "internal/pipeline/bankbasis.go",
"find": "fmt.Fprintf(h, \"canon\\x00%s\\x1e\", canonPart)",
"replace": "_ = canonPart"
}
]
},
{
"id": "BASIS-units-read-a-partial-map-as-unit-zero",
"why": "a zero value that means «no unit» against one that means «unit number zero» — the same integer, and only one is a decision. MergeUnits returns a PARTIAL map and terminology.Batch reads a missing key as a singleton; indexed raw, every unit-less candidate shares unit 0, so ONE unsettled row re-buys all of them. ⚠ MEASURED, not imagined: the pack's own first measurement reported 22 of 69 candidates served where the truth is 65, and the number looked entirely plausible",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestBasisUnitsGiveEveryCandidateAUnitOfItsOwn",
"edits": [
{
"file": "internal/pipeline/bankbasis.go",
"find": "out := make(map[string]int, len(cands))\n\t// Singleton ids are handed out",
"replace": "return merged\n\t//nolint\n\tout := make(map[string]int, len(cands))\n\t// Singleton ids are handed out"
}
]
},
{
"id": "BASIS-predicate-serves-a-row-that-is-not-draft",
"why": "«non-empty dst» is NOT enough and the miner proves it: it produces status:auto WITH a rendering — the raw first-chunk banknote guess — a pair four engine comments declare impossible and no pin guards (row 487). A predicate reading the rendering alone serves an answer nobody consolidated, and the same hole lets an owner-SIGNED row be republished as an engine decision",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestBasisServesOnlyADecidedRow",
"edits": [
{
"file": "internal/pipeline/bankbasis.go",
"find": "if row.Status != \"draft\" || strings.TrimSpace(row.Dst) == \"\" {",
"replace": "if strings.TrimSpace(row.Dst) == \"\" {"
}
]
},
{
"id": "BASIS-unit-rule-dropped",
"why": "a family decided in halves is the chimera co-batching exists to prevent — «old members frozen, a new one asked alone, and the result correlates with the batch boundary perfectly». Without the rule the predicate serves half a series from memory while the rest is re-asked, and the two halves answer to different laws",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestBasisServesAUnitOnlyWhole",
"edits": [
{
"file": "internal/pipeline/bankbasis.go",
"find": "if v.Reason == basisServed && blocked[unitID[c.Key]] {",
"replace": "if false {"
}
]
},
{
"id": "BASIS-signed-row-holds-its-family-open",
"why": "the owner's signature re-buying the family it belongs to. A signed row is settled harder than any draft one, but it carries no basis record (the basis remembers ENGINE decisions), so counted as a hole it blocks its whole unit. Measured on both bought cold runs: the two signed rows were the ONLY blockers, and exempting them moves the saving from 65/69 and 62/66 to 67/69 and 64/66",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestASignedRowDoesNotHoldItsFamilyOpen",
"edits": [
{
"file": "internal/pipeline/bankbasis.go",
"find": "if r := own[c.Key].Reason; r != basisServed && r != basisSigned && r != basisOwnerRow {",
"replace": "if r := own[c.Key].Reason; r != basisServed {"
}
]
},
{
"id": "BASIS-owner-canon-served-as-an-engine-answer",
"why": "the two words the bank ontology keeps apart, merged. The basis is the memory of what the ENGINE decided; handing back the owner's signed rendering as one of its answers republishes his canon as a machine proposal, and «which translations did the human actually approve» stops being answerable — which is the question the whole bank exists for",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestASignedRowDoesNotHoldItsFamilyOpen",
"edits": [
{
"file": "internal/pipeline/bankbasis.go",
"find": "return bankBasisVerdict{Reason: basisSigned}",
"replace": "return bankBasisVerdict{Answer: bankBasisAnswer{Dst: row.Dst}, Reason: basisSigned}"
}
]
},
{
"id": "BASIS-is-a-filter-instead-of-a-source-of-answers",
"why": "⛔ THE PACK'S QUIETEST REGRESSION. Dropping settled candidates from the paid set WITHOUT handing their answer back does not leave the book where it was: attachConsolidatedDst stamps nothing for a term the role did not answer, so the emission falls to the raw first-chunk banknote guess at status auto, or to no rendering at all. The run looks CHEAPER and the bank gets POORER, and nothing goes red — the saving is visible and the loss is silent",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestTheBasisCarriesTheBoughtAnswerRatherThanDroppingIt",
"edits": [
{
"file": "internal/pipeline/terminologist.go",
"find": "for k, a := range basisAnswers {\n\t\tout[k] = a.Dst\n\t}",
"replace": "_ = basisAnswers"
}
]
},
{
"id": "BASIS-classifier-half-of-the-answer-dropped",
"why": "the answer has TWO halves bought on the same money and reaching the row through different doors — the terminologist's rendering and the classifier's type and gender. A basis that carried only the first drops a wire directive the engine has PROMISED since D39.21, on rows nobody will ever be asked about again. ⚠ The pin's fixture runs the classifier ON deliberately: with the phase off this mutation survived, because the comparison was \"\" against \"\"",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestTheBasisCarriesTheBoughtAnswerRatherThanDroppingIt",
"edits": [
{
"file": "internal/pipeline/terminologist.go",
"find": "if a.Gender != \"\" {",
"replace": "if false {"
}
]
},
{
"id": "BASIS-written-before-the-run-reaches-a-boundary",
"why": "a run that dies after the bank roles are paid leaves their checkpoints, and a resume rebuilds the SAME batch composition and replays them for $0. Record the basis before the fork and the crashed run has already stored its decisions: the resume serves them, builds a NARROWER composition, misses every checkpoint addressed by request hash, and buys the whole pass again — money out of a lifetime ceiling for work already done",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestTheBasisIsNotWrittenBeforeTheRunReachesABoundary",
"edits": [
{
"file": "internal/pipeline/terminologist.go",
"find": "\tres.BasisRows = basisRowsToStore(cands, out, classified, gendered, basisFPs, basisRows, basisAmbiguous, basisShape(r.basisWidth(), r.bankRoleProducer()))",
"replace": "\tres.BasisRows = basisRowsToStore(cands, out, classified, gendered, basisFPs, basisRows, basisAmbiguous, basisShape(r.basisWidth(), r.bankRoleProducer()))\n\tif err := r.Store.PutBankBasis(r.Book.BookID, res.BasisRows); err != nil {\n\t\t_ = err\n\t}"
}
]
},
{
"id": "BASIS-store-accepts-an-empty-rendering",
"why": "the guarantee at the WRITE, where a future caller cannot forget it. A basis row with no rendering served back is the same silent loss the mechanism exists to prevent, arriving through its own memory: the emission drops to the raw guess at status auto and the run reads as cheaper",
"package": "./internal/store/",
"battery": true,
"run": "TestBasisStoreRefusesAnEmptyRendering",
"edits": [
{
"file": "internal/store/bankbasis.go",
"find": "if r.SrcKey == \"\" || r.Dst == \"\" || r.FPWhole == \"\" || r.FPVersion == \"\" {",
"replace": "if false {"
}
]
},
{
"id": "BASIS-store-accumulates-where-it-must-replace",
"why": "the guarantee this table does NOT inherit from its neighbour. bank_stop_presented only grows and has no delete on purpose; the basis must OVERWRITE when a term is decided again, or the predicate keeps comparing against evidence the book has moved past and serves an answer that was right two purchases ago",
"package": "./internal/store/",
"battery": true,
"run": "TestBasisStoreReplacesRatherThanAccumulates",
"edits": [
{
"file": "internal/store/bankbasis.go",
"find": "ON CONFLICT(book_id, src_key) DO UPDATE SET",
"replace": "ON CONFLICT(book_id, src_key) DO NOTHING WHERE 0 = (SELECT 0) --"
}
]
},
{
"id": "BASIS-term-window-gap-goes-unreported",
"why": "backlog row 490: the loader refuses two bank rows that OVERLAP and says nothing about two that leave a chapter BETWEEN them — «until_ch 3» then «since_ch 5», and chapter 4 has no law for the term at all. It is not a schema violation and cannot be: the UNIQUE key admits both rows, windowsOverlap permits them, and the spoiler rule then picks neither. The term stops being law for those chapters, the editor is shown nothing, and their drafts render it however they like — inside a book whose whole point is one word per term. The guarantee is taken from the voice sibling and NOT improvised: a deliberate gap is legitimate, so the outcome is a loud line, never a refused load",
"package": "./internal/membank/",
"battery": true,
"run": "TestTermWindowGapsSeesTheHoleTheLoaderCannot",
"edits": [
{
"file": "internal/membank/memvoice.go",
"find": "if win[i].SinceCh > prevUntil+1 {\n\t\t\t\tout = append(out, fmt.Sprintf(\"term %q (sense %q): chapters %d%d have no bank row",
"replace": "if false {\n\t\t\t\tout = append(out, fmt.Sprintf(\"term %q (sense %q): chapters %d%d have no bank row"
}
]
},
{
"id": "BASIS-reaches-a-book-whose-gate-is-off",
"why": "the promise every new mechanism owes the books already in the field. The basis lives on the paid path and the paid path is GATED; a gate whose OFF branch grew a side effect is the quiet way a mechanism reaches books nobody enabled it for — rows in a table for a contour that never ran, and a later purchase serving answers nobody bought. The pin also asserts the run really reached the mining stop first, so its zeros are about a path that was walked",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestABookWithTheGateOffTouchesNoBasisAtAll",
"edits": [
{
"file": "internal/pipeline/bankbasis.go",
"find": "\tt := r.lastTerminology\n\tif t == nil || len(t.BasisRows) == 0 {\n\t\treturn\n\t}",
"replace": "\tt := r.lastTerminology\n\tif t == nil {\n\t\tt = &terminologyResult{BasisRows: []store.BankBasisRow{{SrcKey: \"x\", FPVersion: basisFingerprintVersion, FPWhole: \"h\", Dst: \"d\"}}}\n\t}\n\tif len(t.BasisRows) == 0 {\n\t\treturn\n\t}"
}
]
},
{
"id": "BASIS-banked-type-never-reaches-the-sheet",
"why": "⛔ FOUND BY ADVERSARIAL REVIEW OF THIS PACK, ON THE TREE. The sheet, the stop table and the sidecar's `kind` read Candidate.Type, and applyTypes — the only writer — runs BEFORE the basis answers reach the maps it consults. So the banked type travelled to the auto-bank and NOT to the sheet: in the steady state the row the owner signs by said `place` while the bank row for the same term said `term`. The stamp is deliberately not applyTypes, because that one's return value is published as `reclassified` and a term the classifier never saw must not inflate it",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestTheBankedTypeReachesTheSheetWhenTheBasisAnswers",
"edits": [
{
"file": "internal/pipeline/bankbasis.go",
"find": "\t\tcands[i].Type = a.Type\n\t\tn++",
"replace": "\t\tn++"
}
]
},
{
"id": "BASIS-records-the-owners-signed-rendering",
"why": "⛔ FOUND BY ADVERSARIAL REVIEW. A signed surface still goes to the paid role on purpose (row 447), so its consolidation reaches the recorder — and recording it puts the ENGINE's word into the memory of decisions under a surface whose law is the OWNER's. Lift the signature and the predicate finds a record, sees an unsigned draft row, and serves the engine's rendering as «this book decided it earlier», over his own: exactly the merging of the two words the bank ontology keeps apart, arriving through the door this pack built",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestTheOwnersSignedRowIsNeverRecordedInTheBasis",
"edits": [
{
"file": "internal/pipeline/bankbasis.go",
"find": "if row, inBank := rows[c.Key]; inBank && !membank.IsEngineUnsigned(row) {\n\t\t\tcontinue",
"replace": "if row, inBank := rows[c.Key]; false && inBank && !membank.IsEngineUnsigned(row) {\n\t\t\tcontinue"
}
]
},
{
"id": "BASIS-collapses-two-senses-of-one-surface",
"why": "⛔ FOUND BY ADVERSARIAL REVIEW. The bank's uniqueness key is the FOUR-tuple (src, sense, since_ch, until_ch) — two senses are two laws by design, and a rendering that changes across a spoiler boundary is two rows with different windows — while a candidate carries only a Key. Indexed as out[key]=row, the surface keeps whichever row the store returned LAST (it orders by that tuple, so the latest window wins) and answers for the other: a surface the owner had signed on one window, holding an engine draft on another, served the draft",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestAnAmbiguousSurfaceIsReAskedRatherThanGuessed",
"edits": [
{
"file": "internal/pipeline/bankbasis.go",
"find": "\t\tif len(es) != 1 {\n\t\t\tambiguous[k] = true\n\t\t\tcontinue\n\t\t}",
"replace": "\t\tif false {\n\t\t\tambiguous[k] = true\n\t\t\tcontinue\n\t\t}"
}
]
},
{
"id": "BASIS-width-read-from-the-prompt-knob",
"why": "⛔ FOUND BY ADVERSARIAL REVIEW: this mutation SURVIVED the whole tree before its pin existed. The pack's first pin for the pair datum built a Runner with no pack at all, so only the DEFAULT branch ran and reading kwic_width instead of basis_width went unnoticed — which would make a prompt-shape knob decide which stored decisions survive, and tuning translation quality would re-buy every book's bank out of a lifetime ceiling. No shipping langpack states either key, so nothing else in the tree exercises the pair branch",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestBasisWidthIsReadFromThePairWhenThePairStatesIt",
"edits": [
{
"file": "internal/pipeline/bankbasis.go",
"find": "if pair := r.packTerminology(); pair != nil && pair.BasisWidth > 0 {\n\t\treturn pair.BasisWidth",
"replace": "if pair := r.packTerminology(); pair != nil && pair.KWICWidth > 0 {\n\t\treturn pair.KWICWidth"
}
]
},
{
"id": "BASIS-and-the-bank-filter-claim-the-same-row",
"why": "⛔ FOUND BY ADVERSARIAL REVIEW, reproduced end to end. The two savings are different facts with different sentences on the sheet — «the bank already renders this surface and every draft agreed» against «this book decided it earlier» — and a candidate offered to both carries BOTH marks: the sheet prints two mutually exclusive sentences about one row, the read-out counts it twice, and SettledByBank lifts it out of the contested queue, which is precisely the exemption stopcontest.go refuses for a basis row. ⚠ THE PLANTING IS `&& false` AND NOT `if false`: the latter leaves the loop index unused, the package does not compile, and tmmutate reports «nothing ran» — a non-zero exit that is NOT a catch. Measured on this very entry. ⚠ WHAT THIS MUTATION STILL MEASURES CHANGED WHEN «whose row is this» WAS FIXED, and the entry says so rather than being retired: the two savings can no longer collide on one surface (the filter takes SEED surfaces, the recorder keeps ENGINE rows, and those are disjoint), so the damage is no longer a double MARK but a double COUNT — the predicate reports on candidates nobody offered it, and every re-ask number the run prints is inflated by the other saving. The pin follows the subject",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestASettledRowIsNotAlsoMarkedNeverAsked",
"edits": [
{
"file": "internal/pipeline/bankbasis.go",
"find": "\t\tif !consider[i] {\n\t\t\tcontinue\n\t\t}",
"replace": "\t\tif !consider[i] && false {\n\t\t\tcontinue\n\t\t}"
}
]
},
{
"id": "BASIS-row-accused-of-being-INVENTED",
"why": "⛔ FOUND BY ADVERSARIAL REVIEW: this mutation SURVIVED the whole tree before its pin existed. `Invented` means «the engine produced a rendering no draft proposed» and is a finding about THIS run's drafts; a rendering carried from an earlier purchase was never offered to them, so the flag fires on every settled row and prints «INVENTED (no draft proposed it)» against the book's own established canon, on the sheet the owner signs by",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestTheThreeDeclaredDecisionsAboutABasisRowAreGuarded",
"edits": [
{
"file": "internal/pipeline/mining.go",
"find": "row.Invented = dst != \"\" && !row.SettledByBasis && !proposedByDrafts(dst, c.Variants)",
"replace": "row.Invented = dst != \"\" && !proposedByDrafts(dst, c.Variants)"
}
]
},
{
"id": "BASIS-row-exempted-from-the-contested-queue",
"why": "⛔ FOUND BY ADVERSARIAL REVIEW: SURVIVED the whole tree before its pin existed, against a ⛔-comment written directly above the line refusing exactly this. SettledByBank means «the bank renders the surface and every draft agreed» — genuinely nothing to doubt. A basis row carries a real rendering chosen by a paid role and neither half of that sentence is true of it; exempting it by the resemblance of two field names silences the queue over most of a settled book",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestTheThreeDeclaredDecisionsAboutABasisRowAreGuarded",
"edits": [
{
"file": "internal/pipeline/stopcontest.go",
"find": "\tif r.SettledByBank {",
"replace": "\tif r.SettledByBank || r.SettledByBasis {"
}
]
},
{
"id": "BASIS-stop-table-label-swallowed-on-read-back",
"why": "⛔ FOUND BY ADVERSARIAL REVIEW: SURVIVED the whole tree before its pin existed. Both labels are trailing clauses of one line and the renderer prints NOT ASKED first, so a reader that cuts at the first label it finds swallows the other — and the two really do co-occur. The shipped table then reads back missing a state the sheet shows",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestTheThreeDeclaredDecisionsAboutABasisRowAreGuarded",
"edits": [
{
"file": "internal/pipeline/bankstopparse.go",
"find": "if i := strings.Index(rest, \" SETTLED EARLIER(\"); i >= 0 {",
"replace": "if i := strings.Index(rest, \" NOT ASKED(\"); i >= 0 {\n\t\tr.SettledByBank = true\n\t\trest = rest[:i]\n\t}\n\tif i := strings.Index(rest, \" SETTLED EARLIER(\"); i >= 0 {"
}
]
},
{
"id": "BASIS-evidence-window-differs-from-the-KWIC-window",
"why": "the fingerprint's meaning rests on this equality. EvidenceWindows stopped calling window() for COST — window() re-derives the whole rune view per call, which is quadratic over a book and measured at ×15 time for a ×4 source — so the two now compute the same shape by two routes. Let them drift by one rune and every stored fingerprint stops matching the one computed next purchase: a silent, book-wide re-purchase out of a lifetime budget",
"package": "./internal/terminology/",
"battery": true,
"run": "TestEvidenceWindowsCutsTheSameWindowAsKWIC",
"edits": [
{
"file": "internal/terminology/evidence.go",
"find": "lo := runeAt[at] - width",
"replace": "lo := runeAt[at] - width + 1"
}
]
},
{
"id": "BASIS-evidence-scan-goes-quadratic-again",
"why": "the $0 pass that runs before EVERY purchase. window() declares in its own comment that its inputs are «chunk-sized»; called once per occurrence over the WHOLE book it is quadratic, and a source four times longer took FIFTEEN times as long — minutes on a real volume, plus tens of gigabytes of garbage, all before the first paid call and whether or not anything is saved. A later «simplification» back to window() restores it INVISIBLY: the result stays correct",
"package": "./internal/terminology/",
"battery": true,
"run": "TestEvidenceWindowsDoesNotGrowQUADRATICALLYWithTheBook",
"edits": [
{
"file": "internal/terminology/evidence.go",
"find": "out = append(out, strings.TrimSpace(string(runes[lo:hi])))",
"replace": "out = append(out, window(nsource, at, at+len(key), width))"
}
]
},
{
"id": "BASIS-producer-change-reported-as-a-source-change",
"why": "⛔ F1, FOUND BY ACCEPTANCE: a SILENT QUALITY REGRESSION, not a missing feature. Before the settled basis, improving the terminologist's prompt or moving it to another model missed every checkpoint (RequestHash folds model, effort and snapshot) and the book re-bought its bank from the new producer. With the producer out of the fingerprint a settled row is never asked again no matter who is asking now — a better prompt reaches the unsettled TAIL of every book and nothing else, permanently, and the only exit is bumping the shape, which zeroes every book at once. Improving a bank role's prompt is a direct lever on translationese, goal №1 of this project. ⚠ RE-AIMED: the producer moved OUT of the evidence hash and into the stored SHAPE, because hashed with the evidence it reported every prompt edit as «the source around this term changed» — the wrong cause, told to the operator on every row, about a book nobody had touched. The pin now asks the CLASS and not merely that something moved; its first version asserted movement alone and was green and empty on exactly this",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestAProducerChangeReportsItsOwnCause",
"edits": [
{
"file": "internal/pipeline/bankbasis.go",
"find": "return fmt.Sprintf(\"%s|w%d|p%s\", basisFingerprintVersion, width, producer)",
"replace": "_ = producer\n\treturn fmt.Sprintf(\"%s|w%d\", basisFingerprintVersion, width)"
}
]
},
{
"id": "BASIS-producer-identity-spelled-twice",
"why": "a producer identity assembled at the call site is two identities the day the spellings disagree — the same rule membank.IsEngineUnsigned keeps for «whose row is this», and the rule this pack had already broken once. The classifier rides in it because it authors the TYPE and GENDER halves of every stored answer, and a role that is not configured contributes an empty FIELD rather than vanishing: «off» and «absent» must not hash the same, or turning a phase on would leave every decision it now co-authors untouched. ⚠ THE PLANTING TARGETS THE CLASSIFIER'S CONTRIBUTION rather than deleting a line of the Join: deleting one leaves its variable unused, the package does not compile, and tmmutate reports «nothing ran» — a non-zero exit that is NOT a catch. Measured on this very entry. ⚠ RE-AIMED at the RENDERED prompt: keying on the template's own SHA misses the BRIEF the pair's prompt reads ({{honorifics}}, {{transcription}}, {{venuti}}, {{audience}}, {{title}}), so changing the book's law re-buys both waves through BriefHash while the basis serves renderings decided under the old one. Rendering makes it pair-agnostic by SHAPE rather than by a list of fields in Go",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestTheProducerIdentityIsResolvedInOnePlace",
"edits": [
{
"file": "internal/pipeline/bankbasis.go",
"find": "\tout, err := Render(tpl.System, RenderVars{Book: r.Book})",
"replace": "\tout, err := tpl.System, error(nil)"
}
]
},
{
"id": "BASIS-asks-whose-row-by-a-second-spelling",
"why": "⛔ F2, FOUND BY ACCEPTANCE. The engine has ONE definition of «whose row is this» — membank.IsEngineUnsigned, `Source == \"mined\" && Status != \"approved\"` — with other callers. A private `Status == \"approved\"` is a SECOND spelling, and two spellings are two answers the day they disagree. They already did: a term the OWNER wrote by hand and left unsigned (`source: seed`, `status: draft` — a shape the loader admits and even REQUIRES a rendering for) answered «not approved», so the engine recorded its own consolidation under that surface and served it back as «this book decided it earlier»",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestAnOwnersUNSIGNEDRowIsNotTheEnginesMemoryEither",
"edits": [
{
"file": "internal/pipeline/bankbasis.go",
"find": "if row, inBank := rows[c.Key]; inBank && !membank.IsEngineUnsigned(row) {\n\t\t\tcontinue",
"replace": "if row, inBank := rows[c.Key]; inBank && row.Status == \"approved\" {\n\t\t\tcontinue"
}
]
},
{
"id": "BASIS-width-change-reported-as-a-source-change",
"why": "⛔ D1, FOUND BY ACCEPTANCE against the pack's own order. Hashed only inside the evidence, a change of basis_width moves every fingerprint of every book — and the predicate reports it as `evidence-moved`, «the source around this term changed». That is the WRONG CAUSE for every one of those rows, and the owner's reaction to the two is opposite: one is nothing to do, the other is a knob somebody turned. Carried in the stored SHAPE, the same change is reported by the version check with both widths printed",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestAWidthChangeReportsItsOwnCauseAndNotTheSources",
"edits": [
{
"file": "internal/pipeline/bankbasis.go",
"find": "return fmt.Sprintf(\"%s|w%d|p%s\", basisFingerprintVersion, width, producer)",
"replace": "_ = width\n\treturn fmt.Sprintf(\"%s|p%s\", basisFingerprintVersion, producer)"
}
]
},
{
"id": "BASIS-signature-stop-records-nothing",
"why": "⛔ D2, FOUND BY ACCEPTANCE WITH A CONTROL: removing the write at `run-finished` turned the package RED, removing it at the SIGNATURE STOP left it entirely `ok`. The two boundaries are not interchangeable and the stop is the one that cannot be reached from the other — it returns as an ERROR VALUE, so a run that stops for the owner's signature never arrives at `run-finished`. Lose the write there and the resume after the owner signs re-buys the ENTIRE bank pass out of a lifetime ceiling, while every fixture that only auto-continues stays green",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestTheSignatureStopWritesTheBasisToo",
"edits": [
{
"file": "internal/pipeline/mining.go",
"find": "\tr.writeBankBasis(ctx, \"bank-mining/signature-stop\")",
"replace": ""
}
]
},
{
"id": "BASIS-serves-an-answer-the-bank-contradicts",
"why": "⛔ D3. The predicate's sentence is «this book decided this AND the bank still holds that decision», and only the first half was checked: the stored answer was served and travelled into the delta, overwriting whatever the bank held, with the sheet reporting the row as settled earlier. ⚠ The population is NAMED rather than claimed — on the run that writes them the two agree by construction, so the reachable divergence is a hand edit of the auto-bank FILE, which the ontology lists among the SOURCES. The comparison folds target forms, so a case difference is one decision and not a re-purchase",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestABankRowThatDisagreesWithTheMemoryIsReAsked",
"edits": [
{
"file": "internal/pipeline/bankbasis.go",
"find": "if text.NormalizeTargetForm(row.Dst) != text.NormalizeTargetForm(rec.Answer.Dst) {\n\t\treturn bankBasisVerdict{Reason: basisDiverged}\n\t}",
"replace": ""
}
]
},
{
"id": "BASIS-completeness-line-states-the-wrong-cause",
"why": "⛔ D5, FOUND BY ACCEPTANCE. «The paid role was asked for nothing» now has TWO reasons and they are different facts; the single sentence asserted the FIRST for both. For a book answered from the memory of decisions it was false in BOTH halves — the bank holds no seed surface for those terms and the drafts were never asked to agree with anything. A message that states the wrong cause is worse than one that states none, and D39.93 п.2 refuses it next door. The pin was maintained together with the sentence, and the maintenance is declared",
"package": "./cmd/tmctl/",
"battery": true,
"run": "TestTheSigningScreenSaysHowCompleteTheBankIs",
"edits": [
{
"file": "cmd/tmctl/render.go",
"find": "case c.SettledEarlier > 0 && c.NeverAsked > 0:",
"replace": "case false:"
}
]
},
{
"id": "BASIS-shape-mismatch-reported-as-never-decided",
"why": "a record whose RULE moved must be kept, not dropped. Dropped, it leaves no record — and no record reads as `new`, «this surface has never been decided», which is false of every one of those rows. The summary line would state the right cause once while every row carried the wrong one, and the two would disagree in the same run. ⚠ RE-AIMED at the extracted loading rule: inside bankBasisPass it needs a store, a book and a runner, and a money rule that can only be exercised end to end is one nobody plants a mutation into — the first version of this entry SURVIVED for exactly that reason",
"package": "./internal/pipeline/",
"battery": true,
"run": "TestARecordWhoseRuleMovedIsKeptAndNamed",
"edits": [
{
"file": "internal/pipeline/bankbasis.go",
"find": "\t\t\told[row.FPVersion]++\n\t\t\tchanged++\n\t\t}",
"replace": "\t\t\told[row.FPVersion]++\n\t\t\tchanged++\n\t\t\tcontinue\n\t\t}"
}
]
}
]