textmachine/backend/cmd/tmmutate/mutations.json

1141 lines
50 KiB
JSON

[
{
"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/manifest/seed-lint/bank-apply) must not demand provider keys at all (D20.4)",
"replace": "The $0 read commands (report/status/export/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.escalation\n\t\tFROM checkpoints c JOIN jobs j ON j.id = c.job_id",
"replace": "\t\t 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) {"
}
]
}
]