Skip to content

Commit eab1135

Browse files
sintjuricursoragent
andcommitted
Replace tool-critic soft-publish with thin DeepSeek translation gates.
Whole-file translate is now raw Markdown in/out; Python fail-closed gates block source-locale echo, split-backtick mangling, and missing includes. Tool-using critic is removed from the production review path. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent e4baa4f commit eab1135

14 files changed

Lines changed: 566 additions & 444 deletions

File tree

‎REQUIREMENTS_RU.md‎

Lines changed: 84 additions & 235 deletions
Large diffs are not rendered by default.

‎knowledge/INDEX.md‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22

33
Только подтверждённые решения. При конфликте побеждает `REQUIREMENTS_RU.md`.
44

5-
- `architecture.md` — режимы и инварианты
6-
- `translation-algorithm.md` — scope, перевод, TOC, critic/arbiter
5+
- `architecture.md` — режимы и инварианты (thin pipeline)
6+
- `translation-algorithm.md` — scope, thin translate, gates, arbiter
77
- `model-api.md` — DeepSeek contracts
88
- `testing.md` — TDD и witnesses
99
- `delivery.md` — commits в `main`
1010
- `current-status.md` — что согласовано и где код
11-
- `debt-map.md` — срезы выравнивания кода под контракт
11+
- `debt-map.md` — исторические срезы выравнивания
1212
- `blobdepot-golden-plan.md` — P2 BlobDepot offline golden (done)
13-
- `tool-using-critic-plan.md` — rollout tool-using critic (P0 PASS; P1 offline green; P2 live next)
14-
- `p0-deepseek-tools-probe.md` — live DeepSeek tool_calls multi-turn proof
13+
- `tool-using-critic-plan.md` — **архив** (tool-critic снят с production)
14+
- `p0-deepseek-tools-probe.md` — исторический live tools probe
1515

1616
Не хранить секреты, полные transcripts, черновики агентов.

‎knowledge/architecture.md‎

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,27 @@
44

55
## Поток
66

7-
`label → snapshot → (budget) → direction → Python scope → translate/TOC/ops →
8-
draft commit → critic tool-workspace (patch+re-read → reviewed push) →
9-
arbiter judge-only (GREEN/YELLOW/RED) → QA comment`.
7+
`label → snapshot → (budget) → direction → Python scope → thin translate/TOC/ops
8+
→ publication gates → publish reviewed → arbiter (GREEN/YELLOW/RED) → QA comment`.
109

1110
| Режим | Translator | Budget gate | Ветка |
1211
|---|---|---|---|
13-
| `doc_translate` | да | да | удалить старую, создать чистую |
14-
| `doc_verify` | нет | нет | та же; critic пушит правки |
12+
| `doc_translate` | да (thin) | да | удалить старую, создать чистую |
13+
| `doc_verify` | нет | нет | та же; gates + arbiter |
1514
| `doc_continue` | только pending / direction | нет | та же; + operator context |
1615

1716
## Владение
1817

19-
- **Python:** inventory, Git-операции, dependency closure, protected fragments,
20-
TOC structural delta, publication, checkpoints.
21-
- **DeepSeek:** нужен ли перевод + направление; whole-file prose; TOC strings;
22-
critic tool edits (patches); arbiter verdict/findings only.
18+
- **Python:** inventory, Git-операции, dependency closure, TOC structural delta,
19+
publication gates, publication, checkpoints.
20+
- **DeepSeek:** нужен ли перевод + направление; thin whole-file prose; TOC
21+
strings; arbiter verdict/findings only.
2322
- Модель **не** назначает per-file semantic actions.
23+
- Tool-using critic **не** в production path.
2424

2525
## Публикация и verdict
2626

27-
- Любой собранный UTF-8 файл публикуется. Diagnostics ≠ gate.
27+
- В ветку только файлы, прошедшие publication gates. Полу-EN запрещён.
2828
- GREEN / YELLOW = успех, checkpoint закрыт.
2929
- RED = неуспех, checkpoint открыт (`/ydbdoc continue` или ручная правка +
3030
`doc_verify`).

‎knowledge/current-status.md‎

Lines changed: 20 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,86 +1,32 @@
11
# Текущее состояние
22

3-
## Согласованный контракт (2026-10-02 redesign + 2026-10-03 critic tools)
3+
## Согласованный контракт (thin pipeline, 2026-10-04)
44

55
Semantic flow в `REQUIREMENTS_RU.md`:
66

77
1. Файлы PR + дотянутые missing-target зависимости.
88
2. Direction: только «нужен перевод?» + направление (Python владеет Git-ops).
9-
3. Prep: placeholders + **identifier atoms** (underscore + CamelCase product) +
10-
presentation map from old target (atoms, CLI flags, short ALLCAPS, colon-form).
11-
4. Whole-file translate (old target = presentation reference only when present) → **draft**.
12-
5. Critic = обязательный tool-using gate (§4.1): DeepSeek всегда, scope =
13-
source PR delta + previous EN; Python drop out-of-delta findings;
14-
workspace + read/grep/apply_patch + mandatory re-read → **reviewed**.
15-
6. Arbiter только на reviewed bytes: GREEN / YELLOW / RED (judge-only, no repair).
9+
3. Thin whole-file DeepSeek (или unique string replacements без модели).
10+
4. Publication gates fail-closed: source-locale echo, split-backtick, missing
11+
includes. Один retry; иначе null.
12+
5. Tool-using critic **снят**. Reviewed = gated publish.
13+
6. Arbiter на reviewed bytes: GREEN / YELLOW / RED (judge-only, no repair).
1614
7. YELLOW = успех; RED = continue / ручная правка + `doc_verify`.
17-
8. Soft-publish diagnostics ≠ reader-facing product success.
18-
9. Режимы: `doc_translate`, `doc_verify`, `doc_continue`.
15+
8. Режимы: `doc_translate`, `doc_verify`, `doc_continue`.
1916

20-
## Код vs новый critic contract (2026-10-03)
17+
## Live evidence that forced the cutover
2118

22-
| Item | Status |
23-
|---|---|
24-
| Identifier atoms / presentation map / draft-reviewed gate | **DONE** (prior) |
25-
| P2 BlobDepot golden harness (one-shot critic era) | **DONE** (prior) |
26-
| REQUIREMENTS §4.1 tool-using critic | **DONE (docs)** + adversarial fixups |
27-
| Plan `knowledge/tool-using-critic-plan.md` | **DONE (docs)** + adversarial fixups |
28-
| Runtime tool loop / client `tool_calls` | **DONE** P1a–g offline + P2 live smoke |
29-
| P0 live DeepSeek tools capability probe | **PASS / GO** — `knowledge/p0-deepseek-tools-probe.md` |
30-
| Offline stub-tool integration tests | **PASS** (`pytest -m 'not live'`, 2026-10-03) |
31-
| P2 live tool-critic smoke (`--wait wait`) | **PASS** (2026-10-03) — `tests/live/test_tool_critic_live.py` |
19+
- [#54993](https://github.com/ydb-platform/ydb/pull/54993) / [#55003](https://github.com/ydb-platform/ydb/pull/55003)
20+
(source [#46837](https://github.com/ydb-platform/ydb/pull/46837)): critic
21+
burn / mangled identifiers.
22+
- [#54994](https://github.com/ydb-platform/ydb/pull/54994) (source
23+
[#42314](https://github.com/ydb-platform/ydb/pull/42314)): CI `recovery.md`
24+
published with **41 lines still Russian**; critic budget RED.
25+
- Local PoC: same scope via thin DeepSeek → 8/8 OK, 0 Cyrillic, 0 mangling
26+
(`SINTJURI_SECRET_KEY` + `YANDEX_CLOUD_FOLDER`).
3227

33-
> [!success] Local BlobDepot critic+arbiter → GREEN (YC grant)
34-
> Arbiter noise from [#54927](https://github.com/ydb-platform/ydb/pull/54927) fixed:
35-
> default-GREEN prompt, drop bad snippets / «не требуется», drop source-only TOC
36-
> demands (`selfheal.md`). Live harness PASS GREEN
37-
> (`scripts/probe_blobdepot_critic_live.py`, research
38-
> `knowledge/blobdepot-critic-research.md`). Residual prose (`Blob depot`) may
39-
> remain editorial but no longer blocks the gate.
28+
## Tip pin
4029

41-
## Critic TRANSPORT (runs 37009373894 → 37027975808) — real root cause
42-
43-
Not «provider flaky». Translator OK; critic 2× `TRANSPORT`, `http_status=null`.
44-
45-
| Run | tip | wall per critic attempt | limiter |
46-
|---|---|---|---|
47-
| 37009373894 | pre-timeout bump | ~182s | **our** urllib 180s |
48-
| 37027975808 | `4f2867c` (600s) | ~273s | **provider** silent wall |
49-
50-
Fix on tip: one pair/chunk, relevant glossary only, cap `max_output_tokens`.
51-
Tool-using critic keeps one-pair chunking; patches shrink generation further.
52-
53-
## Quality classes on #54842 / #54888 lineage
54-
55-
Manual review of [#54888](https://github.com/ydb-platform/ydb/pull/54888)
56-
(source [#50839](https://github.com/ydb-platform/ydb/pull/50839) BlobDepot):
57-
structure/links/images largely OK; residual prose/literals (`--wait wait`,
58-
awkward phrasing, inconsistent inline-code). Whole-file critic did not reliably
59-
apply fixes. Tool-using critic is the agreed remedy (not arbiter↔repair loops).
60-
61-
## BlobDepot translation lineage (2026-10-03 P2)
62-
63-
- Source: [#50839](https://github.com/ydb-platform/ydb/pull/50839) (merged)
64-
- Stale [#54888](https://github.com/ydb-platform/ydb/pull/54888) closed; branch
65-
`translation/pr-50839` deleted.
66-
- New open translation: [#54924](https://github.com/ydb-platform/ydb/pull/54924)
67-
- Workflow: [37100488317](https://github.com/ydb-platform/ydb/actions/runs/37100488317)
68-
(`doc_translate` label on #50839, action `@v1.0.1` = tip `164f3e6`)
69-
70-
## Live clean re-run history
71-
72-
- 2026-10-02: tip then produced #54877 → … → **#54888** (one-shot critic era).
73-
- 2026-10-03: P2 tool-critic live PASS; clean re-run → **#54924** (workflow in progress).
74-
75-
## YC / live model env (names found vs missing)
76-
77-
**Found:** `YANDEX_API_KEY`, `YANDEX_FOLDER_ID`, `YDBDOC_MODEL*`,
78-
`YDBDOC_MODEL_HTTP_TIMEOUT_SECONDS`, `YDBDOC_DAILY_BUDGET_RUB`, `YDBDOC_LIVE`,
79-
smoke aliases `YC_API_KEY` / `YDBDOC_YC_API_KEY` / `YC_FOLDER_ID` /
80-
`YDBDOC_MODEL_TRANSLATE`, hardcoded `OPENAI_ENDPOINT` / `NATIVE_ENDPOINT`.
81-
82-
**Missing for grant-limited paid tests:** grant id / remaining quota env names;
83-
unified live creds (prod `YANDEX_*` vs smoke `YC_*`). DeepSeek tool_calls
84-
proof: **done** (`knowledge/p0-deepseek-tools-probe.md`). Production tools
85-
feature-flag dual-path **rejected** (rollback = tip revert). Details:
86-
`knowledge/tool-using-critic-plan.md`.
30+
Workflow `ydbdoc-review.yml` uses
31+
`ydb-platform/ydbdoc-review-ng/.github/actions/doc-review@v1.0.1`.
32+
Move `v1.0.1` with thin-pipeline tip after push.

‎knowledge/model-api.md‎

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,27 @@
11
# Модели и response contracts
22

3-
Production: DeepSeek V4 Flash для direction, translator, TOC strings, critic,
3+
Production: DeepSeek V4 Flash для direction, thin translator, TOC strings,
44
arbiter. YandexGPT только в `doc_model_probe`.
55

66
Контекст 1 048 576. `max_tokens` = остаток после размера полного wire request
77
в UTF-8 bytes (для этого расчёта 1 byte = 1 token). Не путать с рублёвым
8-
дневным бюджетом. `NON_FINAL` → чанк непроверен, итог RED.
8+
дневным бюджетом.
99

1010
## Контракты
1111

1212
- Direction: только `translation_required`, `direction`, `reason`. Per-file
1313
mirror actions считает Python (`mirror_classified_files`), не модель.
14-
- Translator / TOC strings: полная JSON ID-map запрошенных сегментов.
15-
- Critic (canon §4.1): OpenAI tool loop на workspace — `read`, `grep`,
16-
`apply_patch`, `finish`; mandatory re-read after patches; published bytes =
17-
runtime-applied workspace. Whole-file `{"files":…}` **не** primary path.
18-
Пустой scope → no-op `finish`. Plan: `tool-using-critic-plan.md`.
14+
- Translator (thin): полный target Markdown; developer prompt фиксирует YFM /
15+
no split-backtick / no whole-file fence. JSON segment map → reject.
16+
- TOC strings: JSON ID-map запрошенных сегментов.
17+
- Critic tools: **сняты** с production. Quality gate = Python publication gates.
1918
- Arbiter: только `verdict` + `findings`. GREEN → пустые findings; YELLOW/RED →
2019
≥1. Missing/unreviewed → `null` line/snippet. No repair loop.
2120

22-
`reasoning_effort` (tip): critic `medium`, arbiter `none`, else `none`.
21+
`reasoning_effort` (tip): arbiter `none`, else `none`.
2322

24-
Один retry на provider/malformed/protocol для direction, translator, critic,
25-
arbiter. Critic без успешного `finish` не публикует reviewed bytes.
23+
Один retry на provider/malformed для direction, translator, arbiter.
24+
Publication gates: один retry translator, затем null.
2625

2726
Attempts аудируются с cost; unknown = `NULL`. Секреты только из env/GitHub
2827
secrets.
29-
30-
## Clients today vs tools
31-
32-
`YandexOpenAIClient` / `NativeYandexClient` ещё **не** шлют `tools` и не
33-
парсят `tool_calls` (`clients.py`). P0 live probe **PASS**: DeepSeek returns
34-
`finish_reason=tool_calls` with `content=null` and accepts `role=tool`
35-
round-trip (`knowledge/p0-deepseek-tools-probe.md`). P1c must not map that
36-
shape to `NON_FINAL` / `EMPTY_TEXT`.

‎knowledge/translation-algorithm.md‎

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,27 +11,22 @@
1111
6. Лимиты: `YDBDOC_MAX_DEPENDENCY_FILES_PER_ARTICLE` (группа статьи),
1212
`YDBDOC_MAX_SOURCE_CHARACTERS` (один файл).
1313

14-
## Prep + Translator
14+
## Thin translator
1515

16-
Placeholders + identifier atoms (не рвать `BS\_CONTROLLER` на ESCAPE).
17-
Если есть old target и source before/after PR (merged: parent/merge, не
18-
текущий `main`): surgical update (уникальные URL/строки без модели, иначе
19-
модель только на hunks, Markdown с placeholders). Иначе целый файл одним
20-
Markdown request. Hunk: old target = semantic baseline. Whole-file fallback:
21-
presentation reference. Restore placeholders из source. Без глобального
22-
presentation map на unique dest. Собранный UTF-8 → **draft** soft-publish
23-
(diagnostics ≠ product).
16+
Unique string replacements без модели, если возможно. Иначе **thin whole-file**:
17+
полный source Markdown → DeepSeek → полный target Markdown. Placeholders нет.
18+
После ответа: normalize split-backtick, затем publication gates
19+
(`source_locale_echo`, `split_backtick_identifiers`, `missing_include_target`).
20+
Один retry; провал → файл null, не soft-publish полу-EN.
2421

2522
## TOC
2623

2724
Python: source TOC before/after → дельта → apply к target TOC. DeepSeek:
2825
только новые/изменённые видимые строки. Нет target TOC → только entries этого
2926
PR. Покрыть тестами.
3027

31-
## Critic / arbiter
28+
## Quality / arbiter
3229

33-
Critic: tool-using DeepSeek всегда, включая unique dest. Задание — source
34-
delta + previous EN, не весь файл. Патч вне touched lines отклоняется.
35-
Fail/503/protocol/unreviewed → RED; arbiter на сырой dump не вызывается.
36-
Arbiter: тот же scope; Python drop out-of-delta findings → GREEN если дельта
37-
верна. YELLOW не открывает checkpoint.
30+
Tool-using critic снят. Reviewed = gated publish. Arbiter: scope = PR delta +
31+
previous EN; Python drop out-of-delta findings. YELLOW не открывает checkpoint.
32+
RED на дырах / unreviewed / arbiter findings.

‎src/ydbdoc_review_ng/quality/repair.py‎

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -413,15 +413,15 @@ def build_critic(chunk_pairs: Sequence[tuple[str, str]]) -> ModelRequest:
413413
def fits(request: ModelRequest) -> bool:
414414
return _request_fits(executor, request, request_fits)
415415

416-
critic_chunks = _pack_pair_chunks(pairs, build_request=build_critic, fits=fits)
417-
packed_targets = {target for chunk in critic_chunks for _source, target in chunk}
418-
for _source, target in pairs:
419-
if target not in packed_targets:
420-
mark_unreviewed((target,), "context")
421-
if not inventory_pairs:
422-
critic_chunks = ((),)
423-
elif not pairs:
424-
critic_chunks = ()
416+
# Thin pipeline (§4.1 cutover): tool-using critic removed. Translate-time
417+
# publication gates are the quality gate; successful draft bytes are reviewed.
418+
# Missing required targets stay unreviewed RED. Arbiter still judges below.
419+
for _source, target in inventory_pairs:
420+
if translated_files.get(target) is None:
421+
mark_unreviewed((target,), "missing")
422+
critic_chunks: tuple[tuple[tuple[str, str], ...], ...] = ()
423+
_unused_tool_critic = (build_critic, on_successful_critic_chunk)
424+
del _unused_tool_critic
425425

426426
for chunk_pairs in critic_chunks:
427427
target_paths = tuple(target for _source, target in chunk_pairs)

0 commit comments

Comments
 (0)