Land sanitizer fix D33.1: trailing gemini-leak now caught, false-positive broken-word class removed, minor narrowings, golden version-fold verified; re-run sanitizer blocker cleared
This commit is contained in:
parent
8c3d387639
commit
47996f4c71
5 changed files with 201 additions and 173 deletions
|
|
@ -26,20 +26,24 @@ import (
|
|||
// 2. trailing note/edit block — appended «Примечание:/Внесённые правки:/Что изменено:» meta
|
||||
// 3. markdown ### header — «### Глава 1» (8/54 finals of stage A — D29 finding)
|
||||
// 4. Latin-script insertion — an untranslated Latin phrase/heavy Latin in the ru output
|
||||
// 5. broken word form — homoglyph-mixed or invalid-sign / split-duplicated tokens
|
||||
// 5. broken word form — homoglyph-mixed token or an invalid Cyrillic sign bigram
|
||||
//
|
||||
// HONEST recall gap (documented, precision over recall): the broken-word class catches only
|
||||
// the DETERMINISTIC signatures (invalid Cyrillic sign bigrams, mixed Cyrillic/Latin token,
|
||||
// junction-duplicated split). A word broken WITHOUT an invalid character («Первок предок»
|
||||
// split into two individually-valid tokens) or a grammatical-but-wrong form («валуне») is
|
||||
// NOT offline-detectable without a morphology/dictionary pass (Ф2) — left silent.
|
||||
// the two ZERO-false-positive signatures (invalid Cyrillic sign bigrams, mixed Cyrillic/Latin
|
||||
// token). The junction-duplication split heuristic («Первопред предок») was REMOVED (D33.1б): it
|
||||
// false-flagged ordinary prose sharing a morphemic boundary. A word broken WITHOUT an invalid
|
||||
// character («Первок предок» split into two individually-valid tokens) or a grammatical-but-wrong
|
||||
// form («валуне») is NOT offline-detectable without a morphology/dictionary pass (Ф2) — left silent.
|
||||
|
||||
// sanitizerVersion versions the rules below (folded into the snapshot when the gate is
|
||||
// enabled, like cheapGateVersion/coverageGateVersion): editing any pattern shifts the
|
||||
// resolved disposition of flagged chunks, so a bump is a loud --resnapshot. [D15.2 note:
|
||||
// this is a VERDICT version — once content-addressed resume lands it moves to
|
||||
// verdictSnapshotID and a rule edit re-classifies free instead of re-paying the book.]
|
||||
const sanitizerVersion = "sanitizer-v1"
|
||||
// v2 (D33.1/33.2): tail edit-summary «Основные правки для справки:» now flags; the
|
||||
// junction-duplication split detector was removed (false-flagged prose); markdown/heavy-Latin
|
||||
// narrowed. A verdict-axis change → loud --resnapshot + golden re-capture (invariant №8).
|
||||
const sanitizerVersion = "sanitizer-v2"
|
||||
|
||||
// sanitizer tuning constants (versioned by sanitizerVersion).
|
||||
const (
|
||||
|
|
@ -59,10 +63,6 @@ const (
|
|||
// short chunk with one long Latin brand name does not trip the share alone).
|
||||
latinHeavyShare = 0.25
|
||||
latinHeavyTokens = 5
|
||||
// junctionOverlap: minimal suffix==prefix overlap between two adjacent Cyrillic tokens
|
||||
// to call it a split-duplication artifact («Первопред предок»); exact duplicates
|
||||
// (emphatic «хорошо хорошо») are excluded.
|
||||
junctionOverlap = 4
|
||||
)
|
||||
|
||||
// sanitizerResult is the per-chunk outcome: a count per class plus deterministic detail.
|
||||
|
|
@ -129,6 +129,7 @@ func sanitizeOutput(text string) sanitizerResult {
|
|||
// 2. the phrase must be a genuine TRANSLATION/EDIT service label, not merely «lead + common
|
||||
// noun»: either an edit-adjective (отредактированн/исправленн/улучшенн) + a перевод/текст/
|
||||
// вариант noun, or «перевод фрагмента/текста/…», or «ниже приведён … перевод/текст».
|
||||
//
|
||||
// Go RE2 \w/\b are ASCII-only, so Cyrillic uses [а-яё].
|
||||
var leadingPreamblePatterns = []*regexp.Regexp{
|
||||
// «Вот/Представляю/Привожу … отредактированный/исправленный перевод/текст/вариант …:»
|
||||
|
|
@ -164,11 +165,15 @@ func detectLeadingPreamble(text string) string {
|
|||
var trailingNoteRE = regexp.MustCompile(`(?i)^[*_>\s-]{0,4}(?:(?:примечани[ея]|заметк[аи]|комментари[йяю]|пояснени[ея]|сноск[аи])\s*:|(?:примечани[ея]|заметк[аи]|комментари[йяю])\s+(?:переводчик|редактор)[а-яё]*|прим\.\s*(?:перев|ред)\.?)`)
|
||||
|
||||
// editMetaAnywhereRE matches UNAMBIGUOUS editor meta-commentary that is a defect wherever it
|
||||
// appears (not only trailing): «Внесённые правки:», «Что изменено:», «Список правок:». The
|
||||
// generic «Изменения:/Правки:» alone were REMOVED (адверсариальное ревью — «Изменения — вот что
|
||||
// пугало его.» / «Правка — дело тонкое.» are common narrative openers), keeping only the
|
||||
// editor-specific compound phrases that never occur in prose.
|
||||
var editMetaAnywhereRE = regexp.MustCompile(`(?im)^[*_>\s-]{0,4}(?:(?:внесённ|внесен)[а-яё]+\s+правк|что\s+(?:было\s+)?(?:изменен|исправлен)|список\s+(?:правок|изменений)|список\s+внесённых)`)
|
||||
// appears (not only trailing): «Внесённые правки:», «Что изменено:», «Список правок:», and the
|
||||
// gemini tail leak «Основные правки для справки: …» (D33.1а — the A5/5_1 defect the gate exists
|
||||
// to catch, exp12:229: the leading-preamble rule caught the head form «Вот отредактированный
|
||||
// перевод:» but NOT this trailing edit-summary). The generic «Изменения:/Правки:» alone were
|
||||
// REMOVED (адверсариальное ревью — «Изменения — вот что пугало его.» / «Правка — дело тонкое.»
|
||||
// are common narrative openers), keeping only editor-specific compounds that never occur in prose.
|
||||
// «основн…правк» is gated to «… для справки» OR a colon so a bare narrative «Основные правки внёс
|
||||
// редактор» (no summary label) does not fire.
|
||||
var editMetaAnywhereRE = regexp.MustCompile(`(?im)^[*_>\s-]{0,4}(?:(?:внесённ|внесен)[а-яё]+\s+правк|основн[а-яё]+\s+правк[а-яё]*(?:\s+для\s+справк[а-яё]+|\s*:)|что\s+(?:было\s+)?(?:изменен|исправлен)|список\s+(?:правок|изменений)|список\s+внесённых)`)
|
||||
|
||||
func detectTrailingNote(text string) string {
|
||||
if loc := editMetaAnywhereRE.FindStringIndex(text); loc != nil {
|
||||
|
|
@ -190,8 +195,10 @@ func detectTrailingNote(text string) string {
|
|||
// --- 3. markdown ### header -----------------------------------------------------
|
||||
|
||||
// markdownHeaderRE matches a markdown ATX header line («### Глава», «# Title»): 1–6 hashes,
|
||||
// a space, then non-space content. «#1» / «№5» / a lone «#» do not match (no space+text).
|
||||
var markdownHeaderRE = regexp.MustCompile(`(?m)^\s{0,3}#{1,6}\s+\S`)
|
||||
// a space, then a LETTER or DIGIT. «#1» / «№5» / a lone «#» do not match (no space+text); and
|
||||
// (D33.2) a decorative scene-break rendered with hashes — «# # #», «## ***», «### ---» — no
|
||||
// longer matches, since the char after the hashes is punctuation, not a header word/number.
|
||||
var markdownHeaderRE = regexp.MustCompile(`(?m)^\s{0,3}#{1,6}\s+[\p{L}\p{Nd}]`)
|
||||
|
||||
func detectMarkdownHeaders(text string) (int, []string) {
|
||||
var det []string
|
||||
|
|
@ -216,7 +223,7 @@ func detectMarkdownHeaders(text string) (int, []string) {
|
|||
// handful of Latin proper names stays silent.
|
||||
func detectLatinInsertion(text string) string {
|
||||
toks := scriptTokens(text)
|
||||
maxRun, run, latTokens := 0, 0, 0
|
||||
maxRun, run, heavyLatTokens := 0, 0, 0
|
||||
for _, tk := range toks {
|
||||
switch {
|
||||
case tk.lat:
|
||||
|
|
@ -225,7 +232,14 @@ func detectLatinInsertion(text string) string {
|
|||
} else {
|
||||
run = 1 // phrase start (digit/punct separator or a non-Latin predecessor)
|
||||
}
|
||||
latTokens++
|
||||
// Heavy-Latin count EXCLUDES capitalized/brand tokens (D33.2): «iPhone», «iPad»,
|
||||
// «MacBook», «Google» are legit proper nouns, so a list of 5+ brands must not trip the
|
||||
// heavy-share gate. A genuinely leaked English clause is lowercase past its first word,
|
||||
// so it still clears latinHeavyTokens (and a real multi-word Latin PHRASE is caught by
|
||||
// maxRun below, which still counts every Latin token).
|
||||
if !hasUpperLatin(tk.text) {
|
||||
heavyLatTokens++
|
||||
}
|
||||
if run > maxRun {
|
||||
maxRun = run
|
||||
}
|
||||
|
|
@ -245,12 +259,23 @@ func detectLatinInsertion(text string) string {
|
|||
}
|
||||
}
|
||||
total := latinLetters + cyrLetters
|
||||
if total > 0 && latTokens >= latinHeavyTokens && float64(latinLetters)/float64(total) >= latinHeavyShare {
|
||||
if total > 0 && heavyLatTokens >= latinHeavyTokens && float64(latinLetters)/float64(total) >= latinHeavyShare {
|
||||
return "латиница-врезки: тяжёлая доля латиницы в ru-выходе"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// hasUpperLatin reports whether s contains an uppercase Latin letter — the brand/proper-noun
|
||||
// signature («iPhone», «MacBook», «Google») excluded from the heavy-Latin token count (D33.2).
|
||||
func hasUpperLatin(s string) bool {
|
||||
for _, ru := range s {
|
||||
if unicode.Is(unicode.Latin, ru) && unicode.IsUpper(ru) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// --- 5. broken word forms -------------------------------------------------------
|
||||
|
||||
// invalidSignRE matches Cyrillic sign bigrams that never occur in valid Russian: a hard/soft
|
||||
|
|
@ -274,23 +299,20 @@ func detectBrokenWords(text string) (int, []string) {
|
|||
if invalidSignRE.MatchString(text) {
|
||||
add("невалидная кириллическая биграмма (мягкий/твёрдый знак в начале слова или подряд)")
|
||||
}
|
||||
// (b) mixed Cyrillic+Latin within one letter-run token (homoglyph artifact) and
|
||||
// (c) junction-duplicated adjacent split — walk the letter tokens once.
|
||||
toks := scriptTokens(text)
|
||||
for _, tk := range toks {
|
||||
// (b) mixed Cyrillic+Latin within one letter-run token (homoglyph artifact).
|
||||
// NOTE: the junction-duplication split detector («Первопред предок») was REMOVED (D33.1б).
|
||||
// It fired identically on ordinary prose whose adjacent tokens merely share a ≥4-rune
|
||||
// morphemic boundary («около колонны/колодца», «стало талой» — «около» is a frequent
|
||||
// preposition → flag-storm on 25 legit chapters), while its only synthetic target had an
|
||||
// overlap fraction (4/9) INDISTINGUISHABLE from those false positives (4/5): no threshold on
|
||||
// overlap length or share separates them, and the canonical «Первок предок» was never caught
|
||||
// anyway (recall gap — TestSanitizerBrokenWordRecallGap). Deterministic split-duplication with
|
||||
// no invalid sign / homoglyph needs a morphology pass (Ф2), so it stays silent here.
|
||||
for _, tk := range scriptTokens(text) {
|
||||
if tk.mixed {
|
||||
add("смешение кириллицы и латиницы в одном слове (гомоглиф): " + preview(tk.text))
|
||||
}
|
||||
}
|
||||
for i := 1; i < len(toks); i++ {
|
||||
if !toks[i].adjacent {
|
||||
continue
|
||||
}
|
||||
a, b := toks[i-1], toks[i]
|
||||
if a.cyr && b.cyr && a.text != b.text && junctionDuplicated(a.text, b.text) {
|
||||
add("похоже на разорванное/сдвоенное слово: " + preview(a.text+" "+b.text))
|
||||
}
|
||||
}
|
||||
return len(det), det
|
||||
}
|
||||
|
||||
|
|
@ -346,39 +368,6 @@ func scriptTokens(text string) []scriptToken {
|
|||
return out
|
||||
}
|
||||
|
||||
// junctionDuplicated reports whether adjacent tokens a, b share a PROPER suffix==prefix
|
||||
// overlap of ≥ junctionOverlap runes (a split-duplication artifact like «Первопред предок»,
|
||||
// overlap «пред»). CONTAINMENT is EXCLUDED (адверсариальное ревью major): if one token is a
|
||||
// prefix of the other («старик старика», «город города» — a noun + its own inflection, i.e.
|
||||
// legit polyptoton), the suffix==prefix loop would match at the containment length and
|
||||
// false-flag it. A true broken split has a MID overlap where NEITHER token contains the
|
||||
// other. Both must be reasonably long so a short common ending does not trip it.
|
||||
func junctionDuplicated(a, b string) bool {
|
||||
al := []rune(strings.ToLower(a))
|
||||
bl := []rune(strings.ToLower(b))
|
||||
if len(al) < junctionOverlap+1 || len(bl) < junctionOverlap+1 {
|
||||
return false
|
||||
}
|
||||
if strings.HasPrefix(string(bl), string(al)) || strings.HasPrefix(string(al), string(bl)) {
|
||||
return false // containment = polyptoton (word + its inflection), not a broken split
|
||||
}
|
||||
maxK := len(al)
|
||||
if len(bl) < maxK {
|
||||
maxK = len(bl)
|
||||
}
|
||||
// A proper overlap cannot equal a whole token (that would be containment, excluded above),
|
||||
// so cap the search below the shorter length.
|
||||
if maxK > 0 {
|
||||
maxK--
|
||||
}
|
||||
for k := maxK; k >= junctionOverlap; k-- {
|
||||
if runesEqual(al[len(al)-k:], bl[:k]) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// --- shared helpers -------------------------------------------------------------
|
||||
|
||||
func nonEmptyLines(text string) []string {
|
||||
|
|
|
|||
|
|
@ -28,16 +28,16 @@ func TestSanitizerLeadingPreamble(t *testing.T) {
|
|||
clean := []string{
|
||||
"Судзуки шёл по коридорам Академии магии, вспоминая вчерашнюю лекцию.",
|
||||
"Вот и настал тот день, которого он так ждал.", // «Вот и…» narrative — no service phrase
|
||||
"Вот дом стоял на холме, окружённый старыми соснами.", // «Вот дом…»
|
||||
"— Вот твой перевод, — сказал он и протянул конверт.", // dialogue about a translation, not a preamble label
|
||||
"Перевод стрелки часов занял у него всё утро.", // «Перевод» as a common noun, no service label
|
||||
"Ниже по реке стоял старый мост, к которому вела тропа.", // «Ниже…» geographic
|
||||
"Вот дом стоял на холме, окружённый старыми соснами.", // «Вот дом…»
|
||||
"— Вот твой перевод, — сказал он и протянул конверт.", // dialogue about a translation, not a preamble label
|
||||
"Перевод стрелки часов занял у него всё утро.", // «Перевод» as a common noun, no service label
|
||||
"Ниже по реке стоял старый мост, к которому вела тропа.", // «Ниже…» geographic
|
||||
// адверсариальное ревью false positives — must NOT fire (em-dash terminator + common nouns):
|
||||
"Вот такой вариант развития событий — самый вероятный.", // вот + вариант + em-dash, no edit-adjective
|
||||
"Ниже текста была подпись — размашистая.", // ниже + текст + em-dash, not «ниже приведён … перевод:»
|
||||
"Вот новая версия карты — с пометками отца.", // вот + версия + em-dash
|
||||
"Итоговый текст письма — три строки.", // итоговый + текст + em-dash
|
||||
"Вот его вариант: он молча ушёл.", // вот + вариант + COLON, but no edit-adjective / service phrase
|
||||
"Вот такой вариант развития событий — самый вероятный.", // вот + вариант + em-dash, no edit-adjective
|
||||
"Ниже текста была подпись — размашистая.", // ниже + текст + em-dash, not «ниже приведён … перевод:»
|
||||
"Вот новая версия карты — с пометками отца.", // вот + версия + em-dash
|
||||
"Итоговый текст письма — три строки.", // итоговый + текст + em-dash
|
||||
"Вот его вариант: он молча ушёл.", // вот + вариант + COLON, but no edit-adjective / service phrase
|
||||
}
|
||||
for _, s := range clean {
|
||||
if got := sanitizeOutput(s); got.Preamble != 0 {
|
||||
|
|
@ -54,6 +54,11 @@ func TestSanitizerTrailingNote(t *testing.T) {
|
|||
"Текст главы.\n\n*Примечание переводчика:* здесь игра слов.",
|
||||
"Финал сцены.\n\nЗаметки редактора: стиль приведён к норме.",
|
||||
"Список правок: 1) термины; 2) вёрстка.\nТекст главы дальше.", // edit-meta anywhere
|
||||
// D33.1а — the gemini A5/5_1 TAIL leak (exp12:229): the head-preamble rule missed it.
|
||||
// Reproduces the leaked block STRUCTURE (header + edit list), not the copyrighted chapter.
|
||||
"Судзуки закрыл дверь книгохранилища и медленно пошёл прочь.\n\n" +
|
||||
"Основные правки для справки:\n- унифицированы термины культивации;\n- «фракции» заменены на «школы».",
|
||||
"Текст главы.\n\nОсновные правки: приведены имена к глоссарию.", // colon-header variant
|
||||
}
|
||||
for _, s := range fire {
|
||||
if got := sanitizeOutput(s); got.TrailingNote == 0 {
|
||||
|
|
@ -63,16 +68,17 @@ func TestSanitizerTrailingNote(t *testing.T) {
|
|||
clean := []string{
|
||||
"Судзуки открыл дверь и вошёл в тёмный зал, где ждала тишина.",
|
||||
"Примечательно, что никто не заметил его исчезновения в ту ночь.", // «Примечательно» ≠ «Примечание:»
|
||||
"Он оставил заметку на столе и вышел, не оглядываясь назад.", // «заметку» mid-narrative, not a header
|
||||
"— Что изменилось? — спросил он, оглядывая пустую комнату.", // dialogue, not «Что изменено:»
|
||||
"Он оставил заметку на столе и вышел, не оглядываясь назад.", // «заметку» mid-narrative, not a header
|
||||
"— Что изменилось? — спросил он, оглядывая пустую комнату.", // dialogue, not «Что изменено:»
|
||||
// адверсариальное ревью false positives — ordinary narrative nouns/gerunds ending a chapter:
|
||||
"Комментатор захлёбывался от восторга, махая руками над головой.", // «Комментатор» ≠ «Комментарий:»
|
||||
"Комментируя случившееся, старик лишь развёл руками в тишине.", // «Комментируя» gerund
|
||||
"Заметка белела на столе, и никто не решался её тронуть.", // «Заметка» + no colon
|
||||
"Пояснения не требовалось: всё было ясно без единого слова.", // «Пояснения» + no colon (the colon comes later)
|
||||
"Сноска в конце страницы объясняла древний обычай клана.", // «Сноска» narrative subject
|
||||
"Изменения — вот что пугало его больше всего на этом свете.", // «Изменения —» common narrative opener
|
||||
"Правка — дело тонкое, и старый мастер знал это лучше всех.", // «Правка —» aphorism
|
||||
"Комментатор захлёбывался от восторга, махая руками над головой.", // «Комментатор» ≠ «Комментарий:»
|
||||
"Комментируя случившееся, старик лишь развёл руками в тишине.", // «Комментируя» gerund
|
||||
"Заметка белела на столе, и никто не решался её тронуть.", // «Заметка» + no colon
|
||||
"Пояснения не требовалось: всё было ясно без единого слова.", // «Пояснения» + no colon (the colon comes later)
|
||||
"Сноска в конце страницы объясняла древний обычай клана.", // «Сноска» narrative subject
|
||||
"Изменения — вот что пугало его больше всего на этом свете.", // «Изменения —» common narrative opener
|
||||
"Правка — дело тонкое, и старый мастер знал это лучше всех.", // «Правка —» aphorism
|
||||
"Основные правки внёс редактор газеты, и статья пошла в набор.", // «Основные правки» + no «для справки»/colon (D33.1а precision guard)
|
||||
}
|
||||
for _, s := range clean {
|
||||
if got := sanitizeOutput(s); got.TrailingNote != 0 {
|
||||
|
|
@ -86,6 +92,7 @@ func TestSanitizerMarkdownHeader(t *testing.T) {
|
|||
"### Глава 1\n\nСудзуки шёл по коридору.",
|
||||
"# Пролог\n\nТекст.",
|
||||
"Текст первой сцены.\n\n## Часть вторая\n\nПродолжение.",
|
||||
"### 1. Вступление\n\nТекст.", // digit after hashes is still a header (D33.2)
|
||||
}
|
||||
for _, s := range fire {
|
||||
if got := sanitizeOutput(s); got.MarkdownHeader == 0 {
|
||||
|
|
@ -93,10 +100,15 @@ func TestSanitizerMarkdownHeader(t *testing.T) {
|
|||
}
|
||||
}
|
||||
clean := []string{
|
||||
"Он купил дом №5 на этой улице за бесценок прошлой весной.", // «№5» not a header
|
||||
"Комната #1 была заперта, и ключа ни у кого не нашлось.", // «#1» no space+text
|
||||
"Язык C# он выучил ещё в университете, но давно забросил.", // «C#» mid-line
|
||||
"Он купил дом №5 на этой улице за бесценок прошлой весной.", // «№5» not a header
|
||||
"Комната #1 была заперта, и ключа ни у кого не нашлось.", // «#1» no space+text
|
||||
"Язык C# он выучил ещё в университете, но давно забросил.", // «C#» mid-line
|
||||
"Судзуки шёл по коридорам, вспоминая вчерашнюю долгую лекцию.",
|
||||
// D33.2 — decorative scene-breaks rendered with hashes: punctuation after the hashes,
|
||||
// not a header word/number → must NOT fire.
|
||||
"Сцена оборвалась.\n\n# # #\n\nНачалась новая.", // hash-spaced scene break
|
||||
"Он умолк.\n\n## ***\n\nУтро выдалось ясным.", // hashes then asterisks
|
||||
"Конец главы.\n\n### ---\n\nСледующий день.", // hashes then dashes
|
||||
}
|
||||
for _, s := range clean {
|
||||
if got := sanitizeOutput(s); got.MarkdownHeader != 0 {
|
||||
|
|
@ -108,7 +120,7 @@ func TestSanitizerMarkdownHeader(t *testing.T) {
|
|||
func TestSanitizerLatinInsertion(t *testing.T) {
|
||||
fire := []string{
|
||||
"Судзуки открыл книгу и прочитал: the quick brown fox jumps over.", // ≥4-word latin phrase
|
||||
"He walked into the ancient library at dawn and found nothing.", // whole latin sentence
|
||||
"He walked into the ancient library at dawn and found nothing.", // whole latin sentence
|
||||
}
|
||||
for _, s := range fire {
|
||||
if got := sanitizeOutput(s); got.LatinInsert == 0 {
|
||||
|
|
@ -117,11 +129,14 @@ func TestSanitizerLatinInsertion(t *testing.T) {
|
|||
}
|
||||
clean := []string{
|
||||
"Судзуки купил iPhone и MacBook, чтобы работать в дороге по ночам.", // 2 latin brand names
|
||||
"На экране светилась надпись Google, и он нажал на неё пальцем.", // single latin name
|
||||
"Он listened внимательно.", // 1 stray latin word
|
||||
"На экране светилась надпись Google, и он нажал на неё пальцем.", // single latin name
|
||||
"Он listened внимательно.", // 1 stray latin word
|
||||
"Судзуки шёл по коридорам Академии магии, вспоминая вчерашнюю лекцию.",
|
||||
"Идентификатор 138fd5c384e3 и код a1b2c3d4e5f6 записаны в журнале.", // hex/id: single-letter latin tokens separated by digits — NOT a phrase
|
||||
"На гербе была выбита надпись: sic transit gloria mundi.", // 4-word quoted Latin motto — legit preserved (адверсариальное ревью)
|
||||
"На гербе была выбита надпись: sic transit gloria mundi.", // 4-word quoted Latin motto — legit preserved (адверсариальное ревью)
|
||||
// D33.2 — a list of 5+ capitalized brands is legit proper nouns, not a Latin leak: the
|
||||
// heavy-count excludes capitalized tokens (this fired under the pre-D33.2 heavy-share gate).
|
||||
"Он купил iPhone, iPad, MacBook, Apple Watch и Google Pixel вчера.",
|
||||
}
|
||||
for _, s := range clean {
|
||||
if got := sanitizeOutput(s); got.LatinInsert != 0 {
|
||||
|
|
@ -132,9 +147,8 @@ func TestSanitizerLatinInsertion(t *testing.T) {
|
|||
|
||||
func TestSanitizerBrokenWord(t *testing.T) {
|
||||
fire := []string{
|
||||
"Стольь высокая башня терялась в облаках над городом.", // doubled soft sign ьь
|
||||
"Он вошёл в ьзал и замер на пороге, не решаясь шагнуть.", // soft sign word-initial
|
||||
"Древний Первопред предок восстал из пепла забытых веков.", // junction-duplicated split «Первопред|предок»
|
||||
"Стольь высокая башня терялась в облаках над городом.", // doubled soft sign ьь
|
||||
"Он вошёл в ьзал и замер на пороге, не решаясь шагнуть.", // soft sign word-initial
|
||||
}
|
||||
for _, s := range fire {
|
||||
if got := sanitizeOutput(s); got.BrokenWord == 0 {
|
||||
|
|
@ -148,13 +162,18 @@ func TestSanitizerBrokenWord(t *testing.T) {
|
|||
clean := []string{
|
||||
"Судзуки шёл по коридорам Академии магии, вспоминая вчерашнюю лекцию.",
|
||||
"— Хорошо, хорошо, — устало ответил он, поднимая обе руки вверх.", // emphatic exact repeat, NOT a split
|
||||
"Молоко около дома скисло за одну жаркую летнюю ночь под навесом.", // adjacent words, no ≥4 junction overlap
|
||||
"На валуне у реки сидел одинокий путник в сером плаще.", // «валуне» is a VALID form (recall gap)
|
||||
"Молоко около дома скисло за одну жаркую летнюю ночь под навесом.", // adjacent words
|
||||
"На валуне у реки сидел одинокий путник в сером плаще.", // «валуне» is a VALID form (recall gap)
|
||||
// адверсариальное ревью false positives:
|
||||
"Старик старика видел издалека, но узнал не сразу в тумане.", // polyptoton (старик + старика): containment, NOT a split
|
||||
"Город города не выдаёт — так говаривал его дед у очага.", // город + города: containment
|
||||
"Буква ъ раньше называлась ером и стояла в конце многих слов.", // metalinguistic mention of the letter ъ (standalone)
|
||||
"Хорошо хорошо всё это выглядело только со стороны, издалека.", // capitalized emphatic repeat (case-differing) — containment excludes it
|
||||
"Старик старика видел издалека, но узнал не сразу в тумане.", // polyptoton (старик + старика)
|
||||
"Город города не выдаёт — так говаривал его дед у очага.", // город + города
|
||||
"Буква ъ раньше называлась ером и стояла в конце многих слов.", // metalinguistic mention of the letter ъ (standalone)
|
||||
"Хорошо хорошо всё это выглядело только со стороны, издалека.", // capitalized emphatic repeat
|
||||
// D33.1б — the removed junction-duplication detector false-flagged these: adjacent tokens
|
||||
// sharing an incidental ≥4-rune morphemic boundary («коло», «тало»), NOT a broken split.
|
||||
"Он остановился около колонны и поднял голову к тёмному своду.", // «около колонны» — overlap «коло», no containment
|
||||
"Путник склонился около колодца и зачерпнул ледяной воды.", // «около колодца» — overlap «коло»
|
||||
"К утру всё стало талой водой и растеклось по камням двора.", // «стало талой» — overlap «тало»
|
||||
}
|
||||
for _, s := range clean {
|
||||
if got := sanitizeOutput(s); got.BrokenWord != 0 {
|
||||
|
|
@ -165,11 +184,11 @@ func TestSanitizerBrokenWord(t *testing.T) {
|
|||
|
||||
// TestSanitizerBrokenWordRecallGap documents the honest boundary of the DETERMINISTIC
|
||||
// minimum (D30.3: precision over recall, «это ФЛАГГЕР»): a word split into two
|
||||
// individually-valid tokens with NO invalid sign, NO homoglyph and NO ≥4-rune junction
|
||||
// overlap — the bare «Первок предок» from exp12 — is NOT offline-detectable without a
|
||||
// morphology/dictionary pass (Ф2). It is caught only when the split leaves a junction
|
||||
// overlap («Первопред предок») or an invalid character. This test PINS that gap so a future
|
||||
// stronger heuristic is a conscious change, not an accident.
|
||||
// individually-valid tokens with NO invalid sign and NO homoglyph — the bare «Первок предок»
|
||||
// from exp12 — is NOT offline-detectable without a morphology/dictionary pass (Ф2). Since the
|
||||
// junction-duplication heuristic was removed (D33.1б: it false-flagged prose), such a split is
|
||||
// caught only when it leaves an invalid character or a mixed-script token. This test PINS that
|
||||
// gap so a future morphology-based detector is a conscious change, not an accident.
|
||||
func TestSanitizerBrokenWordRecallGap(t *testing.T) {
|
||||
if got := sanitizeOutput("Первок предок восстал из пепла забытых веков."); got.BrokenWord != 0 {
|
||||
t.Errorf("unexpected: the pure-orthographic split «Первок предок» is documented as a recall gap, but it fired: %v", got.Detail)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
==== run 1 (fresh) ====
|
||||
snapshot_id: c3d6d1f3768cf42a3e0b175e0280ff9b242c5596271a49e6fbe9e04e01dc345c
|
||||
snapshot_payload: {"brief_hash":"c2021b1b5e6c20f6084e425b9a70bdc5f682801be347a57eb1c591deb8cab0df","chunker_version":"chunker-v4-utf8-quotedepth","estimator_version":"estimator-v0","max_tokens_policy":"maxtok-v1-double-per-attempt","classifier_version":"classify-v1-refusal+echo015+loop","pipeline_core":"C1","max_output_ratio":2,"min_max_tokens":512,"context_assembly":{"glossary_injection":"selective","glossary_token_budget":800,"stm_depth":0,"overlap_tokens":0,"cache_ttl":""},"memory_version":"cee708b1c530789a0d07f88902051fe0a9af49ad3b0706b230dbe6d503fc3cd9","postcheck_gate":false,"coverage":{"enabled":false},"style_check_version":"cheapgate-v2","sanitizer":{"enabled":true,"version":"sanitizer-v1"},"stages":[{"name":"draft","role":"translator","model":"fake-model","prompt_version":"v-golden","prompt_sha256":"26d0245a56d180eafd200ebe5311aab2488142c4a98dcddee21ea457814aa21a","temperature":0.3,"reasoning":"off","capability":{"Budget":"max_tokens","Temp":"send","TempValue":0,"Reasoning":{"Control":"none","OffEffort":"","OffExtraBody":null,"OnExtraBody":null},"MinMaxTokens":4000},"escalate_to":"fake-fallback","escalate_capability":{"Budget":"max_tokens","Temp":"send","TempValue":0,"Reasoning":{"Control":"none","OffEffort":"","OffExtraBody":null,"OnExtraBody":null},"MinMaxTokens":6000}},{"name":"edit","role":"editor","model":"fake-model","prompt_version":"v-golden","prompt_sha256":"6a8e7f71139d6bc09a95159d1cb895e05b56d2f2f7417c5e20a7073c517c79f6","temperature":0.4,"reasoning":"off","capability":{"Budget":"max_tokens","Temp":"send","TempValue":0,"Reasoning":{"Control":"none","OffEffort":"","OffExtraBody":null,"OnExtraBody":null},"MinMaxTokens":4000}}]}
|
||||
snapshot_id: 22bf92a04ce8d7b3045f0d752998ce818a24f2532a0bc97beeb73e32361bf3d9
|
||||
snapshot_payload: {"brief_hash":"c2021b1b5e6c20f6084e425b9a70bdc5f682801be347a57eb1c591deb8cab0df","chunker_version":"chunker-v4-utf8-quotedepth","estimator_version":"estimator-v0","max_tokens_policy":"maxtok-v1-double-per-attempt","classifier_version":"classify-v1-refusal+echo015+loop","pipeline_core":"C1","max_output_ratio":2,"min_max_tokens":512,"context_assembly":{"glossary_injection":"selective","glossary_token_budget":800,"stm_depth":0,"overlap_tokens":0,"cache_ttl":""},"memory_version":"cee708b1c530789a0d07f88902051fe0a9af49ad3b0706b230dbe6d503fc3cd9","postcheck_gate":false,"coverage":{"enabled":false},"style_check_version":"cheapgate-v2","sanitizer":{"enabled":true,"version":"sanitizer-v2"},"stages":[{"name":"draft","role":"translator","model":"fake-model","prompt_version":"v-golden","prompt_sha256":"26d0245a56d180eafd200ebe5311aab2488142c4a98dcddee21ea457814aa21a","temperature":0.3,"reasoning":"off","capability":{"Budget":"max_tokens","Temp":"send","TempValue":0,"Reasoning":{"Control":"none","OffEffort":"","OffExtraBody":null,"OnExtraBody":null},"MinMaxTokens":4000},"escalate_to":"fake-fallback","escalate_capability":{"Budget":"max_tokens","Temp":"send","TempValue":0,"Reasoning":{"Control":"none","OffEffort":"","OffExtraBody":null,"OnExtraBody":null},"MinMaxTokens":6000}},{"name":"edit","role":"editor","model":"fake-model","prompt_version":"v-golden","prompt_sha256":"6a8e7f71139d6bc09a95159d1cb895e05b56d2f2f7417c5e20a7073c517c79f6","temperature":0.4,"reasoning":"off","capability":{"Budget":"max_tokens","Temp":"send","TempValue":0,"Reasoning":{"Control":"none","OffEffort":"","OffExtraBody":null,"OnExtraBody":null},"MinMaxTokens":4000}}]}
|
||||
brief_hash: c2021b1b5e6c20f6084e425b9a70bdc5f682801be347a57eb1c591deb8cab0df
|
||||
memory_version: cee708b1c530789a0d07f88902051fe0a9af49ad3b0706b230dbe6d503fc3cd9
|
||||
-- book result --
|
||||
|
|
@ -41,36 +41,36 @@ chunk ch6/0 disposition=flagged flag="sanitizer_defect" final_text="" cost=0.003
|
|||
stage=edit role=editor model=fake-model resume=false disp=flagged flag="sanitizer_defect" attempts=1 escalated=false esc_model="" finish="stop" cum_usd=0.00182 detail="ведущая служебная преамбула: Вот перевод фрагмента:"
|
||||
stage_text=""
|
||||
-- chunk_status --
|
||||
ch1/0 draft snap_match=true content_hash=331c6f32c7f3ed15447e2639a2621d24a180e561a2aee92115324f492db5de3e disp=ok flag="" attempts=1 final_hash=5c0cb811ea30bf1e05c9ebbb9d7bf018f35c8fb39eed24aaa67f3bc15b8b72a3 cost=0.00182 escalated=false esc_model="" detail=""
|
||||
ch1/0 edit snap_match=true content_hash=a559165b4d1fc3f9e75472ca654f4d039ae1e0cad1541c043e7aa68fbea5415a disp=ok flag="" attempts=1 final_hash=2a732c0a6fe783fe04dbd2aa701c4b0516c92fa2c40702d18c89a5ae72e2f923 cost=0.00182 escalated=false esc_model="" detail=""
|
||||
ch1/1 draft snap_match=true content_hash=12fe3ccdf062f43e011363a33ff85c9b6842a8f23d790991fe9afab51a8becc8 disp=ok flag="" attempts=1 final_hash=d5d4d6fcfdc6b7be88110b1fbb162faac8857d0617b028e7c126f8f231859f0c cost=0.00182 escalated=false esc_model="" detail=""
|
||||
ch1/1 edit snap_match=true content_hash=b11a1740e5af98af20e207672555da8d411311e6c1e26595b456b656e8de59ef disp=ok flag="" attempts=1 final_hash=e9985b9e4a97521e94a7dd99c3676fad5149455523d5d0e31e9537d23848106b cost=0.00182 escalated=false esc_model="" detail=""
|
||||
ch2/0 draft snap_match=true content_hash=2693325bc747687acf090bc263fe8c17783726b949c6d8a2d072da3401be6827 disp=ok flag="" attempts=1 final_hash=347c7e5fc23c926ad157aa8cceabf862adfa33c24ceda9c5f6703ec70e8e720a cost=0.00728 escalated=true esc_model="fake-fallback" detail=""
|
||||
ch2/0 edit snap_match=true content_hash=b467337f05775296985a6d79454b518302812edb57d398001b8852d0663c5bbb disp=ok flag="" attempts=1 final_hash=a1df2ff560f41e5c72e1f23e1a00f23011cca2e5381868db9ac0af98f4bd294b cost=0.00182 escalated=false esc_model="" detail=""
|
||||
ch1/0 draft snap_match=true content_hash=331c6f32c7f3ed15447e2639a2621d24a180e561a2aee92115324f492db5de3e disp=ok flag="" attempts=1 final_hash=7bda1d23e4828d0f05f167f0980d6dcb31e6d7808175c3e934e512f25ec4d03f cost=0.00182 escalated=false esc_model="" detail=""
|
||||
ch1/0 edit snap_match=true content_hash=a559165b4d1fc3f9e75472ca654f4d039ae1e0cad1541c043e7aa68fbea5415a disp=ok flag="" attempts=1 final_hash=1d2aad2175e4e34c894709417460a3a4a395fc977e603f339327b1d302befcf5 cost=0.00182 escalated=false esc_model="" detail=""
|
||||
ch1/1 draft snap_match=true content_hash=12fe3ccdf062f43e011363a33ff85c9b6842a8f23d790991fe9afab51a8becc8 disp=ok flag="" attempts=1 final_hash=96d877d33a55d992fa1a4d36fa13a0d97eb61324dda80296cce432f279991b96 cost=0.00182 escalated=false esc_model="" detail=""
|
||||
ch1/1 edit snap_match=true content_hash=b11a1740e5af98af20e207672555da8d411311e6c1e26595b456b656e8de59ef disp=ok flag="" attempts=1 final_hash=15ca0e09a901d97cc9f4665196e60aa10ef1ece4a5abb8ac2ccf65355ee4af04 cost=0.00182 escalated=false esc_model="" detail=""
|
||||
ch2/0 draft snap_match=true content_hash=2693325bc747687acf090bc263fe8c17783726b949c6d8a2d072da3401be6827 disp=ok flag="" attempts=1 final_hash=91bc556b12b7ee88771b870dcc872172a7edfa75b4cd0286fc6f9c9b1e030b50 cost=0.00728 escalated=true esc_model="fake-fallback" detail=""
|
||||
ch2/0 edit snap_match=true content_hash=b467337f05775296985a6d79454b518302812edb57d398001b8852d0663c5bbb disp=ok flag="" attempts=1 final_hash=4cb824da88d824dee2548f25c99a07af19d8e7a960dc12eb8a2dcfbfea565dfe cost=0.00182 escalated=false esc_model="" detail=""
|
||||
ch3/0 draft snap_match=true content_hash=733fc6a89215efe112cfadd1d1fb361bb8a7ab1013994248a49da0dbd137548e disp=flagged flag="hard_refusal" attempts=1 final_hash= cost=0.00728 escalated=true esc_model="fake-fallback" detail="provider finish_reason=refusal"
|
||||
ch3/0 edit snap_match=true content_hash= disp=skipped flag="hard_refusal" attempts=0 final_hash= cost=0 escalated=false esc_model="" detail="skipped: an upstream stage was flagged (hard_refusal)"
|
||||
ch4/0 draft snap_match=true content_hash=7aabdcb89dea365c95363b2662144ca1a10b307d377f47a8e7cc19b5b872d287 disp=ok flag="" attempts=1 final_hash=cc910a514d60f6f02e6d31ab9f07777e11fe0009874edff9b0c65e5cabb68311 cost=0.00182 escalated=false esc_model="" detail=""
|
||||
ch4/0 edit snap_match=true content_hash=2854dfe1648b0cf0cbb683cb7ce94c5eedc9223b2ce20c99dc008c7add6317ef disp=ok flag="" attempts=1 final_hash=708b7d426e2f9464b4c32741e4367781ddbb89a6bf119ac08b1d77c71627c7fc cost=0.00182 escalated=false esc_model="" detail=""
|
||||
ch5/0 draft snap_match=true content_hash=d8aba42cabb41853a81875ebc725bb516dc2412e29de3a03bc1a68e90f8cf157 disp=ok flag="" attempts=1 final_hash=0c1a34b813466396a5a9e8150200829fe4ea6cfec8eef999761194ae1ef6ba89 cost=0.00182 escalated=false esc_model="" detail=""
|
||||
ch5/0 edit snap_match=true content_hash=99ebb10d754a2f3ae3a00d62734ad1c39160f083350217eda5bda6e91373f4de disp=ok flag="" attempts=1 final_hash=9d13216d51b230a9519b5afe640b83c25c2a3eb31f45efaa6889aef3acee2e09 cost=0.00182 escalated=false esc_model="" detail=""
|
||||
ch6/0 draft snap_match=true content_hash=9375b05780724cc354eba15a595da9a5f964219c0887042484256eed11fb566f disp=ok flag="" attempts=1 final_hash=6746c63437db911f9b3588d4ddcf8d6effb9f5131df8c7c4ce65cae2236c9534 cost=0.00182 escalated=false esc_model="" detail=""
|
||||
ch4/0 draft snap_match=true content_hash=7aabdcb89dea365c95363b2662144ca1a10b307d377f47a8e7cc19b5b872d287 disp=ok flag="" attempts=1 final_hash=887c72449d515b208d1473df5bfa91b0e0f5e2eec3850b967d2888413189bbc4 cost=0.00182 escalated=false esc_model="" detail=""
|
||||
ch4/0 edit snap_match=true content_hash=2854dfe1648b0cf0cbb683cb7ce94c5eedc9223b2ce20c99dc008c7add6317ef disp=ok flag="" attempts=1 final_hash=88be9923f7e6e6781b8eb9e02ffeea614003dc504b676e0cb54fe21ee1b239ba cost=0.00182 escalated=false esc_model="" detail=""
|
||||
ch5/0 draft snap_match=true content_hash=d8aba42cabb41853a81875ebc725bb516dc2412e29de3a03bc1a68e90f8cf157 disp=ok flag="" attempts=1 final_hash=e723f314c5cd17a0f000c0bbac25812b42f414ae9d395d59ceb186ea65caed90 cost=0.00182 escalated=false esc_model="" detail=""
|
||||
ch5/0 edit snap_match=true content_hash=99ebb10d754a2f3ae3a00d62734ad1c39160f083350217eda5bda6e91373f4de disp=ok flag="" attempts=1 final_hash=b8d6e3f357b740ad065e37c46eeb9b31dc170849db8bd8f8d468040ad2b47701 cost=0.00182 escalated=false esc_model="" detail=""
|
||||
ch6/0 draft snap_match=true content_hash=9375b05780724cc354eba15a595da9a5f964219c0887042484256eed11fb566f disp=ok flag="" attempts=1 final_hash=7b0dd4e5b9a7648c65e7c04b6dd928ff8e6d7dc74b3f4baf469058e8dbdf628f cost=0.00182 escalated=false esc_model="" detail=""
|
||||
ch6/0 edit snap_match=true content_hash=f9a70ce8a43db4a89eda5e53a6f29ba5f0c2a35559a9d35b73f771220bb262ee disp=flagged flag="sanitizer_defect" attempts=1 final_hash= cost=0.00182 escalated=false esc_model="" detail="ведущая служебная преамбула: Вот перевод фрагмента:"
|
||||
-- request_log (insertion order) --
|
||||
ch1/0 draft role=translator req=fake-model actual=fake-model hash=5c0cb811ea30bf1e05c9ebbb9d7bf018f35c8fb39eed24aaa67f3bc15b8b72a3 tm_hit=0 ok=1 finish="stop" degraded="" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
ch1/0 edit role=editor req=fake-model actual=fake-model hash=2a732c0a6fe783fe04dbd2aa701c4b0516c92fa2c40702d18c89a5ae72e2f923 tm_hit=0 ok=1 finish="stop" degraded="" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
ch1/1 draft role=translator req=fake-model actual=fake-model hash=d5d4d6fcfdc6b7be88110b1fbb162faac8857d0617b028e7c126f8f231859f0c tm_hit=0 ok=1 finish="stop" degraded="" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
ch1/1 edit role=editor req=fake-model actual=fake-model hash=e9985b9e4a97521e94a7dd99c3676fad5149455523d5d0e31e9537d23848106b tm_hit=0 ok=1 finish="stop" degraded="" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
ch2/0 draft role=translator req=fake-model actual=fake-model hash=e9aa356e2553b0b678946bbd418f48b2bf5fb58d403f0512b4b5baa92e7ad34f tm_hit=0 ok=0 finish="stop" degraded="cjk_artifact" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
ch2/0 draft role=translator req=fake-fallback actual=fake-fallback hash=347c7e5fc23c926ad157aa8cceabf862adfa33c24ceda9c5f6703ec70e8e720a tm_hit=0 ok=1 finish="stop" degraded="" cost=0.0054600000000000004 tokens=1000/200/0/500/0 err=""
|
||||
ch2/0 edit role=editor req=fake-model actual=fake-model hash=a1df2ff560f41e5c72e1f23e1a00f23011cca2e5381868db9ac0af98f4bd294b tm_hit=0 ok=1 finish="stop" degraded="" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
ch3/0 draft role=translator req=fake-model actual=fake-model hash=68d833174eaa07b859b1e8fd7bf90f95c408f61b76b6684dbbb31402895d40ac tm_hit=0 ok=0 finish="refusal" degraded="hard_refusal" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
ch3/0 draft role=translator req=fake-fallback actual=fake-fallback hash=9874cb22d4d68774551865886f2d186b156d138d791c4368deed09c2bf71e21b tm_hit=0 ok=0 finish="refusal" degraded="hard_refusal" cost=0.0054600000000000004 tokens=1000/200/0/500/0 err=""
|
||||
ch4/0 draft role=translator req=fake-model actual=fake-model hash=cc910a514d60f6f02e6d31ab9f07777e11fe0009874edff9b0c65e5cabb68311 tm_hit=0 ok=1 finish="stop" degraded="" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
ch4/0 edit role=editor req=fake-model actual=fake-model hash=708b7d426e2f9464b4c32741e4367781ddbb89a6bf119ac08b1d77c71627c7fc tm_hit=0 ok=1 finish="stop" degraded="" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
ch5/0 draft role=translator req=fake-model actual=fake-model hash=0c1a34b813466396a5a9e8150200829fe4ea6cfec8eef999761194ae1ef6ba89 tm_hit=0 ok=1 finish="stop" degraded="" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
ch5/0 edit role=editor req=fake-model actual=fake-model hash=9d13216d51b230a9519b5afe640b83c25c2a3eb31f45efaa6889aef3acee2e09 tm_hit=0 ok=1 finish="stop" degraded="" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
ch6/0 draft role=translator req=fake-model actual=fake-model hash=6746c63437db911f9b3588d4ddcf8d6effb9f5131df8c7c4ce65cae2236c9534 tm_hit=0 ok=1 finish="stop" degraded="" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
ch6/0 edit role=editor req=fake-model actual=fake-model hash=e9f657977bca5176035af240b83f06852c8e8ba0a51adab8aa915abea9999b02 tm_hit=0 ok=0 finish="stop" degraded="sanitizer_defect" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
ch1/0 draft role=translator req=fake-model actual=fake-model hash=7bda1d23e4828d0f05f167f0980d6dcb31e6d7808175c3e934e512f25ec4d03f tm_hit=0 ok=1 finish="stop" degraded="" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
ch1/0 edit role=editor req=fake-model actual=fake-model hash=1d2aad2175e4e34c894709417460a3a4a395fc977e603f339327b1d302befcf5 tm_hit=0 ok=1 finish="stop" degraded="" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
ch1/1 draft role=translator req=fake-model actual=fake-model hash=96d877d33a55d992fa1a4d36fa13a0d97eb61324dda80296cce432f279991b96 tm_hit=0 ok=1 finish="stop" degraded="" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
ch1/1 edit role=editor req=fake-model actual=fake-model hash=15ca0e09a901d97cc9f4665196e60aa10ef1ece4a5abb8ac2ccf65355ee4af04 tm_hit=0 ok=1 finish="stop" degraded="" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
ch2/0 draft role=translator req=fake-model actual=fake-model hash=1f46b5678d6507f1bbd445c35ca21105df5a902c67c631e1c64fb044e7d4c818 tm_hit=0 ok=0 finish="stop" degraded="cjk_artifact" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
ch2/0 draft role=translator req=fake-fallback actual=fake-fallback hash=91bc556b12b7ee88771b870dcc872172a7edfa75b4cd0286fc6f9c9b1e030b50 tm_hit=0 ok=1 finish="stop" degraded="" cost=0.0054600000000000004 tokens=1000/200/0/500/0 err=""
|
||||
ch2/0 edit role=editor req=fake-model actual=fake-model hash=4cb824da88d824dee2548f25c99a07af19d8e7a960dc12eb8a2dcfbfea565dfe tm_hit=0 ok=1 finish="stop" degraded="" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
ch3/0 draft role=translator req=fake-model actual=fake-model hash=bc8732c7c5039acef1d37e3d3cc9c3d86f4cfaece50d8c2985c0a405b24f583d tm_hit=0 ok=0 finish="refusal" degraded="hard_refusal" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
ch3/0 draft role=translator req=fake-fallback actual=fake-fallback hash=832508029b158e9b8533740283f1cccdedf1597d6e8bb98f797587b7c461566c tm_hit=0 ok=0 finish="refusal" degraded="hard_refusal" cost=0.0054600000000000004 tokens=1000/200/0/500/0 err=""
|
||||
ch4/0 draft role=translator req=fake-model actual=fake-model hash=887c72449d515b208d1473df5bfa91b0e0f5e2eec3850b967d2888413189bbc4 tm_hit=0 ok=1 finish="stop" degraded="" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
ch4/0 edit role=editor req=fake-model actual=fake-model hash=88be9923f7e6e6781b8eb9e02ffeea614003dc504b676e0cb54fe21ee1b239ba tm_hit=0 ok=1 finish="stop" degraded="" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
ch5/0 draft role=translator req=fake-model actual=fake-model hash=e723f314c5cd17a0f000c0bbac25812b42f414ae9d395d59ceb186ea65caed90 tm_hit=0 ok=1 finish="stop" degraded="" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
ch5/0 edit role=editor req=fake-model actual=fake-model hash=b8d6e3f357b740ad065e37c46eeb9b31dc170849db8bd8f8d468040ad2b47701 tm_hit=0 ok=1 finish="stop" degraded="" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
ch6/0 draft role=translator req=fake-model actual=fake-model hash=7b0dd4e5b9a7648c65e7c04b6dd928ff8e6d7dc74b3f4baf469058e8dbdf628f tm_hit=0 ok=1 finish="stop" degraded="" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
ch6/0 edit role=editor req=fake-model actual=fake-model hash=190b651aa53eb1991b5d2a3b75440190d3a5d9ef4b5226cd0bedfb938179de73 tm_hit=0 ok=0 finish="stop" degraded="sanitizer_defect" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
-- retrieval_state --
|
||||
ch1/0 snap_match=true exact=3 sticky=0 ambiguous=0 spoiler=1 evicted=0 postcheck_miss=1 style_flags=0
|
||||
injected_ids=["紋章\u001f\u001f0\u001f0","鈴木\u001f\u001f0\u001f0","魔法学院\u001f\u001f0\u001f0"] postcheck_detail=[{"src":"紋章","dst":"герб","disp":"confirmed"}] style_detail=
|
||||
|
|
@ -103,8 +103,8 @@ ch6/0 snap_match=true exact=1 sticky=0 ambiguous=0 spoiler=0 evicted=0 postcheck
|
|||
[13] {"max_tokens":4000,"messages":[{"role":"system","content":"Переводи художественный текст с ja на ru. Жанр: ранобэ. Аудитория: взрослые. Баланс Венути: 0.50. Хонорифики: keep. Транскрипция: polivanov."},{"role":"system","content":"ГЛОССАРИЙ (используй эти утверждённые переводы имён и терминов последовательно; строки с пометкой ⟨проверить⟩ — неподтверждённые кандидаты):\n鈴木 → Судзуки"},{"role":"user","content":"第六章 序文漏洩\n\n鈴木は最後の扉の前に立ち、深く息を吸い込んだ。その先に何があるのか、誰も知らなかった。"}],"model":"fake-model","stream":false,"temperature":0.3}
|
||||
[14] {"max_tokens":4000,"messages":[{"role":"system","content":"Ты — монолингвальный редактор русского текста. Правь стиль, не меняя смысла. Книга: Золотая книга."},{"role":"system","content":"КАНОНИЧЕСКИЕ ПЕРЕВОДЫ имён и терминов (в черновике эти сущности должны быть переданы ИМЕННО этими формами — приводи к ним любые расхождения, склоняя по контексту; не вводи иных вариантов и не меняй ничего другого):\n- «Судзуки»"},{"role":"user","content":"Черновик перевода для редактуры: Вот перевод фрагмента: ПРЕАМБУЛА-СЦЕНА Судзуки открыл дверь."}],"model":"fake-model","stream":false,"temperature":0.4}
|
||||
==== run 2 (resume) ====
|
||||
snapshot_id: c3d6d1f3768cf42a3e0b175e0280ff9b242c5596271a49e6fbe9e04e01dc345c
|
||||
snapshot_payload: {"brief_hash":"c2021b1b5e6c20f6084e425b9a70bdc5f682801be347a57eb1c591deb8cab0df","chunker_version":"chunker-v4-utf8-quotedepth","estimator_version":"estimator-v0","max_tokens_policy":"maxtok-v1-double-per-attempt","classifier_version":"classify-v1-refusal+echo015+loop","pipeline_core":"C1","max_output_ratio":2,"min_max_tokens":512,"context_assembly":{"glossary_injection":"selective","glossary_token_budget":800,"stm_depth":0,"overlap_tokens":0,"cache_ttl":""},"memory_version":"cee708b1c530789a0d07f88902051fe0a9af49ad3b0706b230dbe6d503fc3cd9","postcheck_gate":false,"coverage":{"enabled":false},"style_check_version":"cheapgate-v2","sanitizer":{"enabled":true,"version":"sanitizer-v1"},"stages":[{"name":"draft","role":"translator","model":"fake-model","prompt_version":"v-golden","prompt_sha256":"26d0245a56d180eafd200ebe5311aab2488142c4a98dcddee21ea457814aa21a","temperature":0.3,"reasoning":"off","capability":{"Budget":"max_tokens","Temp":"send","TempValue":0,"Reasoning":{"Control":"none","OffEffort":"","OffExtraBody":null,"OnExtraBody":null},"MinMaxTokens":4000},"escalate_to":"fake-fallback","escalate_capability":{"Budget":"max_tokens","Temp":"send","TempValue":0,"Reasoning":{"Control":"none","OffEffort":"","OffExtraBody":null,"OnExtraBody":null},"MinMaxTokens":6000}},{"name":"edit","role":"editor","model":"fake-model","prompt_version":"v-golden","prompt_sha256":"6a8e7f71139d6bc09a95159d1cb895e05b56d2f2f7417c5e20a7073c517c79f6","temperature":0.4,"reasoning":"off","capability":{"Budget":"max_tokens","Temp":"send","TempValue":0,"Reasoning":{"Control":"none","OffEffort":"","OffExtraBody":null,"OnExtraBody":null},"MinMaxTokens":4000}}]}
|
||||
snapshot_id: 22bf92a04ce8d7b3045f0d752998ce818a24f2532a0bc97beeb73e32361bf3d9
|
||||
snapshot_payload: {"brief_hash":"c2021b1b5e6c20f6084e425b9a70bdc5f682801be347a57eb1c591deb8cab0df","chunker_version":"chunker-v4-utf8-quotedepth","estimator_version":"estimator-v0","max_tokens_policy":"maxtok-v1-double-per-attempt","classifier_version":"classify-v1-refusal+echo015+loop","pipeline_core":"C1","max_output_ratio":2,"min_max_tokens":512,"context_assembly":{"glossary_injection":"selective","glossary_token_budget":800,"stm_depth":0,"overlap_tokens":0,"cache_ttl":""},"memory_version":"cee708b1c530789a0d07f88902051fe0a9af49ad3b0706b230dbe6d503fc3cd9","postcheck_gate":false,"coverage":{"enabled":false},"style_check_version":"cheapgate-v2","sanitizer":{"enabled":true,"version":"sanitizer-v2"},"stages":[{"name":"draft","role":"translator","model":"fake-model","prompt_version":"v-golden","prompt_sha256":"26d0245a56d180eafd200ebe5311aab2488142c4a98dcddee21ea457814aa21a","temperature":0.3,"reasoning":"off","capability":{"Budget":"max_tokens","Temp":"send","TempValue":0,"Reasoning":{"Control":"none","OffEffort":"","OffExtraBody":null,"OnExtraBody":null},"MinMaxTokens":4000},"escalate_to":"fake-fallback","escalate_capability":{"Budget":"max_tokens","Temp":"send","TempValue":0,"Reasoning":{"Control":"none","OffEffort":"","OffExtraBody":null,"OnExtraBody":null},"MinMaxTokens":6000}},{"name":"edit","role":"editor","model":"fake-model","prompt_version":"v-golden","prompt_sha256":"6a8e7f71139d6bc09a95159d1cb895e05b56d2f2f7417c5e20a7073c517c79f6","temperature":0.4,"reasoning":"off","capability":{"Budget":"max_tokens","Temp":"send","TempValue":0,"Reasoning":{"Control":"none","OffEffort":"","OffExtraBody":null,"OnExtraBody":null},"MinMaxTokens":4000}}]}
|
||||
brief_hash: c2021b1b5e6c20f6084e425b9a70bdc5f682801be347a57eb1c591deb8cab0df
|
||||
memory_version: cee708b1c530789a0d07f88902051fe0a9af49ad3b0706b230dbe6d503fc3cd9
|
||||
-- book result --
|
||||
|
|
@ -145,48 +145,48 @@ chunk ch6/0 disposition=flagged flag="sanitizer_defect" final_text="" cost=0
|
|||
stage=edit role=editor model=fake-model resume=true disp=flagged flag="sanitizer_defect" attempts=1 escalated=false esc_model="" finish="" cum_usd=0.00182 detail="ведущая служебная преамбула: Вот перевод фрагмента:"
|
||||
stage_text=""
|
||||
-- chunk_status --
|
||||
ch1/0 draft snap_match=true content_hash=331c6f32c7f3ed15447e2639a2621d24a180e561a2aee92115324f492db5de3e disp=ok flag="" attempts=1 final_hash=5c0cb811ea30bf1e05c9ebbb9d7bf018f35c8fb39eed24aaa67f3bc15b8b72a3 cost=0.00182 escalated=false esc_model="" detail=""
|
||||
ch1/0 edit snap_match=true content_hash=a559165b4d1fc3f9e75472ca654f4d039ae1e0cad1541c043e7aa68fbea5415a disp=ok flag="" attempts=1 final_hash=2a732c0a6fe783fe04dbd2aa701c4b0516c92fa2c40702d18c89a5ae72e2f923 cost=0.00182 escalated=false esc_model="" detail=""
|
||||
ch1/1 draft snap_match=true content_hash=12fe3ccdf062f43e011363a33ff85c9b6842a8f23d790991fe9afab51a8becc8 disp=ok flag="" attempts=1 final_hash=d5d4d6fcfdc6b7be88110b1fbb162faac8857d0617b028e7c126f8f231859f0c cost=0.00182 escalated=false esc_model="" detail=""
|
||||
ch1/1 edit snap_match=true content_hash=b11a1740e5af98af20e207672555da8d411311e6c1e26595b456b656e8de59ef disp=ok flag="" attempts=1 final_hash=e9985b9e4a97521e94a7dd99c3676fad5149455523d5d0e31e9537d23848106b cost=0.00182 escalated=false esc_model="" detail=""
|
||||
ch2/0 draft snap_match=true content_hash=2693325bc747687acf090bc263fe8c17783726b949c6d8a2d072da3401be6827 disp=ok flag="" attempts=1 final_hash=347c7e5fc23c926ad157aa8cceabf862adfa33c24ceda9c5f6703ec70e8e720a cost=0.00728 escalated=true esc_model="fake-fallback" detail=""
|
||||
ch2/0 edit snap_match=true content_hash=b467337f05775296985a6d79454b518302812edb57d398001b8852d0663c5bbb disp=ok flag="" attempts=1 final_hash=a1df2ff560f41e5c72e1f23e1a00f23011cca2e5381868db9ac0af98f4bd294b cost=0.00182 escalated=false esc_model="" detail=""
|
||||
ch1/0 draft snap_match=true content_hash=331c6f32c7f3ed15447e2639a2621d24a180e561a2aee92115324f492db5de3e disp=ok flag="" attempts=1 final_hash=7bda1d23e4828d0f05f167f0980d6dcb31e6d7808175c3e934e512f25ec4d03f cost=0.00182 escalated=false esc_model="" detail=""
|
||||
ch1/0 edit snap_match=true content_hash=a559165b4d1fc3f9e75472ca654f4d039ae1e0cad1541c043e7aa68fbea5415a disp=ok flag="" attempts=1 final_hash=1d2aad2175e4e34c894709417460a3a4a395fc977e603f339327b1d302befcf5 cost=0.00182 escalated=false esc_model="" detail=""
|
||||
ch1/1 draft snap_match=true content_hash=12fe3ccdf062f43e011363a33ff85c9b6842a8f23d790991fe9afab51a8becc8 disp=ok flag="" attempts=1 final_hash=96d877d33a55d992fa1a4d36fa13a0d97eb61324dda80296cce432f279991b96 cost=0.00182 escalated=false esc_model="" detail=""
|
||||
ch1/1 edit snap_match=true content_hash=b11a1740e5af98af20e207672555da8d411311e6c1e26595b456b656e8de59ef disp=ok flag="" attempts=1 final_hash=15ca0e09a901d97cc9f4665196e60aa10ef1ece4a5abb8ac2ccf65355ee4af04 cost=0.00182 escalated=false esc_model="" detail=""
|
||||
ch2/0 draft snap_match=true content_hash=2693325bc747687acf090bc263fe8c17783726b949c6d8a2d072da3401be6827 disp=ok flag="" attempts=1 final_hash=91bc556b12b7ee88771b870dcc872172a7edfa75b4cd0286fc6f9c9b1e030b50 cost=0.00728 escalated=true esc_model="fake-fallback" detail=""
|
||||
ch2/0 edit snap_match=true content_hash=b467337f05775296985a6d79454b518302812edb57d398001b8852d0663c5bbb disp=ok flag="" attempts=1 final_hash=4cb824da88d824dee2548f25c99a07af19d8e7a960dc12eb8a2dcfbfea565dfe cost=0.00182 escalated=false esc_model="" detail=""
|
||||
ch3/0 draft snap_match=true content_hash=733fc6a89215efe112cfadd1d1fb361bb8a7ab1013994248a49da0dbd137548e disp=flagged flag="hard_refusal" attempts=1 final_hash= cost=0.00728 escalated=true esc_model="fake-fallback" detail="provider finish_reason=refusal"
|
||||
ch3/0 edit snap_match=true content_hash= disp=skipped flag="hard_refusal" attempts=0 final_hash= cost=0 escalated=false esc_model="" detail="skipped: an upstream stage was flagged (hard_refusal)"
|
||||
ch4/0 draft snap_match=true content_hash=7aabdcb89dea365c95363b2662144ca1a10b307d377f47a8e7cc19b5b872d287 disp=ok flag="" attempts=1 final_hash=cc910a514d60f6f02e6d31ab9f07777e11fe0009874edff9b0c65e5cabb68311 cost=0.00182 escalated=false esc_model="" detail=""
|
||||
ch4/0 edit snap_match=true content_hash=2854dfe1648b0cf0cbb683cb7ce94c5eedc9223b2ce20c99dc008c7add6317ef disp=ok flag="" attempts=1 final_hash=708b7d426e2f9464b4c32741e4367781ddbb89a6bf119ac08b1d77c71627c7fc cost=0.00182 escalated=false esc_model="" detail=""
|
||||
ch5/0 draft snap_match=true content_hash=d8aba42cabb41853a81875ebc725bb516dc2412e29de3a03bc1a68e90f8cf157 disp=ok flag="" attempts=1 final_hash=0c1a34b813466396a5a9e8150200829fe4ea6cfec8eef999761194ae1ef6ba89 cost=0.00182 escalated=false esc_model="" detail=""
|
||||
ch5/0 edit snap_match=true content_hash=99ebb10d754a2f3ae3a00d62734ad1c39160f083350217eda5bda6e91373f4de disp=ok flag="" attempts=1 final_hash=9d13216d51b230a9519b5afe640b83c25c2a3eb31f45efaa6889aef3acee2e09 cost=0.00182 escalated=false esc_model="" detail=""
|
||||
ch6/0 draft snap_match=true content_hash=9375b05780724cc354eba15a595da9a5f964219c0887042484256eed11fb566f disp=ok flag="" attempts=1 final_hash=6746c63437db911f9b3588d4ddcf8d6effb9f5131df8c7c4ce65cae2236c9534 cost=0.00182 escalated=false esc_model="" detail=""
|
||||
ch4/0 draft snap_match=true content_hash=7aabdcb89dea365c95363b2662144ca1a10b307d377f47a8e7cc19b5b872d287 disp=ok flag="" attempts=1 final_hash=887c72449d515b208d1473df5bfa91b0e0f5e2eec3850b967d2888413189bbc4 cost=0.00182 escalated=false esc_model="" detail=""
|
||||
ch4/0 edit snap_match=true content_hash=2854dfe1648b0cf0cbb683cb7ce94c5eedc9223b2ce20c99dc008c7add6317ef disp=ok flag="" attempts=1 final_hash=88be9923f7e6e6781b8eb9e02ffeea614003dc504b676e0cb54fe21ee1b239ba cost=0.00182 escalated=false esc_model="" detail=""
|
||||
ch5/0 draft snap_match=true content_hash=d8aba42cabb41853a81875ebc725bb516dc2412e29de3a03bc1a68e90f8cf157 disp=ok flag="" attempts=1 final_hash=e723f314c5cd17a0f000c0bbac25812b42f414ae9d395d59ceb186ea65caed90 cost=0.00182 escalated=false esc_model="" detail=""
|
||||
ch5/0 edit snap_match=true content_hash=99ebb10d754a2f3ae3a00d62734ad1c39160f083350217eda5bda6e91373f4de disp=ok flag="" attempts=1 final_hash=b8d6e3f357b740ad065e37c46eeb9b31dc170849db8bd8f8d468040ad2b47701 cost=0.00182 escalated=false esc_model="" detail=""
|
||||
ch6/0 draft snap_match=true content_hash=9375b05780724cc354eba15a595da9a5f964219c0887042484256eed11fb566f disp=ok flag="" attempts=1 final_hash=7b0dd4e5b9a7648c65e7c04b6dd928ff8e6d7dc74b3f4baf469058e8dbdf628f cost=0.00182 escalated=false esc_model="" detail=""
|
||||
ch6/0 edit snap_match=true content_hash=f9a70ce8a43db4a89eda5e53a6f29ba5f0c2a35559a9d35b73f771220bb262ee disp=flagged flag="sanitizer_defect" attempts=1 final_hash= cost=0.00182 escalated=false esc_model="" detail="ведущая служебная преамбула: Вот перевод фрагмента:"
|
||||
-- request_log (insertion order) --
|
||||
ch1/0 draft role=translator req=fake-model actual=fake-model hash=5c0cb811ea30bf1e05c9ebbb9d7bf018f35c8fb39eed24aaa67f3bc15b8b72a3 tm_hit=0 ok=1 finish="stop" degraded="" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
ch1/0 edit role=editor req=fake-model actual=fake-model hash=2a732c0a6fe783fe04dbd2aa701c4b0516c92fa2c40702d18c89a5ae72e2f923 tm_hit=0 ok=1 finish="stop" degraded="" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
ch1/1 draft role=translator req=fake-model actual=fake-model hash=d5d4d6fcfdc6b7be88110b1fbb162faac8857d0617b028e7c126f8f231859f0c tm_hit=0 ok=1 finish="stop" degraded="" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
ch1/1 edit role=editor req=fake-model actual=fake-model hash=e9985b9e4a97521e94a7dd99c3676fad5149455523d5d0e31e9537d23848106b tm_hit=0 ok=1 finish="stop" degraded="" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
ch2/0 draft role=translator req=fake-model actual=fake-model hash=e9aa356e2553b0b678946bbd418f48b2bf5fb58d403f0512b4b5baa92e7ad34f tm_hit=0 ok=0 finish="stop" degraded="cjk_artifact" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
ch2/0 draft role=translator req=fake-fallback actual=fake-fallback hash=347c7e5fc23c926ad157aa8cceabf862adfa33c24ceda9c5f6703ec70e8e720a tm_hit=0 ok=1 finish="stop" degraded="" cost=0.0054600000000000004 tokens=1000/200/0/500/0 err=""
|
||||
ch2/0 edit role=editor req=fake-model actual=fake-model hash=a1df2ff560f41e5c72e1f23e1a00f23011cca2e5381868db9ac0af98f4bd294b tm_hit=0 ok=1 finish="stop" degraded="" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
ch3/0 draft role=translator req=fake-model actual=fake-model hash=68d833174eaa07b859b1e8fd7bf90f95c408f61b76b6684dbbb31402895d40ac tm_hit=0 ok=0 finish="refusal" degraded="hard_refusal" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
ch3/0 draft role=translator req=fake-fallback actual=fake-fallback hash=9874cb22d4d68774551865886f2d186b156d138d791c4368deed09c2bf71e21b tm_hit=0 ok=0 finish="refusal" degraded="hard_refusal" cost=0.0054600000000000004 tokens=1000/200/0/500/0 err=""
|
||||
ch4/0 draft role=translator req=fake-model actual=fake-model hash=cc910a514d60f6f02e6d31ab9f07777e11fe0009874edff9b0c65e5cabb68311 tm_hit=0 ok=1 finish="stop" degraded="" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
ch4/0 edit role=editor req=fake-model actual=fake-model hash=708b7d426e2f9464b4c32741e4367781ddbb89a6bf119ac08b1d77c71627c7fc tm_hit=0 ok=1 finish="stop" degraded="" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
ch5/0 draft role=translator req=fake-model actual=fake-model hash=0c1a34b813466396a5a9e8150200829fe4ea6cfec8eef999761194ae1ef6ba89 tm_hit=0 ok=1 finish="stop" degraded="" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
ch5/0 edit role=editor req=fake-model actual=fake-model hash=9d13216d51b230a9519b5afe640b83c25c2a3eb31f45efaa6889aef3acee2e09 tm_hit=0 ok=1 finish="stop" degraded="" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
ch6/0 draft role=translator req=fake-model actual=fake-model hash=6746c63437db911f9b3588d4ddcf8d6effb9f5131df8c7c4ce65cae2236c9534 tm_hit=0 ok=1 finish="stop" degraded="" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
ch6/0 edit role=editor req=fake-model actual=fake-model hash=e9f657977bca5176035af240b83f06852c8e8ba0a51adab8aa915abea9999b02 tm_hit=0 ok=0 finish="stop" degraded="sanitizer_defect" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
ch1/0 draft role=translator req=fake-model actual=fake-model hash=5c0cb811ea30bf1e05c9ebbb9d7bf018f35c8fb39eed24aaa67f3bc15b8b72a3 tm_hit=1 ok=1 finish="stop" degraded="" cost=0 tokens=0/0/0/0/0 err=""
|
||||
ch1/0 edit role=editor req=fake-model actual=fake-model hash=2a732c0a6fe783fe04dbd2aa701c4b0516c92fa2c40702d18c89a5ae72e2f923 tm_hit=1 ok=1 finish="stop" degraded="" cost=0 tokens=0/0/0/0/0 err=""
|
||||
ch1/1 draft role=translator req=fake-model actual=fake-model hash=d5d4d6fcfdc6b7be88110b1fbb162faac8857d0617b028e7c126f8f231859f0c tm_hit=1 ok=1 finish="stop" degraded="" cost=0 tokens=0/0/0/0/0 err=""
|
||||
ch1/1 edit role=editor req=fake-model actual=fake-model hash=e9985b9e4a97521e94a7dd99c3676fad5149455523d5d0e31e9537d23848106b tm_hit=1 ok=1 finish="stop" degraded="" cost=0 tokens=0/0/0/0/0 err=""
|
||||
ch2/0 draft role=translator req=fake-model actual=fake-fallback hash=347c7e5fc23c926ad157aa8cceabf862adfa33c24ceda9c5f6703ec70e8e720a tm_hit=1 ok=1 finish="stop" degraded="" cost=0 tokens=0/0/0/0/0 err=""
|
||||
ch2/0 edit role=editor req=fake-model actual=fake-model hash=a1df2ff560f41e5c72e1f23e1a00f23011cca2e5381868db9ac0af98f4bd294b tm_hit=1 ok=1 finish="stop" degraded="" cost=0 tokens=0/0/0/0/0 err=""
|
||||
ch1/0 draft role=translator req=fake-model actual=fake-model hash=7bda1d23e4828d0f05f167f0980d6dcb31e6d7808175c3e934e512f25ec4d03f tm_hit=0 ok=1 finish="stop" degraded="" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
ch1/0 edit role=editor req=fake-model actual=fake-model hash=1d2aad2175e4e34c894709417460a3a4a395fc977e603f339327b1d302befcf5 tm_hit=0 ok=1 finish="stop" degraded="" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
ch1/1 draft role=translator req=fake-model actual=fake-model hash=96d877d33a55d992fa1a4d36fa13a0d97eb61324dda80296cce432f279991b96 tm_hit=0 ok=1 finish="stop" degraded="" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
ch1/1 edit role=editor req=fake-model actual=fake-model hash=15ca0e09a901d97cc9f4665196e60aa10ef1ece4a5abb8ac2ccf65355ee4af04 tm_hit=0 ok=1 finish="stop" degraded="" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
ch2/0 draft role=translator req=fake-model actual=fake-model hash=1f46b5678d6507f1bbd445c35ca21105df5a902c67c631e1c64fb044e7d4c818 tm_hit=0 ok=0 finish="stop" degraded="cjk_artifact" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
ch2/0 draft role=translator req=fake-fallback actual=fake-fallback hash=91bc556b12b7ee88771b870dcc872172a7edfa75b4cd0286fc6f9c9b1e030b50 tm_hit=0 ok=1 finish="stop" degraded="" cost=0.0054600000000000004 tokens=1000/200/0/500/0 err=""
|
||||
ch2/0 edit role=editor req=fake-model actual=fake-model hash=4cb824da88d824dee2548f25c99a07af19d8e7a960dc12eb8a2dcfbfea565dfe tm_hit=0 ok=1 finish="stop" degraded="" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
ch3/0 draft role=translator req=fake-model actual=fake-model hash=bc8732c7c5039acef1d37e3d3cc9c3d86f4cfaece50d8c2985c0a405b24f583d tm_hit=0 ok=0 finish="refusal" degraded="hard_refusal" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
ch3/0 draft role=translator req=fake-fallback actual=fake-fallback hash=832508029b158e9b8533740283f1cccdedf1597d6e8bb98f797587b7c461566c tm_hit=0 ok=0 finish="refusal" degraded="hard_refusal" cost=0.0054600000000000004 tokens=1000/200/0/500/0 err=""
|
||||
ch4/0 draft role=translator req=fake-model actual=fake-model hash=887c72449d515b208d1473df5bfa91b0e0f5e2eec3850b967d2888413189bbc4 tm_hit=0 ok=1 finish="stop" degraded="" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
ch4/0 edit role=editor req=fake-model actual=fake-model hash=88be9923f7e6e6781b8eb9e02ffeea614003dc504b676e0cb54fe21ee1b239ba tm_hit=0 ok=1 finish="stop" degraded="" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
ch5/0 draft role=translator req=fake-model actual=fake-model hash=e723f314c5cd17a0f000c0bbac25812b42f414ae9d395d59ceb186ea65caed90 tm_hit=0 ok=1 finish="stop" degraded="" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
ch5/0 edit role=editor req=fake-model actual=fake-model hash=b8d6e3f357b740ad065e37c46eeb9b31dc170849db8bd8f8d468040ad2b47701 tm_hit=0 ok=1 finish="stop" degraded="" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
ch6/0 draft role=translator req=fake-model actual=fake-model hash=7b0dd4e5b9a7648c65e7c04b6dd928ff8e6d7dc74b3f4baf469058e8dbdf628f tm_hit=0 ok=1 finish="stop" degraded="" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
ch6/0 edit role=editor req=fake-model actual=fake-model hash=190b651aa53eb1991b5d2a3b75440190d3a5d9ef4b5226cd0bedfb938179de73 tm_hit=0 ok=0 finish="stop" degraded="sanitizer_defect" cost=0.00182 tokens=1000/200/0/500/0 err=""
|
||||
ch1/0 draft role=translator req=fake-model actual=fake-model hash=7bda1d23e4828d0f05f167f0980d6dcb31e6d7808175c3e934e512f25ec4d03f tm_hit=1 ok=1 finish="stop" degraded="" cost=0 tokens=0/0/0/0/0 err=""
|
||||
ch1/0 edit role=editor req=fake-model actual=fake-model hash=1d2aad2175e4e34c894709417460a3a4a395fc977e603f339327b1d302befcf5 tm_hit=1 ok=1 finish="stop" degraded="" cost=0 tokens=0/0/0/0/0 err=""
|
||||
ch1/1 draft role=translator req=fake-model actual=fake-model hash=96d877d33a55d992fa1a4d36fa13a0d97eb61324dda80296cce432f279991b96 tm_hit=1 ok=1 finish="stop" degraded="" cost=0 tokens=0/0/0/0/0 err=""
|
||||
ch1/1 edit role=editor req=fake-model actual=fake-model hash=15ca0e09a901d97cc9f4665196e60aa10ef1ece4a5abb8ac2ccf65355ee4af04 tm_hit=1 ok=1 finish="stop" degraded="" cost=0 tokens=0/0/0/0/0 err=""
|
||||
ch2/0 draft role=translator req=fake-model actual=fake-fallback hash=91bc556b12b7ee88771b870dcc872172a7edfa75b4cd0286fc6f9c9b1e030b50 tm_hit=1 ok=1 finish="stop" degraded="" cost=0 tokens=0/0/0/0/0 err=""
|
||||
ch2/0 edit role=editor req=fake-model actual=fake-model hash=4cb824da88d824dee2548f25c99a07af19d8e7a960dc12eb8a2dcfbfea565dfe tm_hit=1 ok=1 finish="stop" degraded="" cost=0 tokens=0/0/0/0/0 err=""
|
||||
ch3/0 draft role=translator req=fake-model actual=fake-model hash= tm_hit=1 ok=0 finish="" degraded="hard_refusal" cost=0 tokens=0/0/0/0/0 err=""
|
||||
ch4/0 draft role=translator req=fake-model actual=fake-model hash=cc910a514d60f6f02e6d31ab9f07777e11fe0009874edff9b0c65e5cabb68311 tm_hit=1 ok=1 finish="stop" degraded="" cost=0 tokens=0/0/0/0/0 err=""
|
||||
ch4/0 edit role=editor req=fake-model actual=fake-model hash=708b7d426e2f9464b4c32741e4367781ddbb89a6bf119ac08b1d77c71627c7fc tm_hit=1 ok=1 finish="stop" degraded="" cost=0 tokens=0/0/0/0/0 err=""
|
||||
ch5/0 draft role=translator req=fake-model actual=fake-model hash=0c1a34b813466396a5a9e8150200829fe4ea6cfec8eef999761194ae1ef6ba89 tm_hit=1 ok=1 finish="stop" degraded="" cost=0 tokens=0/0/0/0/0 err=""
|
||||
ch5/0 edit role=editor req=fake-model actual=fake-model hash=9d13216d51b230a9519b5afe640b83c25c2a3eb31f45efaa6889aef3acee2e09 tm_hit=1 ok=1 finish="stop" degraded="" cost=0 tokens=0/0/0/0/0 err=""
|
||||
ch6/0 draft role=translator req=fake-model actual=fake-model hash=6746c63437db911f9b3588d4ddcf8d6effb9f5131df8c7c4ce65cae2236c9534 tm_hit=1 ok=1 finish="stop" degraded="" cost=0 tokens=0/0/0/0/0 err=""
|
||||
ch4/0 draft role=translator req=fake-model actual=fake-model hash=887c72449d515b208d1473df5bfa91b0e0f5e2eec3850b967d2888413189bbc4 tm_hit=1 ok=1 finish="stop" degraded="" cost=0 tokens=0/0/0/0/0 err=""
|
||||
ch4/0 edit role=editor req=fake-model actual=fake-model hash=88be9923f7e6e6781b8eb9e02ffeea614003dc504b676e0cb54fe21ee1b239ba tm_hit=1 ok=1 finish="stop" degraded="" cost=0 tokens=0/0/0/0/0 err=""
|
||||
ch5/0 draft role=translator req=fake-model actual=fake-model hash=e723f314c5cd17a0f000c0bbac25812b42f414ae9d395d59ceb186ea65caed90 tm_hit=1 ok=1 finish="stop" degraded="" cost=0 tokens=0/0/0/0/0 err=""
|
||||
ch5/0 edit role=editor req=fake-model actual=fake-model hash=b8d6e3f357b740ad065e37c46eeb9b31dc170849db8bd8f8d468040ad2b47701 tm_hit=1 ok=1 finish="stop" degraded="" cost=0 tokens=0/0/0/0/0 err=""
|
||||
ch6/0 draft role=translator req=fake-model actual=fake-model hash=7b0dd4e5b9a7648c65e7c04b6dd928ff8e6d7dc74b3f4baf469058e8dbdf628f tm_hit=1 ok=1 finish="stop" degraded="" cost=0 tokens=0/0/0/0/0 err=""
|
||||
ch6/0 edit role=editor req=fake-model actual=fake-model hash= tm_hit=1 ok=0 finish="" degraded="sanitizer_defect" cost=0 tokens=0/0/0/0/0 err=""
|
||||
-- retrieval_state --
|
||||
ch1/0 snap_match=true exact=3 sticky=0 ambiguous=0 spoiler=1 evicted=0 postcheck_miss=1 style_flags=0
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# Журнал прогресса
|
||||
|
||||
> **⟶ ТЕКУЩЕЕ СОСТОЯНИЕ** (обновляемый блок; на 2026-07-12). **Источник истины по РЕШЕНИЯМ — `architecture/05-decisions-log.md` (D1–D31); этот файл — ЖУРНАЛ, не спека.**
|
||||
> - **Фаза:** 0 ✅; Ф1-машинерия ✅ (D21–D28); **приёмка этап A ✅ с оговорками (D24); этап B заморожен (D26) до читаемых 25 глав.** **exp12-диагностика ПРИНЯТА (D30): «нечитаемо» = пассивный моно-редактор + кривой сид + построчная вёрстка от промптов + нет санитайзера; дефекты смысла — в черновике.** Ратифицировано D30: **флип D1 моно→билингв** (supersede D17.в; re-gate верности на пере-прогоне обязателен), reflow-вёрстка (промпты чинятся), output-санитайзер (новый гейт-класс), глоссарий v2 условно (спорные → draft до подписи владельца), **exp13 бейк-офф ПЕРЕВОДЧИКОВ** (deepseek качеством не мерен — главный невыжатый рычаг), COGS флипа +15–25% (~$0.85/ранобэ; «$1.5–2» = отдельная опция Б). **exp13 ПРИНЯТ (D32): черновик flash СОХРАНЁН (pro отклонён), сид v2 под подпись владельца. Бэкенд-пакет D15.2 ЭТАП А ПРИНЯТ и залендён (D33, 00f8e36): билингв-редактор+reflow+санитайзер+golden — golden байт-в-байт, конфиг-флип D32 соблюдён; НО 2 обязательных фикса санитайзера до пере-прогона (D33.1: хвостовая утечка + false-positive «около колонны»). Этап Б/В D15.2 осознанно не начаты (Б трогает денежный resume-путь). Очередь: фикс санитайзера (`BACKEND_SANITIZER_FIX_SESSION_PROMPT.md`) ∥ подпись владельца сида → единый resnapshot (промпты+editor+санитайзер-фикс+сид v2) → пере-прогон 25 глав (flash+свзяка, budget_usd>0) с re-gate верности → чтение владельца → этап B.** Трек владельца: дешёвые модели сейчас, фронтир потом (архитектура конфиг-первая — D30.7). Решающая точка — пилот Ф2.5 (блокеры: билингв-якорь/аннотаторы ≥3 — D25.9-Q1, корпус, проба судьи-дублёра — D22.6).
|
||||
> - **Фаза:** 0 ✅; Ф1-машинерия ✅ (D21–D28); **приёмка этап A ✅ с оговорками (D24); этап B заморожен (D26) до читаемых 25 глав.** **exp12-диагностика ПРИНЯТА (D30): «нечитаемо» = пассивный моно-редактор + кривой сид + построчная вёрстка от промптов + нет санитайзера; дефекты смысла — в черновике.** Ратифицировано D30: **флип D1 моно→билингв** (supersede D17.в; re-gate верности на пере-прогоне обязателен), reflow-вёрстка (промпты чинятся), output-санитайзер (новый гейт-класс), глоссарий v2 условно (спорные → draft до подписи владельца), **exp13 бейк-офф ПЕРЕВОДЧИКОВ** (deepseek качеством не мерен — главный невыжатый рычаг), COGS флипа +15–25% (~$0.85/ранобэ; «$1.5–2» = отдельная опция Б). **exp13 ПРИНЯТ (D32): черновик flash СОХРАНЁН (pro отклонён), сид v2 под подпись владельца. Бэкенд-пакет D15.2 ЭТАП А ПРИНЯТ и залендён (D33, 00f8e36): билингв-редактор+reflow+санитайзер+golden — golden байт-в-байт, конфиг-флип D32 соблюдён; НО 2 обязательных фикса санитайзера до пере-прогона (D33.1: хвостовая утечка + false-positive «около колонны»). Этап Б/В D15.2 осознанно не начаты (Б трогает денежный resume-путь). Очередь: ~~фикс санитайзера~~ ЗАЛЕНДЁН (D33.1, ACCEPT) ∥ сид v2-финализация (полигон проставляет статусы по подписи владельца) → единый resnapshot (промпты+editor+санитайзер+сид v2) → пере-прогон 25 глав (flash+свзяка, budget_usd>0) с re-gate верности → чтение владельца → этап B.** Трек владельца: дешёвые модели сейчас, фронтир потом (архитектура конфиг-первая — D30.7). Решающая точка — пилот Ф2.5 (блокеры: билингв-якорь/аннотаторы ≥3 — D25.9-Q1, корпус, проба судьи-дублёра — D22.6).
|
||||
> - **Стек (пост-D32):** черновик — **deepseek-v4-flash СОХРАНЁН** (exp13/D32: смена на pro отклонена по данным — сфабрикованная сходимость + катастрофа 蛊→«гусеницы» + верность у flash не хуже; thinking ON; escalate_to=pro без изменений) · редактор — **БИЛИНГВ (D30.1), кандидат glm-5-билингв** (gemini — премиум-эскалация за санитайзером; grok reasoning-off из редакторов СНЯТ — no-op) · судья/апекс Gemini 3.1 Pro (**слаг `-preview`**; mandatory thinking; `additive_total` — D22.3) · эскалация A: DeepSeek V4 Pro → GLM-5.1 → Gemini-preview · **канал B (18+): Mistral · эскалация grok-4.3 reasoning-ON (⚠ не на архаичных zh — D22.5) · abliterated-скрининг · судьи: эротика — Grok (дублёр гейтится пробой D22.6), violence/SFW — Grok+Gemini** (DeepSeek в explicit запрещён ToS — D14.1). 7 ключей.
|
||||
> - **Экономика:** `experiments/08-cost-model-v2.md` — до-флиповый ~$0.69 ранобэ / ~$10.94 вебновелла-500; **после флипа D1 → ~$0.85/ранобэ (+15–25%, D30.4)**; «$1.5–2» = опция Б (селективный апекс+память, НЕ подписана); пере-съём = exp08 v3 (D21.8/D25.8). ⚠ Resume: любой `--resnapshot` = переоплата книги — онгоинг гейтится реализацией D15.2 (идёт, D30.9). Gemini-недоучёт 146×/вызов закрыт additive_total (D22.3).
|
||||
> - **Ждём от владельца:** **подпись спорных терминов сида v2** (修炼/культивация · 人祖/Первопредок · род «гу» · 花酒行者 — таблицу даст exp13) · **флагман-сверка exp13** (переводчики, monitor-паттерн) · DashScope-ключ для qwen-арма exp13 (опционально) · **планка запуска** (лучше-фана/гибрид/издательский + готовность к COGS опции Б ~$1.5–2 — мемо-эскалация exp12; интерим D30.7: «лучше фана» на дешёвом миксе) · решение по билингв-якорю пилота (D25.9-Q1) · «да/нет» митигации контаминации пилотного корпуса (D27.4) · publishable/waiver — при экспорте (D25.1) · FN-bound L3 — при спеке (D25.4) · провенанс 12-*-доков · юр-пакет (+rights manifest, D25.8).
|
||||
|
|
@ -165,6 +165,22 @@
|
|||
- **Спека D15.2 доведена до v3.1** (§0-бис: D22.2-амендменты — `SourceLang`/`TargetLang`→`verdictSnapshotID` (cjk-gate/coverage-коридор вне рендера; editor.md не рендерит target_lang), `Context.CacheTTL` демотирован до advisory (wire-инертен — `clients.go:38` шлёт `prov.CacheTTL`), `prov.CacheTTL`→`wireSnapshotID`; axis-тест `RequestHash` §12.9; паритетные не-цели §8 (classify-Source editor-строк, Retries/BudgetUSD вне ключа, транспорт); line-ref-нот про рефактор D23). Реализация РАЗБЛОКИРОВАНА в спеке.
|
||||
- **Реализация Б (три хеша/guard_hash/verdict-split/миграция v8/fast-path v2/dry-run+--accept-rebill) и В (`tmctl export`/annotations/цвет-мап/override) — НЕ начаты этой сессией.** Осознанное решение: Б трогает денежно-критичный resume-путь (`RequestHash`, fast-path), где рывковая частичная реализация рискует ровно минами F1/D15 (тихая переоплата / stale-serve), а безопасный лендинг Б связан (fast-path снимает loud-гейт согласия → dry-run обязан его заменить, §7) — всё-или-ничего. Бюджет сессии ушёл на гейтящий этап А (полный цикл + ревью, поймавшее 14 реальных FP санитайзера) + v3.1-спеку. Хендофф чистый: спека v3.1 = дизайн-оф-рекорд, план §12 + тест-лист §12.9 готовы для следующей бэкенд-сессии. Дерево -race зелёное на границе А.
|
||||
|
||||
### 2026-07-12 (мини-сессия D33.1/33.2 — 2 обязательных фикса санитайзера + golden re-capture, гейтят пере-прогон) — ЗАВЕРШЕНО
|
||||
|
||||
По `BACKEND_SANITIZER_FIX_SESSION_PROMPT.md`. **Ничего не закоммичено** (лендинг — оркестратор). `go build ./... && go vet ./... && go test -race ./...` — все пакеты зелёные; gofmt чисто. Зона: только `backend/` (3 файла: `sanitizer.go`, `sanitizer_test.go`, `testdata/golden/capture.golden`). Чужой untracked `eval/exp13_seed_signoff.py` (полигон) НЕ трогал. **Все 4 фикса/пина mutation-verified исполнением** (revert→FAIL, restore→ok — по каждому в изоляции).
|
||||
|
||||
**Сделано:**
|
||||
|
||||
1. **[major D33.1а] Хвостовой класс теперь ловит «Основные правки для справки:».** В `editMetaAnywhereRE` добавлена high-precision альтернатива `основн…правк…` — гейтится «… для справки» ИЛИ двоеточием, так что нарративное «Основные правки внёс редактор газеты» (без summary-метки) НЕ фаерит. Ловит и «Основные правки для справки:» (утечка A5/5_1, exp12:229), и colon-вариант «Основные правки:». Пины: 2 fire-теста, воспроизводящие СТРУКТУРУ утёкшего блока (заголовок + список правок; копирайтную главу не встраивал — диагностика в заголовке) + 1 clean-пин на нарративную форму без метки.
|
||||
|
||||
2. **[major D33.1б] Класс junction-дубликации СНЯТ (опция (б)), НЕ сужен.** Разобрал: опция (а) «перекрытие ≥ бо́льшей части ОБОИХ токенов» математически обратна — все четыре кейса (три FP + единственный синтетический реальный «Первопред предок») делят overlap РОВНО 4 руны, причём у реального кейса доля перекрытия НИЖЕ (4/9) чем у FP (4/5); никакой порог на длину/долю overlap их не разделяет, а канонический «Первок предок» не ловился и так (recall-gap). Класс ловил мало реального и много ложного на частом предлоге «около» → флаг-шторм на 25 главах. Убраны `junctionDuplicated`, конста `junctionOverlap`, петля в `detectBrokenWords`; остались две ZERO-FP сигнатуры (невалид-знак ь/ъ, гомоглиф кир+лат). Пины: 3 clean-кейса «около колонны»/«около колодца»/«стало талой» (mutation: восстановил детектор → все три фаерят). `TestSanitizerBrokenWordRecallGap` сохранён (assertion как есть; коммент обновлён — «Первок предок» по-прежнему не ловится, теперь by-design).
|
||||
|
||||
3. **[minor D33.2] Быстрые сужения (в тот же resnapshot, не блокеры):** (а) markdown-заголовок требует букву/цифру после хешей → декоративные сцен-брейки «# # #», «## ***», «### ---» больше не фаерят (пины + fire «### 1. Вступление»); (б) heavy-латиница исключает капитализированные бренд-токены из счёта (`hasUpperLatin`) → список «iPhone, iPad, MacBook, Apple Watch, Google Pixel» не фаерит, а лоуэркейс-англ-фраза ловится фразовым детектором (пин). Хвостовые «Примечание:»/«Комментарий:» уже ловятся `trailingNoteRE` — без правки. Разговорный префикс «Конечно!/Готово!» и recall-gap «Первок предок» — приняты как границы (не трогал).
|
||||
|
||||
4. **Golden re-capture (`TM_UPDATE_GOLDEN=1`) — дифф-класс РОВНО санкционированный.** `sanitizerVersion` `sanitizer-v1`→`v2` (правка правил = loud --resnapshot, инвариант №8). Аудит диффа исполнением: маскированный дифф (все hex-хеши + версия → плейсхолдер) **ПУСТ** — т.е. изменились ТОЛЬКО `snapshot_id` + `snapshot_payload` (строка `"version":"sanitizer-v2"`, дважды: fresh+resume) + каскад request/content-хешей, ключёванных на snapID. Ноль дрейфа disposition/flag/final_text/cost/postcheck_miss/injected_ids/term-order; 0× `snap_match=false`; счётчик строк 206=206. Фикстура ch6 упражняет только класс Preamble (не затронут) → новых санитайзер-вердиктов НЕТ, только version-fold-каскад. Другого класса диффа нет → стоп/пинг не потребовался.
|
||||
|
||||
**Итог по вопросу промта («сузил/снял»):** класс «битые словоформы» — junction-подкласс **СНЯТ** (precision-обоснование выше); два high-precision подкласса сохранены.
|
||||
|
||||
## Полигон
|
||||
(секция параллельной сессии — записи добавлять сюда)
|
||||
|
||||
|
|
|
|||
|
|
@ -418,6 +418,10 @@ D1 остаётся дефолтом Фазы 1 (менять конфигура
|
|||
5. **Этап Б (реализация content-addressed resume) и В (`tmctl export`/annotations/override) — НЕ начаты, осознанно** (backend): Б трогает денежно-критичный resume-путь (RequestHash/fast-path) — рывковая частичная реализация рискует минами F1/D15 (тихая переоплата/stale-serve); Б связан (fast-path снимает loud-гейт согласия → dry-run обязан заменить §7 — всё-или-ничего). Спека v3.1 = дизайн-оф-рекорд, план §12 + тест-лист §12.9 готовы. **Порядок правильный: этап А гейтит пере-прогон, Б/В — нет.** Промт следующей бэкенд-сессии на Б+В — выдам после пере-прогона (исход чтения может уточнить экспорт-требования В).
|
||||
6. **Дорожка:** обязательные фиксы санитайзера (п.1) — быстрый backend-follow-up ∥ подпись владельца сида v2 (D32) → **единый resnapshot** (промпты+editor+санитайзер-фикс+сид v2) → пере-прогон 25 глав (flash+свзяка, `escalation.budget_usd>0` — D22.11, иначе echo-эскалация не стреляет) с re-gate верности → чтение владельца → этап B.
|
||||
|
||||
## D33.1 — ЗАКРЫТ (12.07): 2 обязательных фикса санитайзера залендены и приняты. ✅
|
||||
|
||||
Мини-сессия по `BACKEND_SANITIZER_FIX_SESSION_PROMPT.md`. Верификация исполнением (сфокусированный агент в scratchpad-копии, все 6 осей): **ACCEPT, залендено.** (а) хвостовой класс теперь ловит «Основные правки для справки:» (gemini-утечка A5/5_1) + colon-вариант, НЕ фаерит нарратив «Основные правки внёс редактор» — 2 fire + 1 clean-пин; (б) класс «битые словоформы» СНЯТ целиком (backend-разбор: порог не отделяет «около колонны» от «Первок предок», у реального доля перекрытия даже ниже; канонический дефект и так не ловился → умнее убрать шумный класс, чем подкручивать), оставлены 2 zero-FP сигнатуры (невалид ь/ъ, кир+лат гомоглиф) — 3 clean-пина «около колонны/колодца», «стало талой»; мелочи D33.2 (# # #-разделители, латиница-бренды) сужены. Golden re-capture — дифф-класс РОВНО version-fold (sanitizer-v1→v2; маскированный дифф пуст, 0 дрейфа disposition/flag/final_text/cost/postcheck/injected_ids/term-order, 206=206, регенерация байт-в-байт). build/vet/test-race зелёные, скоуп 3 файла + журнал, stdlib-only, контрабанды нет. **Принятая граница (документируется рядом с recall-gap «Первок предок»):** строка-ОПЕНЕР абзаца «Основные правки … для справки предоставил …» ещё фаерит — редакторский регистр, не проза; неизбежная поверхность «для справки»-гейтящей сигнатуры (снять = потерять целевую gemini-утечку); precision-over-recall → редкий FP деградирует один чанк, не портит выход. **Санитайзер как блокер пере-прогона снят** (D33.6-предусловие №1 закрыто); остаётся сид v2-финализация (полигон) + единый resnapshot.
|
||||
|
||||
## Сопутствующие правки доков (оркестратор, 09.07)
|
||||
|
||||
`02-mvp-plan.md` → v3 (мёртвые пороги/интерим-18+/фазовые списки синхронизированы с D-логом); обе `*.puml` → v3 (убраны Opus/BYOK/«≤2×», дорисованы ре-гейт эскалации, три класса отказов D12, человек в петле, фазовые пометки); superseded-баннеры на `research/01, 02, 03, 04, 09`; провенанс-шапки на `research/12-architecture-as-antipattern.md` и `12-common-failures.md` (происхождение не зафиксировано — до уточнения владельцем числа оттуда не абсорбировать как факты); закрытые промты → `docs/archive/prompts/`; онбординг: корневой `CLAUDE.md` + `backend/README.md` + `eval/README.md`.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue