Skip to content

Proof: a dispatched campaign hands the dual proof its lane run ids (V5b2d-4e) - #553

Merged
lemone112 merged 6 commits into
mainfrom
v5b2d-4e-lane-run-collection
Aug 7, 2026
Merged

Proof: a dispatched campaign hands the dual proof its lane run ids (V5b2d-4e)#553
lemone112 merged 6 commits into
mainfrom
v5b2d-4e-lane-run-collection

Conversation

@lemone112

@lemone112 lemone112 commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

Что это

Полное покрытие домена — это 512 отдельных прогонов воркфлоу (256 полос на движок). Дуальному доказательству нужен список их идентификаторов, и собрать его было нечем: координатор печатает команды gh workflow run, которые id не возвращают, а собирать по времени создания ломается, как только пересекаются две кампании.

Это прямой блокер запуска доказательства — даже при полностью живом GitHub.

Что добавлено

Режим сбора: по evidence-прогону и плану находит прогоны полос по их именам (в PR #549 полоса получает run-name с координатами) и выдаёт машинно-читаемый список в --out.

Архитектура — принятая в модуле: нечистое наблюдение отдельно, чистое сопоставление имён с планом отдельно и покрыто тестами, отказ типизированный, наблюдение проецирует белый список полей, а не сырой объект прогона.

Неполный сбор — типизированный отказ, а не тихий частичный список. Ничего не пишется: частичный список идентификаторов читается потребителем ровно как полный. В отказ выводится, каких окон не хватает и какие задвоены.

Что нашла независимая проверка и что исправлено

Проверяющий прогнал 11 мутаций, переживших набор. Три из них — один класс: инвариант объявлен в коде и в комментарии рядом, а теста нет.

Второй движок не проверялся ни разу — самая дорогая находка. Оба движка реплеят одну evidence-сборку, поэтому листинг несёт обе кампании. Мутант с захардкоженным первым артефактом отвечал на запрос MPFI идентификаторами Arb и выходил с кодом 0. Половина дуального доказательства, тихо неверная, отрапортованная как успех. Все CLI-кейсы использовали только Arb, поэтому различить было нечем.

Охранник пересечения окон — театр в буквальном смысле. Его докстринг называет пересечение «единственным, что не должно пройти», а в наборе отказов не было ни одного пересекающегося плана: тот кейс, что был, падал на соседней проверке длины кортежа. Теперь в наборе есть план из двух окон, делящих ординал.

Дедупликация по идентификатору прогона — та же форма: повторяющийся листинг не должен фабриковать отказ «покрытие задвоено», и снятие проверки оставляло набор зелёным.

Каждая починка доказана убитым мутантом, по одному тесту на каждый: захардкоженный артефакт на пути сбора, window[0] < cursor ослабленное до тавтологии, безусловный append.

Проверки

  • 31 тест диспетчера, 0 падений.
  • Полный набор на Linux (WSL): 429 тестов, 3 падения — все предсуществующие в test_build, воспроизведены на нетронутом дереве.
  • Дрейфа пинов инвентаря нет.
  • Сырых дампов API нет.

Зависимость

Полезен вместе с #549, где полоса получает run-name с координатами. Без него сопоставление по именам не имеет опоры.

Откат

Ревертом одного коммита. Новый режим аддитивен, существующие пути не затронуты.

Summary by CodeRabbit

  • Новые возможности

    • Добавлен режим collect для поиска успешных verification-запусков и проверки полного покрытия плана.
    • Результаты можно сохранять в формате JSON.
    • Добавлен параметр --run-limit для ограничения количества запрашиваемых запусков.
    • Система выявляет пропущенные, дублированные и некорректные запуски.
  • Исправления

    • Добавлена обработка повреждённых данных, неуспешных запусков и ошибок получения сведений.
    • Результаты не сохраняются при неполном покрытии плана.

Claude Code added 2 commits August 6, 2026 23:22
…5b2d-4e)

Наблюдаемый дефект: полное покрытие домена — 512 отдельных прогонов полос (256
на движок), и дуальному доказательству нужен список их идентификаторов. Собрать
его нечем: `corpus_dispatch.py` печатает команды `gh workflow run`, а они id не
возвращают; сбор по времени создания ломается ровно там, где он и нужен — два
движка реплеят одни и те же окна одной evidence-сборки одновременно.

Закон: прогон полосы назван своими координатами (`verification-lanes.yml`
рендерит `lane <artifact> <start>+<points> of <evidence_run_id>`), поэтому
список кампании — запрос по именам, а не догадка по часам. Кампанию отделяют
артефакт и evidence run id, не время.

Режим `--mode collect` устроен по границе, уже принятой в модуле:

- `gh_lane_runs_v1` — единственное нечистое наблюдение. Проекция сделана самим
  `--jq` в запросе, поэтому в процесс входят ровно три поля (databaseId,
  displayTitle, conclusion) и ни одно непросмотренное поле ответа API не может
  попасть ни в решение, ни в лог. Запись, которая не проецируется точно,
  отвергается, а не угадывается.
- `match_lane_runs_v1` — чистое сопоставление имён с планом. Все правила —
  чья кампания, чей движок, какое заключение считается, что такое полное
  покрытие — достижимы тестом без сети.
- `collect_lane_runs_v1` — шов между ними: недоступный API, отсутствующий
  токен или нечитаемый ответ становятся типизированным отказом с причиной, а
  не пустой кампанией; пустая кампания и сломанный запрос ведут оператора к
  противоположным действиям.

Неполный сбор — типизированный отказ `LaneRunCollectionRejectedV1`, а не тихий
частичный список: окна без прогона и окна с двумя едут в нём данными
(`missing`/`duplicated`), оператор передиспатчит ровно их, а CLI не пишет
ничего и выходит 64. Частичный список неотличим от полного для того, кто
прочитает его следующим.

Парсер имени допускает ровно канонический рендеринг: `int()` принял бы `+7`,
`007`, `1_0` и не-ASCII цифры, и каждое из них позволило бы чужому заголовку
занять окно плана.

Доказательства (WSL, python3 -m unittest):

- RED до реализации: 17 ошибок «module 'corpus_dispatch' has no attribute
  parse_lane_run_name_v1 / match_lane_runs_v1 / collect_lane_runs_v1».
- 19 новых тестов; каждый заявленный класс убивает мутацию:
  порядок плана → порядок наблюдения (M1); дыра терпится (M2);
  дубль терпится (M3); фильтр артефакта снят (M4); фильтр evidence run снят
  (M5); заключение игнорируется (M6); ordinals по `isdigit()` (M7);
  `except Exception` сужен до `OSError` на шве наблюдения (M8).
  Все восемь падают на финальном коде.
- Контакт с реальностью: `gh run list --workflow verification-lanes.yml --json
  databaseId,displayTitle,conclusion --jq ...` на живом репозитории возвращает
  реальные записи; `--mode collect` против прогона 31104030757 отказывает с
  256 missing и не пишет ничего (в `main` run-name ещё нет — он приходит с
  V5b2d-4d, до него ни один заголовок не является полосой кампании).
- Набор proof: 427 тестов, 3 падения — ровно предсуществующие в test_build на
  Linux (два golden-digest и post_popen_handler_gap).

Связность: режим полагается на `run-name` из `verification-lanes.yml`
(V5b2d-4d). Без него сбор не выдумывает совпадений — он отказывает громко.
Independent verification ran mutants and found the same class three times: an
invariant stated in code and in the comment beside it, with nothing that would
notice its removal.

The expensive one is the second engine.  Both engines replay the same evidence
build, so a listing carries both campaigns — and a collector that hardcoded
the first artifact answered an MPFI request with Arb's run ids and exited 0.
Half a dual proof, silently wrong, reported as success.  Every CLI case used
the Arb artifact, so nothing could tell the two apart.

The overlap guard was theatre in the literal sense: its docstring calls
overlap "the one thing that must not pass", and the refusal suite contained no
overlapping plan at all — the case it did contain died on the tuple-shape
branch beside it.  A plan of two windows sharing an ordinal is in the suite
now.

Deduplicating by run id had the same shape: a listing that repeats a run must
not manufacture a duplicate-cover refusal, and removing the check left
everything green.

Each is proven by the mutant it kills, one test apiece: the hardcoded
artifact at the collect call site, `window[0] < cursor` weakened to a
tautology, and the unconditional append.

Verified: 31 dispatch tests pass; 429 on Linux with the three pre-existing
`test_build` failures that also fail on an untouched tree.
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

Добавлен режим collect для получения успешных lane runs через GitHub CLI. Код разбирает имена запусков, проверяет покрытие плана, устраняет дубликаты, сериализует коллекцию и не записывает результат при неполном покрытии.

Changes

Коллекция lane runs

Layer / File(s) Summary
Контракты и разбор имён
proof/region/v1/corpus_dispatch.py, proof/region/v1/tests/test_corpus_dispatch.py
Добавлены типизированные модели наблюдений, коллекций и отказов. Парсер принимает только канонический формат имён lane runs.
Сопоставление и наблюдение
proof/region/v1/corpus_dispatch.py, proof/region/v1/tests/test_corpus_dispatch.py
Код получает whitelisted поля через gh run list, фильтрует runs по артефакту и evidence run, устраняет дубликаты и проверяет покрытие плана.
Режим collect и CLI
proof/region/v1/corpus_dispatch.py, proof/region/v1/tests/test_corpus_dispatch.py, proof/region/v1/tests/test_verification_dispatch.py
CLI поддерживает collect и --run-limit. При полном покрытии создаётся lane-runs.json. При отказе файл не создаётся. CLI-тесты проверяют коды завершения и сообщения об отказах.

Estimated code review effort: 4 (Сложный) | ~45 минут

Sequence Diagram(s)

sequenceDiagram
  participant CLI as collect CLI
  participant GH as gh run list
  participant Collector as collect_lane_runs_v1
  participant Matcher as match_lane_runs_v1
  participant File as lane-runs.json
  CLI->>GH: Запрашивает lane runs с лимитом
  GH-->>Collector: Возвращает TSV-наблюдения
  Collector->>Matcher: Передаёт успешные observations
  Matcher-->>Collector: Возвращает коллекцию или отказ
  Collector->>File: Записывает JSON при полном покрытии
Loading

Possibly related PRs

  • Labpics-Team/lab-colors#529 — lane-assembly workflow использует идентификаторы и артефакты, которые собирает этот PR.
  • Labpics-Team/lab-colors#548 — оба PR изменяют наблюдение и проверку GitHub verification runs в corpus_dispatch.py.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 22.92% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Заголовок точно описывает основное изменение: передача идентификаторов lane runs для dual proof в рамках dispatched campaign.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch v5b2d-4e-lane-run-collection

Comment @coderabbitai help to get the list of available commands.

coderabbitai[bot]
coderabbitai Bot previously requested changes Aug 6, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@proof/region/v1/corpus_dispatch.py`:
- Around line 649-661: В режиме collect добавьте до вызова collect_lane_runs_v1
валидацию положительного значения args.run_limit, положительного
args.evidence_run_id и допустимого значения args.evidence_artifact. При каждой
ошибке сразу выведите сообщение с именем неверного параметра и верните код 64,
не выполняя сетевой запрос; сохраните существующие проверки обязательных
аргументов.

In `@proof/region/v1/tests/test_corpus_dispatch.py`:
- Around line 611-635: Add a CollectCliTests test covering --run-limit: use an
observer that records its limit argument, invoke _with_observer with --run-limit
set to 37, and assert successful execution plus seen == [37]. Keep the existing
collect output assertions unchanged.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: c7773709-db0d-4b6f-a08b-6b9db50a16a6

📥 Commits

Reviewing files that changed from the base of the PR and between e420e21 and 8f4c924.

📒 Files selected for processing (2)
  • proof/region/v1/corpus_dispatch.py
  • proof/region/v1/tests/test_corpus_dispatch.py

Comment thread proof/region/v1/corpus_dispatch.py
Comment thread proof/region/v1/tests/test_corpus_dispatch.py
Claude Code added 2 commits August 7, 2026 08:52
Замечание ревью верно по существу: `--mode collect` передавал свои аргументы в
`collect_lane_runs_v1` без единой проверки, а тот первым делом делает сетевой
вызов. Наблюдённое поведение до правки (WSL, наблюдатель-заглушка вместо `gh`):

- `--evidence-run-id 0` и `-1`: запрос выполнен (observer_called=[2000]), отказ
  гласит «lane run collection cannot observe verification-lanes.yml: …» — вина
  переложена на workflow, а не на аргумент;
- `--evidence-artifact verification-evidence-flint`: то же самое;
- `--run-limit 0` и `-5`: значение уходит в `gh run list --limit` дословно, а
  пустой ответ превращается в отказ «cover is incomplete: missing=…» с 256
  окнами — оператор идёт передиспатчивать кампанию, которая цела.

Закон: координата, которая будет потрачена на сетевой запрос, проверяется до
запроса, и отказ называет виновный аргумент. Код возврата назвать его не может —
он 64 у всех соседних отказов, поэтому именно на текст и на отсутствие запроса
опираются тесты. Allowlist не продублирован: он рендерится из
`EVIDENCE_ARTIFACTS_V1`, так что оператор узнаёт допустимый набор из самого
отказа.

Тот же инвариант рядом (предсуществующий дефект, закрыт этим же срезом):
`--mode verification-dispatch` с непозитивным run id или чужим артефактом
обходил построитель команд, тот возвращал типизированный отказ, а `main`
обходил его циклом как список команд — оператор получал `TypeError:
'ShardCorpusRejectedV1' object is not iterable` вместо причины. Теперь отказ
построителя печатается с его собственной причиной и выходит 64.

Доказательства (WSL, python3 -m unittest):

- RED до реализации: три падения по заявленной причине («--evidence-run-id» не
  найден в тексте отказа; «--run-limit» не найден в отказе про неполное
  покрытие) и одна ошибка TypeError в verification-dispatch.
- 8 мутантов, каждый убит: M1/M2/M3 — снятие каждой из трёх проверок; M4 —
  общий текст «requires valid arguments» вместо имени аргумента (убивает все
  три теста); M5 — проверки перенесены ПОСЛЕ запроса (observed=[2000] != []);
  M6 — проверка лимита сделана слишком строгой (`>= 0`), убита тестом на
  допустимые аргументы; M7 — отказ без причины; M8 — снятие защиты от обхода
  отказа (тот самый TypeError).
- Прежний `test_collect_requires_both_evidence_coordinates` заменён: его
  наблюдатель звал `self.fail`, а `collect_lane_runs_v1` глотает любое
  исключение наблюдателя в типизированный отказ с тем же кодом 64 — тест не мог
  упасть по своей заявленной причине.
- Набор proof: 433 теста, 3 падения — ровно предсуществующие в test_build (два
  golden-digest и post_popen_handler_gap), они же падают на нетронутом дереве
  (429 тестов, те же три).
- Контакт с реальностью: после правки все пять случаев дают observer_called=[],
  ничего не записано, текст называет аргумент.

Rust не затронут: изменены три файла в proof/region/v1.
Independent verification found the class this branch claimed closed was
closed only at the zero boundary: a positive but truncating --run-limit spent
the query and then reported the campaign incomplete — sending the operator to
re-dispatch 256 lanes when the fix is one flag.  `gh run list --limit N`
drops the oldest runs, so a listing that came back exactly at the limit
cannot distinguish a real hole from its own truncation.

The refusal now names the flag when the listing is saturated, and keeps
blaming the campaign when there is room to spare — the anti-vacuity case,
because hiding real damage behind the flag would be the opposite failure.

Also corrected here: the comment claiming CalledProcessError.__repr__ drops
stderr — measured false on the #555 branch, repr carries every constructor
argument; stderr is preferred for legibility, not recovery.

Verified: 36 dispatch tests pass, both new ones read the refusal text.
Claude Code added 2 commits August 7, 2026 10:33
The interleave was real: git tried to merge the new collect observer into the
artifact observer because both begin identically, so the zone was
reconstructed programmatically — both sides whole, shared fragments
duplicated into each.

Resolution by intent:
- printing is the default and dispatching is `--execute` (main's polarity);
  the collect tests lose the flag that no longer exists;
- `--run-limit` joins main's argument set;
- main's typed not-a-tuple guard and single mid-flight handler stand; the
  branch's older duplicates go;
- the collect block — observation, matching, saturation rule, CLI mode —
  lands beside the admission chain rather than inside it.

Verified: 75 dispatch tests pass, and pass again under PYTHONOPTIMIZE=2.
One conflict, the module docstring: both paragraphs are true — the origin
admission from #552 and the collect mode from this branch — so both stand.
Everything else, including the provenance chain and its tests, merged clean.

Verified: 95 dispatch tests pass, and again under PYTHONOPTIMIZE=2.
coderabbitai[bot]
coderabbitai Bot previously requested changes Aug 7, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
proof/region/v1/corpus_dispatch.py (1)

846-862: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Добавьте таймаут в gh run list.

Два других наблюдения этого модуля (gh_run_artifacts_v1, gh_run_provenance_v1) передают timeout=OBSERVATION_TIMEOUT_SECONDS_V1. Здесь таймаута нет. Зависший gh останавливает режим collect без ограничения времени, и оператор не отличает зависание от работы. Таймаут также нужен потому, что collect_lane_runs_v1 превращает любую ошибку наблюдения в типизированный отказ; без него отказа не будет вовсе.

🛠️ Предлагаемая правка
         capture_output=True,
         text=True,
         check=True,
+        # Инвариант наблюдений этого модуля: у запроса есть предельный срок,
+        # иначе зависший `gh` неотличим от работы и отказ никогда не наступит.
+        timeout=OBSERVATION_TIMEOUT_SECONDS_V1,
     )
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@proof/region/v1/corpus_dispatch.py` around lines 846 - 862, Update the
subprocess.run invocation in collect_lane_runs_v1 to pass
timeout=OBSERVATION_TIMEOUT_SECONDS_V1, matching the existing
gh_run_artifacts_v1 and gh_run_provenance_v1 observations. Preserve the current
command and error propagation behavior so a hung gh run list becomes the
existing typed observation failure.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@proof/region/v1/corpus_dispatch.py`:
- Line 844: Исправьте форматирование в match_lane_runs_v1: перенесите
закрывающие тройные кавычки докстроки на отдельную строку, а закрывающую скобку
кортежа аргументов — после значения --jq на отдельную строку, сохранив
содержимое и поведение без изменений.

---

Outside diff comments:
In `@proof/region/v1/corpus_dispatch.py`:
- Around line 846-862: Update the subprocess.run invocation in
collect_lane_runs_v1 to pass timeout=OBSERVATION_TIMEOUT_SECONDS_V1, matching
the existing gh_run_artifacts_v1 and gh_run_provenance_v1 observations. Preserve
the current command and error propagation behavior so a hung gh run list becomes
the existing typed observation failure.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 55ea9f33-2f73-437c-ab90-1ef234b2031b

📥 Commits

Reviewing files that changed from the base of the PR and between 8f4c924 and 6a7c85e.

📒 Files selected for processing (3)
  • proof/region/v1/corpus_dispatch.py
  • proof/region/v1/tests/test_corpus_dispatch.py
  • proof/region/v1/tests/test_verification_dispatch.py

it saw, without deciding anything. The projection is done by `--jq` in
the query itself, so no unreviewed field of the API reply ever enters the
process; which of these runs belongs to a campaign is a rule, and it lives
in `match_lane_runs_v1` where a test can reach it. """

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Исправьте склеенное форматирование.

В строке 844 закрывающая """ стоит на одной строке с текстом докстроки. В строке 858 закрывающая скобка кортежа аргументов стоит после значения --jq. Обе строки выглядят как результат неудачного слияния и мешают чтению.

♻️ Предлагаемая правка
-    in `match_lane_runs_v1` where a test can reach it.    """
+    in `match_lane_runs_v1` where a test can reach it.
+    """
@@
-            ".[] | [.databaseId, .displayTitle, .conclusion] | `@tsv`",        ),
+            ".[] | [.databaseId, .displayTitle, .conclusion] | `@tsv`",
+        ),

Also applies to: 858-858

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@proof/region/v1/corpus_dispatch.py` at line 844, Исправьте форматирование в
match_lane_runs_v1: перенесите закрывающие тройные кавычки докстроки на
отдельную строку, а закрывающую скобку кортежа аргументов — после значения --jq
на отдельную строку, сохранив содержимое и поведение без изменений.

@lemone112

Copy link
Copy Markdown
Collaborator Author

@coderabbitai Оба замечания закрыты кодом в aa32514: режим collect валидирует аргументы до первого сетевого вызова — положительный --evidence-run-id, allowlisted --evidence-artifact, положительный --run-limit; каждый отказ типизирован (exit 64) и называет конкретный флаг, а не соседний. Независимая проверка прогнала 17 мутантов на этих правилах — 0 выживших, включая подмену текста одного отказа другим и перенос гвардов после запроса. Дополнительно в b4450f66 закрыт смежный класс: насыщенный листинг винит --run-limit, а не кампанию. Снимаю оба ревью как разрешённые.

@lemone112
lemone112 dismissed stale reviews from coderabbitai[bot] and coderabbitai[bot] August 7, 2026 07:51

Закрыто кодом в aa32514 (валидация всех трёх аргументов до сетевого вызова, типизированные отказы с именем флага) и b4450f6 (правило насыщения лимита). Проверено 17 мутантами, 0 выживших. Ответ в треде PR.

@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

@lemone112 Принято. Оба замечания закрыты.

Режим collect теперь проверяет --evidence-run-id, --evidence-artifact и --run-limit до сетевого вызова. Ошибки используют exit code 64 и называют неверный флаг. Насыщенный листинг корректно указывает на --run-limit.

🐇 ✅


✏️ Learnings added
Learnt from: lemone112
URL: https://github.com/Labpics-Team/lab-colors/pull/553

Timestamp: 2026-08-07T07:51:45.341Z
Learning: In `proof/region/v1/corpus_dispatch.py`, collect-mode CLI validation must run before any network request. `--evidence-run-id` and `--run-limit` must be positive, and `--evidence-artifact` must be allowlisted. Each validation rejection must use exit code `64` and identify the specific invalid flag. A listing that reaches `--run-limit` is a truncated observation and must attribute the rejection to `--run-limit`, not to incomplete campaign coverage.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

You are interacting with an AI system.

@lemone112
lemone112 merged commit ff921c2 into main Aug 7, 2026
10 checks passed
@lemone112
lemone112 deleted the v5b2d-4e-lane-run-collection branch August 7, 2026 07:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant