Skip to content

Proof: вынести общую BUILD-границу - #508

Closed
lemone112 wants to merge 21 commits into
agent/mpfi-sourcefrom
agent/build-transport
Closed

Proof: вынести общую BUILD-границу#508
lemone112 wants to merge 21 commits into
agent/mpfi-sourcefrom
agent/build-transport

Conversation

@lemone112

@lemone112 lemone112 commented Aug 1, 2026

Copy link
Copy Markdown
Collaborator

Контракт

  • Общая BUILD-граница остаётся engine-neutral: публичный DockerBuildRequestV1 содержит только attempt, capability, sealed input и output cap.
  • Native adapter владеет private CID lease; cleanup не использует имя контейнера или fallback-координату.
  • Неканоническое внутреннее observation не выходит наружу сырой ошибкой: adapter возвращает typed terminal outcome.
  • Для поддельного преждевременного CID_ROOT claim доверяется только уже канонизированный progress sealed input. Если затем реально падает собственный cleanup, результат сохраняет exact progress и отражает OBSERVER_FAILURE + единственную собственную CID-root запись.
  • Короткая каноническая cleanup-диагностика сохраняется; при переполнении bounded evidence budget выдаётся явный typed dual-failure outcome, без усечения и без TypeError.
  • После probe Arb берёт семантику sealed input только из сохранённой docker_capability.policy, а не из изменяемого module global. V1 preimage не менялся: он описывает source→tree bootstrap; argv0 уже входит во внешние transport/capability/receipt identities и не создаёт ложный V2.

Проверка на текущей голове

  • RED → GREEN: reentrant backend не может подменить post-probe input binding; receipt replay также не перечитывает module global.
  • Mutation: подмена exact_policy ambient global снова делает этот тест красным.
  • Arb gate normal и -O: 185 tests, exact 11-skip manifest, inventory 43c97cac…f608b11; добавлены hostile-тесты dispatcher, recipe taxonomy и comparator replay.
  • Outer gate normal и -O: 42 tests.
  • git show --check чист; два независимых read-only scope/architecture-аудита подтвердили отсутствие основания для искусственного V2.

Stack

Основан на agent/mpfi-source (#503). PR остаётся draft: native Docker CLI в этом родительском срезе ещё требует descendant #509 с проверкой всех pathname segments без symbolic-link переходов. Отдельный exact-head disposable-VM gate также не пройден; этот PR не заявляет его зелёным.

Последняя проверка — 2026-08-02

  • Новый head 8998ada1b4128514579e3e50afbb9d6a68ac91d4 включает source-bound dispatcher, полную recipe-taxonomy и независимый comparator replay.
  • build.sh — только source-owned dispatcher; trusted Docker transport запускает fixed bundle path, а path resolution к build-inner.sh происходит после очистки окружения. Standalone wrapper не заявляется source-identity authority.
  • Outer и inner recipe связаны общей ordered BUILD/test coordinate; inner-only mutation меняет BUILD/test-observation, но не evaluator-source.
  • Receipt replay использует versioned public derive_arb_comparator_for_build_v1 и заново сравнивает все named coordinates; self-consistent mutation-тест охватывает каждую координату.
  • Local Arb fast gate: 185 tests, 11 exact skips, inventory 43c97cac…f608b11; targeted receipt, pipeline и transport tests, shell syntax, ShellCheck и diff-check green.
  • External exact-head jobs 30727350047, 30727350050, 30727350046 пока queued; production/live gate не заявлен.

@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Добавлены общие контракты канонического BUILD-входа и Docker-транспорта. Arb pipeline и receipt replay переведены на Docker capability, sealed input, две сборки и identity V2. Добавлены transport-контракты и расширены тесты.

Changes

BUILD transport и identity

Layer / File(s) Summary
Протокол и канонический вход
proof/region/v1/PROTOCOL.md, proof/region/v1/build/*
Протокол описывает BUILD-границу. build.input валидирует входы, создаёт канонический USTAR и формирует SealedInputV1.
Docker policy, capability и наблюдения
proof/region/v1/build/transport.py
Добавлены Docker policy, capability, typed observations, native backend, leases, cleanup и контролируемая двухсборочная сессия.
Интеграция Arb pipeline
proof/region/v1/arb/pipeline.py
Pipeline использует общие input и transport-типы, проверяет binding и ELF-выход, выполняет две сборки и формирует identity V2.
Receipt replay и source-bound identity
proof/region/v1/arb/receipt.py
Replay и provenance используют capability-dependent policy identity V2, transport observations и bound input.
Контрактные и identity-тесты
proof/region/v1/tests/*, proof/region/v1/arb/tests/*
Тесты проверяют канонизацию, immutable contracts, capability binding, process observations, cleanup, identity V2 и обновлённый Arb gate.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

  • Labpics-Team/lab-colors#499: Изменяет тот же Arb pipeline и связанные BUILD transport/identity-контракты.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 4.37% 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
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Заголовок точно отражает основное изменение: выделение общей engine-neutral BUILD-границы.
✨ 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 agent/build-transport

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

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

Пожалуйста, проверьте именно causal identity/lease semantics, boundary between generic BUILD and Arb source authority, cleanup/lifecycle paths, API and documentation claims. Не требуется проверка GitHub Actions или runner infrastructure.

@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown

@lemone112 Принято. Проверю только causal identity и lease semantics, границу generic BUILD и Arb source authority, cleanup/lifecycle paths, а также API и claims в документации. GitHub Actions и runner infrastructure не проверяю.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@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: 19

🤖 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/arb/pipeline.py`:
- Around line 354-378: В функции _arb_input_binding_identity_v1 замените метку
_BUILD_INPUT_BUNDLE_ID_LABEL_V1 на значение схемы V2 для arb-build-input-bundle,
сохранив добавленный digest ARB_BUILD_TRANSPORT_POLICY_V1.bootstrap. Обновите
все зависимые ожидаемые значения и тестовые векторы, чтобы они соответствовали
новой идентичности.

In `@proof/region/v1/arb/receipt.py`:
- Around line 51-64: Update source_bound_policy_identity_v2 to accept an
explicit host_trust value and pass it to pipeline_policy_identity_v2 instead of
hard-coding UNSEALED_LINUX_X64_DOCKER_HOST. Update its callers, including the
paths around evidence.request and replay_request, to provide the corresponding
request.host_trust so policy and BUILD identities use the same trust boundary.

In `@proof/region/v1/arb/tests/test_build_identity_v2.py`:
- Around line 375-376: В тесте вокруг `capability_identity` и
`baseline_capability` удалите условие `if name != "hostname"` и выполняйте
`self.assertNotEqual(capability_identity, baseline_capability)` безусловно для
всех имён.

In `@proof/region/v1/arb/tests/test_pipeline.py`:
- Around line 275-308: Устраните дублирование Docker probe-фикстур: расширьте
`_probe_native_backend` параметрами `daemon_marker` и `host_user`, формируйте
наблюдение с переданными значениями и сохраните различия в `sort_keys` и маркере
daemon. Затем замените локальные реализации `_capability` и probe-наблюдений в
тестах `test_pipeline.py`, `test_build_identity_v2.py` и
`test_build_identity.py` вызовами этого общего хелпера.
- Around line 663-682: Replace the positional mutations of coordinates[4] and
coordinates[6] in the pipeline policy identity tests with the existing
named-field mutation approach from _policy_with in test_build_identity_v2.py.
Target the bootstrap field for the altered bootstrap command and tmpfs_specs for
the private tmpfs change, preserving the existing identity assertions.

In `@proof/region/v1/arb/tests/test_receipt.py`:
- Around line 225-229: Добавьте короткий комментарий непосредственно перед
проверкой digest в тесте, поясняющий, что golden digest вычислен для capability
из фикстуры _docker_capability и должен обновляться вместе с изменениями
daemon_marker, пути Docker CLI или host_user; не пересказывайте сам assert.
- Around line 495-500: Замените проверки object.__new__ в тесте вокруг
first.input_transfer и first на сценарии подделки через tuple.__new__: создайте
поддельный process или transfer, подставьте его в dag.build и проверьте, что
replay_evidence_is_well_bound_v1 возвращает False. Сохраните проверки отсутствия
__dict__ и покрытие отказа для обоих объектов.

In `@proof/region/v1/arb/tests/test_transport.py`:
- Around line 314-317: Update the immutability assertion in the Docker
capability test to target the existing DockerSupportedV1 coordinate host_user
instead of the nonexistent platform field, while preserving the
AttributeError/TypeError expectation and the surrounding __dict__ check.

In `@proof/region/v1/build/input.py`:
- Around line 61-95: Сведите ошибки невалидного входа в конструкторах
CanonicalInputLimitsV1 и SealedInputV1 к InputErrorV1: добавьте в закрытую сумму
InputReasonV1 причину WRONG_TYPE либо отдельную причину для лимитов и
используйте её для всех проверок типов и диапазонов вместо TypeError с текстом.
Сохраните существующую валидацию, но обеспечьте, чтобы lane мог классифицировать
каждый отказ по полю reason.
- Around line 123-131: Обновите `_ustar_path_is_encodable`, добавив признак
директории и передавая его из вызывающего кода. При проверке директорий
учитывайте дополнительный завершающий `/` в размере имени и префикса, чтобы пути
длиной 101–155 байт корректно принимались через `prefix`; поведение для обычных
файлов сохраните.

In `@proof/region/v1/build/transport.py`:
- Around line 2567-2572: Вынесите проверку целостности из публичного property
BuildSessionV1.input_value в отдельную функцию-валидатор, сохранив проверку в
BuildSessionV1.__new__. Сделайте input_value чистым чтением без RuntimeError;
если проверка при чтении всё же необходима, замените исключение на TypeError с
формулировкой, принятой для остальных отказов модуля, чтобы публичные
потребители получали типизированную ошибку.
- Line 21: Переименуйте импорт `input` в `build_input` и обновите все обращения
к `input.SealedInputV1` и `input.sealed_input_is_intact_v1` на соответствующие
обращения через `build_input`, сохранив текущее поведение модуля.
- Around line 2011-2063: Добавьте регрессионные проверки для _observe_command:
при процессе, не читающем stdin, неблокирующая запись не должна блокировать
цикл, а по истечении build_timeout_ns метод должен вернуть DockerBuildTimedOutV1
с частичным прогрессом. В NativeDockerBuildBackendV1.probe определяйте
успешность по коду возврата и другим существующим критериям, не отклоняя
успешный probe только из-за непустого result.stderr.

In `@proof/region/v1/PROTOCOL.md`:
- Around line 234-265: Уточните абзац о сохранении causal prefix в разделе
«Общая граница BUILD»: добавьте оговорку, что context-free contract violations,
возникающие при невалидной сессии или сбое создания TemporaryDirectory в
ControlledBuildTransportV1._build_once, могут возвращать BuildRejectedV1 без
session и completed_processes. Не изменяйте остальные гарантии документа.

In `@proof/region/v1/tests/test_build_identity.py`:
- Around line 139-199: Добавьте короткий комментарий непосредственно перед
функциями _blob и _identity, поясняющий, что _blob, _identity, _policy_chunks и
функции _expected_* намеренно дублируют production-схему preimage как
независимый literal oracle для выявления незаметных изменений identity-схемы в
build.transport; не описывайте сами операции и сохраните существующую реализацию
без иных изменений.
- Around line 399-443: Переместите определение тестового класса
`_AlternateUserMode` из конца файла к другим вспомогательным символам, разместив
его до класса `BuildIdentitySurfaceTests` и до метода
`test_policy_identity_binds_all_thirteen_coordinates`, который его использует;
содержимое класса и остальную логику теста не изменяйте.
- Around line 154-157: В функции _policy_chunks замените assert
type(tmpfs_specs) is tuple на явную проверку типа, которая при несоответствии
выбрасывает TypeError. Сохраните дальнейшую обработку tmpfs_specs без изменений
и обеспечьте выполнение проверки независимо от режима запуска Python.

In `@proof/region/v1/tests/test_build.py`:
- Around line 93-104: Уберите дублирование `"provenance"` в определении
`FORBIDDEN_TRANSPORT_IMPORTS_V1`: если для transport нет дополнительных
запрещённых импортов, присвойте ему `FORBIDDEN_INPUT_IMPORTS_V1` напрямую; если
дополнительные запреты предусмотрены, добавьте только их.
- Around line 18-30: Добавьте корень репозитория в список путей перед импортом
`proof.region.v1.arb.tests.gate`, вычислив его относительно `__file__` и вставив
в `sys.path` до `import pipeline` и `from proof.region.v1.arb.tests import gate
as arb_gate`; сохраните существующие импорты и плоский импорт `gate` без
изменений.
🪄 Autofix (Beta)

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: 33fbf045-9f50-42c1-bf38-a28954146a2d

📥 Commits

Reviewing files that changed from the base of the PR and between 8a63b23 and c23facf.

📒 Files selected for processing (13)
  • proof/region/v1/PROTOCOL.md
  • proof/region/v1/arb/pipeline.py
  • proof/region/v1/arb/receipt.py
  • proof/region/v1/arb/tests/gate.py
  • proof/region/v1/arb/tests/test_build_identity_v2.py
  • proof/region/v1/arb/tests/test_pipeline.py
  • proof/region/v1/arb/tests/test_receipt.py
  • proof/region/v1/arb/tests/test_transport.py
  • proof/region/v1/build/__init__.py
  • proof/region/v1/build/input.py
  • proof/region/v1/build/transport.py
  • proof/region/v1/tests/test_build.py
  • proof/region/v1/tests/test_build_identity.py

Comment thread proof/region/v1/arb/pipeline.py Outdated
Comment on lines +354 to +378
def _arb_input_binding_identity_v1(
source_identity: bytes,
build_input_identity: bytes,
contents: bytes,
) -> bytes:
if (
not _valid_digest(source_identity)
or not _valid_digest(build_input_identity)
or type(contents) is not bytes
or not contents
):
raise TypeError("invalid Arb build input binding coordinates")
digest = hashlib.sha256(contents).digest()
return _identity(
_BUILD_INPUT_BUNDLE_ID_LABEL_V1,
(
source_identity,
build_input_identity,
len(contents).to_bytes(8, "big"),
digest,
hashlib.sha256(
ARB_BUILD_TRANSPORT_POLICY_V1.bootstrap.encode("utf-8")
).digest(),
),
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Найти определение метки и её прежний состав.
rg -n 'BUILD_INPUT_BUNDLE_ID_LABEL' proof/region/v1 -C3
git log -1 --format=%H
git diff HEAD~1 -- proof/region/v1/arb/pipeline.py | rg -n 'BUILD_INPUT_BUNDLE_ID_LABEL|bootstrap|binding_identity' -C4 | head -60

Repository: Labpics-Team/lab-colors

Length of output: 3437


🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '--- parent implementation ---'
git show HEAD~1:proof/region/v1/arb/pipeline.py | sed -n '85,125p'
printf '%s\n' '--- current implementation ---'
sed -n '354,382p' proof/region/v1/arb/pipeline.py
printf '%s\n' '--- label history in parent ---'
git show HEAD~1:proof/region/v1/arb/pipeline.py | rg -n '_BUILD_INPUT_BUNDLE_ID_LABEL_V1|_identity\(' -C4

Repository: Labpics-Team/lab-colors

Length of output: 8391


Замените метку на V2.

Старая схема под _BUILD_INPUT_BUNDLE_ID_LABEL_V1 содержала четыре координаты. Новая схема добавляет digest ARB_BUILD_TRANSPORT_POLICY_V1.bootstrap. Используйте labcolors.proof-region.arb-build-input-bundle.v2\0 и обновите зависимые ожидаемые значения.

🧰 Tools
🪛 Ruff (0.16.0)

[warning] 365-365: Avoid specifying long messages outside the exception class

(TRY003)

🤖 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/arb/pipeline.py` around lines 354 - 378, В функции
_arb_input_binding_identity_v1 замените метку _BUILD_INPUT_BUNDLE_ID_LABEL_V1 на
значение схемы V2 для arb-build-input-bundle, сохранив добавленный digest
ARB_BUILD_TRANSPORT_POLICY_V1.bootstrap. Обновите все зависимые ожидаемые
значения и тестовые векторы, чтобы они соответствовали новой идентичности.

Comment thread proof/region/v1/arb/receipt.py
Comment thread proof/region/v1/arb/tests/test_build_identity_v2.py Outdated
Comment thread proof/region/v1/arb/tests/test_pipeline.py
Comment thread proof/region/v1/arb/tests/test_pipeline.py
Comment thread proof/region/v1/tests/test_build_identity.py
Comment thread proof/region/v1/tests/test_build_identity.py Outdated
Comment thread proof/region/v1/tests/test_build_identity.py Outdated
Comment thread proof/region/v1/tests/test_build.py
Comment thread proof/region/v1/tests/test_build.py Outdated

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@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: 7

♻️ Duplicate comments (1)
proof/region/v1/arb/tests/test_pipeline.py (1)

664-682: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Замените позиционные индексы координат политики на мутацию по имени поля.

coordinates[3] и coordinates[5] привязаны к порядку полей DockerBuildPolicyV1. При изменении порядка тест будет мутировать другое поле того же строкового или кортежного типа, конструктор не откажет, и тест продолжит проходить, проверяя не тот инвариант. Файл proof/region/v1/arb/tests/test_build_identity_v2.py содержит _policy_with, который мутирует политику по имени поля. Переиспользуйте этот подход.

🤖 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/arb/tests/test_pipeline.py` around lines 664 - 682, Замените
позиционные мутации coordinates[3] и coordinates[5] в тестах идентичности
политики на именованную мутацию через существующий подход _policy_with из
test_build_identity_v2.py. Обновите соответствующие тесты, чтобы изменялись
именно поля bootstrap и tmpfs_specs независимо от порядка полей
DockerBuildPolicyV1.
🤖 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/arb/tests/test_pipeline.py`:
- Around line 1296-1312: Release the run lease created by _next_run_lease_v1 in
this test by registering self.addCleanup(backend._release_run_lease_v1, lease)
immediately after lease creation, ensuring the private CID-root directory is
removed regardless of test outcome.

In `@proof/region/v1/arb/tests/test_transport.py`:
- Around line 547-555: Добавьте короткий комментарий перед проверкой TypeError
вокруг DockerBuildRequestV1, объясняющий инвариант: тип не предоставляет
позиционных полей для host cleanup authority, включая внешний CID-файл и имя
контейнера. Не изменяйте саму проверку и не дублируйте уже существующие проверки
hasattr.

In `@proof/region/v1/build/transport.py`:
- Around line 2878-2885: В логике повторного закрытия дескриптора вокруг
close_failed ограничьте вызов os.close проверкой, что descriptor всё ещё
принадлежит исходному stream, используя stream.fileno() или эквивалентную
проверку. Не закрывайте дескриптор только по сохранённому числовому значению
после исключения из stream.close(); сохраните существующую обработку ошибок и
retained_base_exception.
- Around line 3513-3515: В публичном методе probe замените RuntimeError при
outcome is None на типизированный отказ DockerUnsupportedV1 с причиной
BACKEND_CONTRACT, сохранив единый контракт возврата probe для всех отказов.
- Around line 2338-2363: Защитите публичный метод run_build от исключений при
вызове _with_cid_root_cleanup_failure_v1 в блоке finally: обработайте ошибки
валидации наблюдения или координат и верните типизированный
DockerBuildObserverFailureV1 вместо выхода исключения наружу. Сохраните
приоритет повторного выбрасывания retained_base_exception, если он уже
установлен.

In `@proof/region/v1/tests/test_build.py`:
- Around line 39-44: Update the test setup in test_build.py to import and reuse
arb_gate.EXPECTED_TEST_INVENTORY_SHA256 instead of defining
ARB_INVENTORY_SHA256_V1 locally. Extract the duplicated expected test count 166
into one named constant and use it at both references, while keeping
ARB_ORDER_SHA256_V1 unchanged.
- Around line 1380-1392: Сделайте поиск `process_store` в тесте вокруг
`backend._observe_command` диагностируемым: передайте `default=None` в `next()`,
а при отсутствии совпадения вызовите `self.fail(...)`, указав версию Python и
ожидаемый шаблон опкодов. Не используйте `skipTest`; сохраните проверку
`CALL_FUNCTION_EX` и добавляйте `CALL` только при подтверждённом шаблоне для
целевой версии.

---

Duplicate comments:
In `@proof/region/v1/arb/tests/test_pipeline.py`:
- Around line 664-682: Замените позиционные мутации coordinates[3] и
coordinates[5] в тестах идентичности политики на именованную мутацию через
существующий подход _policy_with из test_build_identity_v2.py. Обновите
соответствующие тесты, чтобы изменялись именно поля bootstrap и tmpfs_specs
независимо от порядка полей DockerBuildPolicyV1.
🪄 Autofix (Beta)

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: 990f9803-c86c-4d33-b379-8d2bf7d97c4e

📥 Commits

Reviewing files that changed from the base of the PR and between c23facf and 1ff6dad.

📒 Files selected for processing (10)
  • proof/region/v1/PROTOCOL.md
  • proof/region/v1/arb/pipeline.py
  • proof/region/v1/arb/tests/gate.py
  • proof/region/v1/arb/tests/test_build_identity_v2.py
  • proof/region/v1/arb/tests/test_pipeline.py
  • proof/region/v1/arb/tests/test_receipt.py
  • proof/region/v1/arb/tests/test_transport.py
  • proof/region/v1/build/transport.py
  • proof/region/v1/tests/test_build.py
  • proof/region/v1/tests/test_build_identity.py
💤 Files with no reviewable changes (1)
  • proof/region/v1/arb/tests/test_build_identity_v2.py

Comment thread proof/region/v1/arb/tests/test_pipeline.py
Comment thread proof/region/v1/arb/tests/test_transport.py
Comment thread proof/region/v1/build/transport.py
Comment thread proof/region/v1/build/transport.py Outdated
Comment thread proof/region/v1/build/transport.py Outdated
Comment thread proof/region/v1/tests/test_build.py Outdated
Comment on lines +39 to +44
ARB_INVENTORY_SHA256_V1 = (
"4853e06c6e8c1864bc65e0b4c0cd9cdbe0881e0d5907daecb6c8a9fea42f3643"
)
ARB_ORDER_SHA256_V1 = (
"82b8e00867bc0bed7bd4020f8d9b9531cd195f7c712ddff9a4d73ef7fc0484d5"
)

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 | 🟠 Major | ⚡ Quick win

Ссылайтесь на inventory-хэш из gate как на единственный источник истины.

ARB_INVENTORY_SHA256_V1 дублирует значение arb_gate.EXPECTED_TEST_INVENTORY_SHA256 из proof/region/v1/arb/tests/gate.py:17-19. При изменении набора тестов нужно обновить два литерала, и расхождение обнаружится только по падению одного из тестов. Число 166 также повторяется дважды в этом тесте.

Возьмите хэш из arb_gate и вынесите ожидаемое количество в одну константу.

♻️ Предлагаемая правка
-ARB_INVENTORY_SHA256_V1 = (
-    "4853e06c6e8c1864bc65e0b4c0cd9cdbe0881e0d5907daecb6c8a9fea42f3643"
-)
+ARB_INVENTORY_SHA256_V1 = arb_gate.EXPECTED_TEST_INVENTORY_SHA256
+ARB_TEST_COUNT_V1 = 166
 ARB_ORDER_SHA256_V1 = (
     "82b8e00867bc0bed7bd4020f8d9b9531cd195f7c712ddff9a4d73ef7fc0484d5"
 )
-        self.assertEqual(len(identifiers), 166)
-        self.assertEqual(len(set(identifiers)), 166)
+        self.assertEqual(len(identifiers), ARB_TEST_COUNT_V1)
+        self.assertEqual(len(set(identifiers)), ARB_TEST_COUNT_V1)

Also applies to: 271-272

🤖 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/tests/test_build.py` around lines 39 - 44, Update the test
setup in test_build.py to import and reuse
arb_gate.EXPECTED_TEST_INVENTORY_SHA256 instead of defining
ARB_INVENTORY_SHA256_V1 locally. Extract the duplicated expected test count 166
into one named constant and use it at both references, while keeping
ARB_ORDER_SHA256_V1 unchanged.

Comment thread proof/region/v1/tests/test_build.py

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

Актуальный follow-up: 2ebba78. Перед запросом независимое hostile-review не нашло P1/P2/P3; normal и -O proof-gates зелёные. Просьба ревьюировать именно текущий head, включая сохранение V1 input-binding identity без фиктивной V2-миграции.

@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown

@lemone112 Принято. Проверю текущий head, включая follow-up 2ebba78.

Проверка будет включать сохранение V1 input-binding identity без фиктивной миграции на V2. Также проверю causal identity, lease semantics, границу generic BUILD и Arb source authority, cleanup/lifecycle paths, публичный API и claims в документации.

GitHub Actions и runner infrastructure не входят в проверку.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@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.

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/build/transport.py (1)

1083-1101: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Верните типизированный отказ из DockerBuildRequestV1.

DockerBuildRequestV1(...) является публичным путём и поднимает raw TypeError для invalid attempt, capability, sealed input и output cap. Потребитель не может классифицировать причину отказа без разбора текста исключения.

Добавьте domain error с закрытой суммой причин, например DockerBuildRequestErrorV1, и замените все эти TypeError на него.

As per coding guidelines: «Новый или изменяемый public path не должен вызывать panic и не должен получать plausible fallback; invalid, unreachable, unsupported и incomplete context должны возвращаться типизированно».

🤖 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/build/transport.py` around lines 1083 - 1101, Добавьте
закрытую типизированную ошибку домена DockerBuildRequestErrorV1 с отдельными
причинами для invalid attempt, capability, sealed input и output limit, затем в
публичном конструкторе DockerBuildRequestV1 замените все соответствующие
TypeError на эту ошибку, сохранив существующую валидацию и контекст причины.

Source: Coding guidelines

♻️ Duplicate comments (1)
proof/region/v1/tests/test_build.py (1)

40-45: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Устраните дублирование golden-хэша инвентаря и числа тестов.

ARB_INVENTORY_SHA256_V1 дублирует arb_gate.EXPECTED_TEST_INVENTORY_SHA256 из proof/region/v1/arb/tests/gate.py:18. Число 169 также повторяется дважды в этом файле (строки 274-275). При изменении набора тестов нужно вручную синхронизировать два литерала хэша и число в двух местах. Расхождение обнаружится только после падения одного из тестов, без явного указания причины.

Ссылайтесь на хэш из arb_gate напрямую и вынесите ожидаемое количество тестов в одну именованную константу.

♻️ Предлагаемая правка
-ARB_INVENTORY_SHA256_V1 = (
-    "e93060f8fa2ff5035bcc394f92dccc5f7f8baf7f9e019fc13cda933295393dce"
-)
+ARB_INVENTORY_SHA256_V1 = arb_gate.EXPECTED_TEST_INVENTORY_SHA256
+ARB_TEST_COUNT_V1 = 169
 ARB_ORDER_SHA256_V1 = (
     "78712585ffac242f31c3a385ab98c047a3501df1037b5830d5428ec9f39bf9d6"
 )
-        self.assertEqual(len(identifiers), 169)
-        self.assertEqual(len(set(identifiers)), 169)
+        self.assertEqual(len(identifiers), ARB_TEST_COUNT_V1)
+        self.assertEqual(len(set(identifiers)), ARB_TEST_COUNT_V1)

Also applies to: 274-275

🤖 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/tests/test_build.py` around lines 40 - 45, Устраните
дублирование в тестах: замените локальный ARB_INVENTORY_SHA256_V1 прямой ссылкой
на arb_gate.EXPECTED_TEST_INVENTORY_SHA256, а повторяющееся число 169 в
проверках вокруг тестовых подсчётов вынесите в одну именованную константу и
используйте её в обоих местах.
🤖 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.

Outside diff comments:
In `@proof/region/v1/build/transport.py`:
- Around line 1083-1101: Добавьте закрытую типизированную ошибку домена
DockerBuildRequestErrorV1 с отдельными причинами для invalid attempt,
capability, sealed input и output limit, затем в публичном конструкторе
DockerBuildRequestV1 замените все соответствующие TypeError на эту ошибку,
сохранив существующую валидацию и контекст причины.

---

Duplicate comments:
In `@proof/region/v1/tests/test_build.py`:
- Around line 40-45: Устраните дублирование в тестах: замените локальный
ARB_INVENTORY_SHA256_V1 прямой ссылкой на
arb_gate.EXPECTED_TEST_INVENTORY_SHA256, а повторяющееся число 169 в проверках
вокруг тестовых подсчётов вынесите в одну именованную константу и используйте её
в обоих местах.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: ba71882e-f3e0-4804-8e1a-c66a9b70b8c9

📥 Commits

Reviewing files that changed from the base of the PR and between 1ff6dad and 2ebba78.

📒 Files selected for processing (10)
  • proof/region/v1/PROTOCOL.md
  • proof/region/v1/arb/receipt.py
  • proof/region/v1/arb/tests/gate.py
  • proof/region/v1/arb/tests/test_build_identity_v2.py
  • proof/region/v1/arb/tests/test_receipt.py
  • proof/region/v1/arb/tests/test_transport.py
  • proof/region/v1/build/input.py
  • proof/region/v1/build/transport.py
  • proof/region/v1/tests/test_build.py
  • proof/region/v1/tests/test_build_identity.py

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

Актуальный follow-up 48dd558 устраняет подтверждённый stale-FD double-close: cleanup повторяет close() только через исходный stream-owner и никогда по сохранённому числовому FD. Добавлены RED-контрпримеры для FD reuse, transient и persistent KeyboardInterrupt; полный локальный набор проверок зелёный. Просьба ревьюировать exact head.

@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '== HEAD and target commit =='
git rev-parse HEAD
git show -s --format='%H%n%P%n%s' 48dd558

printf '%s\n' '== Files changed by target commit =='
git diff-tree --no-commit-id --name-status -r 48dd558

printf '%s\n' '== Target commit diff =='
git show --format=fuller --find-renames --find-copies --stat 48dd558
git show --format= --find-renames --find-copies --unified=80 48dd558

printf '%s\n' '== BUILD module outline =='
ast-grep outline proof/region/v1/build/transport.py --items all --view expanded | sed -n '1,260p'

printf '%s\n' '== Cleanup/stream/descriptor references =='
rg -n -C 5 -i '(\bcleanup\b|\bclose\s*\(|\bfileno\s*\(|\bfd\b|KeyboardInterrupt|Popen|stream.owner|stream_owner)' \
  proof/region/v1/build/transport.py proof/region/v1/tests/test_build.py proof/region/v1/arb/tests/test_transport.py || true

Length of output: 195977


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '== Observe-command lifecycle and close helper =='
sed -n '2180,2365p' proof/region/v1/build/transport.py
sed -n '2440,2910p' proof/region/v1/build/transport.py

printf '%s\n' '== Lease, CID authority, and container cleanup =='
sed -n '1140,1235p' proof/region/v1/build/transport.py
sed -n '2960,3120p' proof/region/v1/build/transport.py

printf '%s\n' '== Numeric descriptor close call sites in transport =='
rg -n -C 4 'os\.close\s*\(' proof/region/v1/build/transport.py

printf '%s\n' '== Public API and generic BUILD import boundary =='
sed -n '1,120p' proof/region/v1/build/input.py
sed -n '1,125p' proof/region/v1/build/transport.py
rg -n -C 3 '(from |import )(arb|pipeline|receipt|provenance|formula|comparator|mpfi|region_proof_protocol)\b' \
  proof/region/v1/build || true

printf '%s\n' '== V1 input binding identity definitions and consumers =='
rg -n -C 5 '(binding_identity|seal_input_v1|input_bundle_identity|input_bundle_identity_v|input.*identity.*v[12])' \
  proof/region/v1/build/input.py proof/region/v1/build/transport.py \
  proof/region/v1/arb/pipeline.py proof/region/v1/arb/receipt.py

printf '%s\n' '== Protocol claims relevant to cleanup and authority =='
rg -n -C 5 -i '(BUILD|Docker|CID|cleanup|lease|same-UID|Popen|binding|V1|V2)' \
  proof/region/v1/PROTOCOL.md | sed -n '1,360p'

Length of output: 84492


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '== Controller state and capability lease methods =='
ast-grep outline proof/region/v1/build/transport.py --items all --match 'ControlledBuildTransportV1|NativeDockerBuildBackendV1' --view expanded
rg -n -C 8 '^\s*def (probe|build|_consume|_in_owner_process_v1|_bound_request_capability_v1|run_build)\b|class ControlledBuildTransportV1|class NativeDockerBuildBackendV1' \
  proof/region/v1/build/transport.py
sed -n '3260,3800p' proof/region/v1/build/transport.py

printf '%s\n' '== Arb source authority to BUILD handoff =='
ast-grep outline proof/region/v1/arb/pipeline.py --items all --match 'arb_input_is_bound_v1|_seal_build_input_bundle_v1|ControlledPipelineV1|DiagnosticBuildObservationV1' --view expanded
rg -n -C 8 '^\s*def (_arb_input_binding_identity_v1|arb_input_is_bound_v1|_seal_build_input_bundle_v1)\b|class (ControlledPipelineV1|DiagnosticBuildObservationV1)' \
  proof/region/v1/arb/pipeline.py
sed -n '340,465p' proof/region/v1/arb/pipeline.py
sed -n '1570,1670p' proof/region/v1/arb/pipeline.py

printf '%s\n' '== PR base and complete changed-file summary =='
base="$(git merge-base HEAD origin/main 2>/dev/null || git merge-base HEAD main 2>/dev/null || true)"
printf 'base=%s\n' "$base"
if [ -n "$base" ]; then
  git diff --stat "$base"..HEAD
  git diff --check "$base"..HEAD
  git diff --name-status "$base"..HEAD
fi

printf '%s\n' '== Removed cleanup authority API references =='
rg -n -C 2 '(container_name_prefix|container_name|cid_file)' \
  proof/region/v1/build proof/region/v1/arb proof/region/v1/PROTOCOL.md \
  -g '*.py' -g '*.md'

printf '%s\n' '== Exact follow-up static test references =='
rg -n -C 3 '(stream_close_fallback_requires_current_stream_ownership|persistent_stream_close_interrupt|stream_close_interrupt_still_closes)' \
  proof/region/v1/tests/test_build.py

Length of output: 52102


@lemone112 Проверил exact head 48dd5585dfa5679fb3986f562f51ec9d285e0fbd.

Не нашёл blocking findings в запрошенной области.

  • NativeDockerBuildBackendV1._close_owned_stream() больше не вызывает os.close() для сохранённого stream FD.
  • Повторный close() выполняется только через исходный stream owner и только когда owner сообщает closed is False.
  • Оставшийся os.close() закрывает только descriptor, который _docker_issued_container_id_v1() сам открыл для чтения private CID file.
  • Lease остаётся привязан к adapter, capability и creator PID. Fork и concurrent reuse отклоняются до build.
  • Cleanup принимает adapter-owned lease, использует только полный CID из private path, сверяет exact CID через docker container inspect и проверяет отсутствие после удаления.
  • DockerBuildRequestV1 не переносит CID path или container name через публичную BUILD boundary.
  • build.input и build.transport не импортируют Arb-specific authority.
  • Arb сохраняет _arb_input_binding_identity_v1(). Pipeline, transport и receipt replay продолжают проверять V1 binding identity. Фиктивной V2-миграции нет.
  • PROTOCOL.md согласован с реализацией для same-UID ограничения, private CID path, cleanup и случая interruption во время Popen.
  • git diff --check завершился без замечаний.

Я не запускал тесты в sandbox, так как среда разрешает только статическую проверку без выполнения repository code.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@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

🤖 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/tests/test_build.py`:
- Around line 1859-1880: Перенесите очистку дочернего процесса, его потоков и
wrapped_stdout из последовательного блока после утверждений в гарантированный
finally либо зарегистрируйте её сразу после spawn в тесте вокруг
backend._observe_command. Обеспечьте закрытие descriptor и завершение процесса
даже при исключении из os.fstat, сохранив последующие проверки stderr_closed,
close_calls и cleanup_calls.
🪄 Autofix (Beta)

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: ce8be34c-1d93-414d-ab53-c24dc053db17

📥 Commits

Reviewing files that changed from the base of the PR and between 2ebba78 and 48dd558.

📒 Files selected for processing (4)
  • proof/region/v1/arb/tests/test_pipeline.py
  • proof/region/v1/arb/tests/test_transport.py
  • proof/region/v1/build/transport.py
  • proof/region/v1/tests/test_build.py

Comment thread proof/region/v1/tests/test_build.py

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

Финальный узкий follow-up ba87cc4: hostile persistent-interrupt fixture регистрирует cleanup сразу после spawn, поэтому неожиданный assertion/error не может оставить child или stream. Production-код не менялся; полный normal/-O набор локально зелёный. Просьба проверить exact head.

@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown

Tip

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '== Exact HEAD and requested commit =='
git rev-parse HEAD
git show -s --format='%H%n%P%n%s' ba87cc4

printf '%s\n' '== Files changed by ba87cc4 =='
git diff-tree --no-commit-id --name-status -r ba87cc4
git show --format=fuller --stat ba87cc4
git show --format= --find-renames --find-copies --unified=100 ba87cc4

printf '%s\n' '== Relevant fixture and interruption test locations =='
rg -n -C 12 -i \
  '(persistent.*interrupt|interrupt.*persistent|hostile.*interrupt|register.*cleanup|addCleanup|cleanup.*spawn|spawn.*cleanup|KeyboardInterrupt)' \
  proof/region/v1/tests/test_build.py proof/region/v1/arb/tests/test_transport.py || true

printf '%s\n' '== Structural map of changed test module =='
ast-grep outline proof/region/v1/tests/test_build.py --items all --view expanded | sed -n '1,320p'

printf '%s\n' '== Production files modified after prior reviewed commit =='
git diff --name-status 48dd558..ba87cc4 -- \
  'proof/region/v1/build/**' 'proof/region/v1/arb/**' 'proof/region/v1/PROTOCOL.md'

printf '%s\n' '== Whitespace validation =='
git diff --check 48dd558..ba87cc4

Length of output: 63662


@lemone112 Проверил exact head ba87cc431e60f50520cc2cd1eb86b9ad8f5e1882.

Нашёл один узкий finding в fixture.

  • ba87cc4 изменяет только proof/region/v1/tests/test_build.py.
  • Production-код после 48dd558 не изменялся.
  • git diff --check завершился без замечаний.

P2 — Register the emergency cleanup before wrapper setup.

В spawn() Popen возвращает child на Line 1852. Cleanup регистрируется только на Line 1857. Между этими точками выполняются spawned.append, создание CloseAlwaysInterrupts, wrapped_stdout.append и присваивание process.stdout.

Если любая операция в этом промежутке выбросит исключение, cleanup_spawned() не выполнится. Тогда fixture может оставить child или исходный stream. Это противоречит заявленной цели follow-up.

Зарегистрируйте cleanup сразу после real_popen(...). Передайте ему исходный process.stdout или отдельный mutable holder. Затем создавайте wrapper и заменяйте process.stdout.

Остальные ранее проверенные invariants для production cleanup, stream ownership и lease semantics не затронуты.

You are interacting with an AI system.

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

Exact head f2a757f: устраняет найденный край fixture-lifecycle. Cleanup теперь регистрируется непосредственно после Popen и удерживает исходный stdout до появления hostile wrapper; полный normal/-O набор локально зелёный. Это последний узкий follow-up #508.

@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown

Tip

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '== Exact HEAD and requested commit =='
git rev-parse HEAD
git show -s --format='%H%n%P%n%s' f2a757f

printf '%s\n' '== Changed files and exact diff =='
git diff-tree --no-commit-id --name-status -r f2a757f
git show --format=fuller --stat f2a757f
git show --format= --find-renames --find-copies --unified=120 f2a757f

printf '%s\n' '== Fixture lifecycle context =='
rg -n -C 18 -i \
  '(def spawn|real_popen|addCleanup|cleanup_spawned|CloseAlwaysInterrupts|wrapped_stdout|KeyboardInterrupt|persistent.*interrupt|interrupt.*persistent)' \
  proof/region/v1/tests/test_build.py

printf '%s\n' '== Structural map of relevant test module =='
ast-grep outline proof/region/v1/tests/test_build.py --items all --view expanded | sed -n '1,360p'

printf '%s\n' '== Production changes since previous reviewed commit =='
git diff --name-status ba87cc4..f2a757f -- \
  'proof/region/v1/build/**' 'proof/region/v1/arb/**' 'proof/region/v1/PROTOCOL.md'

printf '%s\n' '== Whitespace validation =='
git diff --check ba87cc4..f2a757f

Length of output: 53991


@lemone112 Проверил exact head f2a757f1c38a290a4b11e8077e5bb1ab43c27b9c.

Blocking findings не найдены.

  • f2a757f изменяет только proof/region/v1/tests/test_build.py.
  • В test_persistent_stream_close_interrupt_keeps_release_failure_honest() fixture регистрирует cleanup_spawned сразу после успешного real_popen(...).
  • Cleanup получает исходный process.stdout до создания CloseAlwaysInterrupts и до замены process.stdout.
  • Если spawned.append, создание wrapper или присваивание process.stdout завершится с ошибкой, ранее зарегистрированный cleanup остановит child и закроет stdin, stderr и исходный stdout.
  • Cleanup не зависит от hostile wrapper.
  • Production-код после ba87cc4 не изменялся.
  • git diff --check ba87cc4..f2a757f завершился без замечаний.

Предыдущий finding по fixture lifecycle устранён.

You are interacting with an AI system.

@lemone112

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

Exact head d78bfb4: публичные value-errors build/input теперь типизированы; проверь границу WRONG_TYPE/INVALID_VALUE, default-overflow и отсутствие изменения private token/call-shape.

@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown

Tip

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '== Exact HEAD and requested commit =='
git rev-parse HEAD
git show -s --format='%H%n%P%n%s' d78bfb4

printf '%s\n' '== Changed files and target diff =='
git diff-tree --no-commit-id --name-status -r d78bfb4
git show --format=fuller --stat d78bfb4
git show --format= --find-renames --find-copies --unified=100 d78bfb4

printf '%s\n' '== Public build input API map =='
ast-grep outline proof/region/v1/build/input.py --items all --view expanded

printf '%s\n' '== Error enum, public constructors, defaults, and token/call-shape context =='
rg -n -C 10 \
  '(class InputReasonV1|class InputErrorV1|class CanonicalInputLimitsV1|class SealedInputV1|def seal_input_v1|def canonical_ustar_v1|WRONG_TYPE|INVALID_VALUE|__post_init__|_token|default)' \
  proof/region/v1/build/input.py proof/region/v1/tests/test_build.py proof/region/v1/arb/tests/test_transport.py

printf '%s\n' '== All direct ValueError/TypeError and InputError sites in input module =='
rg -n -C 5 '(raise (ValueError|TypeError|InputErrorV1)|except (ValueError|TypeError))' \
  proof/region/v1/build/input.py

printf '%s\n' '== Focused tests for typed validation and overflow =='
rg -n -C 12 -i \
  '(wrong.type|invalid.value|value.error|type.error|overflow|limit|private.token|call.shape|seal_input_v1|canonical_ustar_v1)' \
  proof/region/v1/tests/test_build.py proof/region/v1/arb/tests/test_transport.py

Length of output: 134267


@lemone112 Проверил exact head d78bfb48220cd48a3bb60583ee8e3b64802e2d56.

Blocking findings не найдены в указанной области.

  • CanonicalInputLimitsV1 теперь разделяет ошибки корректно. На Line 47 не-int значения, включая bool, дают InputReasonV1.WRONG_TYPE. На Line 49 нуль и значения >= 2**64 дают InputReasonV1.INVALID_VALUE.
  • seal_input_v1() проверяет публичные аргументы до private constructor. На Lines 218-225 неверный тип binding_identity или contents даёт WRONG_TYPE. Неверный digest и пустой contents дают INVALID_VALUE.
  • Default-overflow обработан. После вычисления default max_encoded_bytes на Lines 88-98 код повторно вызывает _positive_u64(). Если derived value не входит в положительный u64, код возвращает INVALID_VALUE для поля max_encoded_bytes. Добавленный тест покрывает этот случай.
  • CanonicalInputLimitsV1 сохраняет прежнюю сигнатуру и optional fourth argument max_encoded_bytes: int | None = None.
  • seal_input_v1(binding_identity, contents) сохраняет прежнюю call shape.
  • SealedInputV1.__new__() сохраняет keyword-only _token без default. Прямое создание с чужим token продолжает давать TypeError. Изменение public validation не расширяет private construction authority.
  • Тесты также проверяют отсутствие аргументов и чужой _token как TypeError.

Я не запускал тесты в sandbox. Проверка основана на статическом анализе diff и тестовых контрактов.

You are interacting with an AI system.

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@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: 3

♻️ Duplicate comments (1)
proof/region/v1/tests/test_build.py (1)

40-46: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Возьмите inventory hash из arb_gate как единственный источник истины.

ARB_INVENTORY_SHA256_V1 снова повторяет литерал из proof/region/v1/arb/tests/gate.py:17-19. Оба значения обновлены в этом PR вручную. При следующем изменении набора тестов расхождение проявится только падением одного из двух тестов.

Импортируйте значение из arb_gate.

♻️ Предлагаемая правка
-ARB_INVENTORY_SHA256_V1 = (
-    "bd62145334bcd64d9c1d95551b2856ced34f97e6fee3f60447fe0170ae116930"
-)
+ARB_INVENTORY_SHA256_V1 = arb_gate.EXPECTED_TEST_INVENTORY_SHA256
🤖 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/tests/test_build.py` around lines 40 - 46, Replace the
duplicated ARB_INVENTORY_SHA256_V1 literal in the test constants with the value
imported from arb_gate, making arb_gate the single source of truth while
preserving the existing test count and order hash constants.
🤖 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/arb/tests/test_transport.py`:
- Around line 846-940: Вынесите повторяющуюся сборку backend и request в
module-level helper `_native_backend_with_request`, принимающий необязательный
bundle и возвращающий `(backend, request)`, чтобы все тесты использовали единый
контракт `DockerBuildRequestV1`. Также добавьте отдельный helper для сценария
отказа освобождения lease и замените им повторяющиеся `report_cleanup_failure` в
тестах, сохранив текущие проверки и результаты.

In `@proof/region/v1/build/transport.py`:
- Around line 2377-2391: При создании DockerBuildObserverFailureV1 в ветке
проверки DockerBuildCleanupFailureV1 передайте исходное значение input_progress
из canonical_observation, чтобы подменённое наблюдение сохраняло прогресс sealed
input и корректно классифицировалось ControlledBuildTransportV1.
- Around line 2479-2483: В ветви, возвращающей DockerBuildObserverFailureV1 для
нек canonical native Docker build observation, усеките объединённую строку с
префиксом и detail до _DIAGNOSTIC_DETAIL_TEXT_LIMIT_V1 перед передачей
конструктору; примените тот же подход, что уже используется в соседней
защищённой ветви.

---

Duplicate comments:
In `@proof/region/v1/tests/test_build.py`:
- Around line 40-46: Replace the duplicated ARB_INVENTORY_SHA256_V1 literal in
the test constants with the value imported from arb_gate, making arb_gate the
single source of truth while preserving the existing test count and order hash
constants.
🪄 Autofix (Beta)

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: 2c7f5ba5-f601-4e88-8781-a9e2d1aa9ce1

📥 Commits

Reviewing files that changed from the base of the PR and between 48dd558 and 7a82231.

📒 Files selected for processing (6)
  • proof/region/v1/arb/tests/gate.py
  • proof/region/v1/arb/tests/test_build_identity_v2.py
  • proof/region/v1/arb/tests/test_transport.py
  • proof/region/v1/build/input.py
  • proof/region/v1/build/transport.py
  • proof/region/v1/tests/test_build.py

Comment thread proof/region/v1/arb/tests/test_transport.py
Comment on lines +2377 to +2391
if (
type(canonical_observation) is DockerBuildCleanupFailureV1
and any(
record.resource is CleanupResourceV1.DOCKER_CID_ROOT
for record in canonical_observation.failures
)
):
observation = DockerBuildObserverFailureV1(
"native Docker build observation already contains a "
"CID-root cleanup failure",
canonical_observation.stdout,
canonical_observation.stderr,
)
else:
observation = canonical_observation

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Сохраните input_progress при подмене наблюдения на DockerBuildObserverFailureV1.

canonical_observation типа DockerBuildCleanupFailureV1 содержит input_progress. Конструктор вызывается только с тремя аргументами, поэтому input_progress становится None. Публичное наблюдение теряет прогресс передачи sealed input, а ControlledBuildTransportV1 классифицирует такой отказ как OBSERVER_FAILURE без данных о переданных байтах.

🛡️ Предлагаемое изменение
                     observation = DockerBuildObserverFailureV1(
                         "native Docker build observation already contains a "
                         "CID-root cleanup failure",
                         canonical_observation.stdout,
                         canonical_observation.stderr,
+                        canonical_observation.input_progress,
                     )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (
type(canonical_observation) is DockerBuildCleanupFailureV1
and any(
record.resource is CleanupResourceV1.DOCKER_CID_ROOT
for record in canonical_observation.failures
)
):
observation = DockerBuildObserverFailureV1(
"native Docker build observation already contains a "
"CID-root cleanup failure",
canonical_observation.stdout,
canonical_observation.stderr,
)
else:
observation = canonical_observation
if (
type(canonical_observation) is DockerBuildCleanupFailureV1
and any(
record.resource is CleanupResourceV1.DOCKER_CID_ROOT
for record in canonical_observation.failures
)
):
observation = DockerBuildObserverFailureV1(
"native Docker build observation already contains a "
"CID-root cleanup failure",
canonical_observation.stdout,
canonical_observation.stderr,
canonical_observation.input_progress,
)
else:
observation = canonical_observation
🤖 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/build/transport.py` around lines 2377 - 2391, При создании
DockerBuildObserverFailureV1 в ветке проверки DockerBuildCleanupFailureV1
передайте исходное значение input_progress из canonical_observation, чтобы
подменённое наблюдение сохраняло прогресс sealed input и корректно
классифицировалось ControlledBuildTransportV1.

Comment on lines +2479 to +2483
return DockerBuildObserverFailureV1(
"native Docker build observation is not canonical; " + detail,
b"",
b"",
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Усекайте объединённый detail перед созданием DockerBuildObserverFailureV1.

Префикс "native Docker build observation is not canonical; " добавляет 46 символов. detail допускает длину до _DIAGNOSTIC_DETAIL_TEXT_LIMIT_V1 (4096). Сумма превысит границу, и конструктор поднимет TypeError внутри finally публичного run_build. Сейчас все значения detail — короткие литералы, поэтому путь недостижим. Защитите его от будущего изменения источника detail.

Ветвь на строках 2487-2491 имеет ту же арифметику, но уже защищена внутренним обработчиком.

♻️ Предлагаемое изменение
         else:
+            # The joined detail must stay inside the bounded diagnostic limit;
+            # otherwise a typed failure would become an exception in `finally`.
+            combined = "native Docker build observation is not canonical; " + detail
             return DockerBuildObserverFailureV1(
-                "native Docker build observation is not canonical; " + detail,
+                combined[:_DIAGNOSTIC_DETAIL_TEXT_LIMIT_V1],
                 b"",
                 b"",
             )

Примените то же усечение на строке 2488.

🤖 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/build/transport.py` around lines 2479 - 2483, В ветви,
возвращающей DockerBuildObserverFailureV1 для нек canonical native Docker build
observation, усеките объединённую строку с префиксом и detail до
_DIAGNOSTIC_DETAIL_TEXT_LIMIT_V1 перед передачей конструктору; примените тот же
подход, что уже используется в соседней защищённой ветви.

@lemone112
lemone112 marked this pull request as ready for review August 1, 2026 10:38
@lemone112
lemone112 force-pushed the agent/build-transport branch from 7a82231 to 284ee16 Compare August 1, 2026 12:55
@lemone112
lemone112 marked this pull request as draft August 1, 2026 12:55

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@lemone112

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

Проверьте текущий exact head 8998ada: source-bound dispatcher claim, split recipe BUILD/test/evaluator coordinates, independent comparator replay, causal identity and receipt semantics. Не расширяйте review на Actions/runner infrastructure.

@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown

Tip

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

target="8998ada1b4128514579e3e50afbb9d6a68ac91d4"

printf '%s\n' '== Exact commit =='
printf 'HEAD: '; git rev-parse HEAD
git show -s --format='target: %H%nparents: %P%nsubject: %s' "$target"

printf '%s\n' '== Target change set =='
git diff-tree --no-commit-id --name-status -r "$target"
git show --format=fuller --stat "$target"
git show --format= --find-renames --find-copies --unified=90 "$target"

printf '%s\n' '== Changed Python module outlines =='
git diff-tree --no-commit-id --name-only -r "$target" | while IFS= read -r f; do
  case "$f" in
    *.py)
      printf '\n--- %s ---\n' "$f"
      ast-grep outline "$f" --items all --view expanded | sed -n '1,260p'
      ;;
  esac
done

printf '%s\n' '== Dispatcher, claim, recipe-coordinate, comparator, and receipt symbols =='
rg -n -C 10 -i \
  '(dispatcher|dispatch|source.bound|source_bound|claim|recipe|build.coordinate|test.coordinate|evaluator.coordinate|comparator.*replay|replay.*comparator|causal.identity|causal_identity|receipt)' \
  proof/region/v1/arb proof/region/v1/build proof/region/v1/PROTOCOL.md \
  -g '*.py' -g '*.md' | sed -n '1,1600p'

printf '%s\n' '== Relevant function and class definitions =='
rg -n -C 5 \
  '^\s*(class|def) .*([Dd]ispatch|[Cc]laim|[Rr]ecipe|[Cc]omparator|[Rr]eplay|[Rr]eceipt|[Cc]ausal)' \
  proof/region/v1/arb proof/region/v1/build -g '*.py' | sed -n '1,1200p'

printf '%s\n' '== Generic BUILD boundary imports =='
rg -n -C 3 '(from |import )(arb|pipeline|receipt|provenance|formula|comparator|mpfi|region_proof_protocol)\b' \
  proof/region/v1/build -g '*.py' || true

printf '%s\n' '== Test contracts for requested semantics =='
rg -n -C 10 -i \
  '(dispatcher|source.bound|split.recipe|recipe.*coordinate|comparator.*replay|causal.identity|receipt.*replay|receipt.*claim)' \
  proof/region/v1/arb/tests proof/region/v1/tests -g '*.py' | sed -n '1,1600p'

printf '%s\n' '== Protocol documentation claims =='
rg -n -C 8 -i \
  '(dispatcher|source.bound|recipe|coordinate|comparator|replay|causal|receipt)' \
  proof/region/v1/PROTOCOL.md | sed -n '1,1000p'

printf '%s\n' '== Whitespace validation =='
git diff --check "${target}^" "$target"

Length of output: 193846


🏁 Script executed:

#!/bin/bash
set -euo pipefail

target="8998ada1b4128514579e3e50afbb9d6a68ac91d4"

printf '%s\n' '== Changed files =='
git diff-tree --no-commit-id --name-status -r "$target"

printf '%s\n' '== Exact patch =='
git diff --find-renames --find-copies --unified=140 "${target}^" "$target"

printf '%s\n' '== Receipt implementation map =='
ast-grep outline proof/region/v1/arb/receipt.py --items all --view expanded | sed -n '1,420p'

printf '%s\n' '== Receipt source / comparator / build / run replay bodies =='
sed -n '1,290p' proof/region/v1/arb/receipt.py
sed -n '385,850p' proof/region/v1/arb/receipt.py

printf '%s\n' '== Pipeline comparator derivation and source-coordinate bodies =='
ast-grep outline proof/region/v1/arb/pipeline.py --items all \
  --match 'derive_arb_comparator_for_build_v1|DiagnosticArbComparatorV1|BuildSources|PipelineRequestV1' \
  --view expanded
sed -n '650,1125p' proof/region/v1/arb/pipeline.py
sed -n '1500,1750p' proof/region/v1/arb/pipeline.py

printf '%s\n' '== Recipe dispatch and coordinate sources =='
for f in proof/region/v1/arb/build.sh proof/region/v1/arb/build-inner.sh; do
  if [ -f "$f" ]; then
    printf '\n--- %s ---\n' "$f"
    cat -n "$f"
  fi
done
rg -n -C 8 -i '(build.sh|build-inner.sh|formula.*source|evaluator.*source|test.*observation|wrapper.*source|operation.*allowlist|legal.*file)' \
  proof/region/v1/arb/pipeline.py proof/region/v1/arb/receipt.py \
  proof/region/v1/arb/tests/test_pipeline.py proof/region/v1/arb/tests/test_receipt.py \
  -g '*.py' | sed -n '1,1800p'

printf '%s\n' '== Targeted adversarial tests =='
rg -n -A45 -B8 \
  'test_(each_self_consistent_comparator_coordinate_is_rederived|inner_recipe_mutation_is_not_evaluator_source|source_replay_rejects_a_self_consistent_forged_manifest|job_first_binds_at_run_not_source_or_build)' \
  proof/region/v1/arb/tests/test_pipeline.py proof/region/v1/arb/tests/test_receipt.py

printf '%s\n' '== Dispatcher sources and tests =='
rg -n -C 12 -i '(source.owned.dispatch|dispatcher|dispatch.*source|exec /usr/bin/env -i|script_path|script_dir)' \
  proof/region/v1/arb/build.sh proof/region/v1/arb/build-inner.sh \
  proof/region/v1/arb/tests/test_build_recipe.py \
  -g '*.sh' -g '*.py'

Length of output: 221591


@lemone112 Проверил exact head 8998ada1b4128514579e3e50afbb9d6a68ac91d4.

Blocking findings в запрошенной области не найдены.

  • build.sh выполняет source-owned dispatch. Он создаёт clean child через /usr/bin/env -i до path resolution. Он разрешает путь dispatcher и запускает только regular, non-symlink build-inner.sh.
  • Split recipe coordinates согласованы. build.sh и build-inner.sh исключены из evaluator_source. Они входят в build_identity и test_observation. Изменение inner recipe меняет BUILD и test coordinates, но не маскируется как изменение evaluator source.
  • pipeline.derive_arb_comparator_for_build_v1() теперь является versioned cross-module verifier. receipt._comparator_replays_v1() заново выводит все десять preimages из retained request и BUILD observation.
  • Replay не принимает самосогласованный forged comparator. Он сравнивает derived preimages, fresh manifest, resolved manifest и identity с retained observation.
  • Source identity связывает source lock, admitted archives и build-source coordinates. Он намеренно не включает job.
  • Build identity связывает source identity, Docker capability, policy, sealed bundle, два transfer records, binary и comparator identity.
  • Run identity впервые связывает job, invocation, platform, observed process, transcript и RunClaimV1.
  • SourceBoundEvaluatorReceiptV1 связывает provenance policy identity, run claim identity и replay evidence identity. Public raw claims и diagnostic objects не создают receipt.
  • Тесты покрывают self-consistent comparator mutations, source-manifest forgery, recipe-coordinate split и job-first-at-run semantics.
  • git diff --check завершился без замечаний.

Я не проверял GitHub Actions или runner infrastructure. Я также не запускал repository code в sandbox.

You are interacting with an AI system.

Copy link
Copy Markdown
Collaborator Author

Этот stacked-срез поглощён терминальным PR #514 (base main, exact head 6e8bb6445cf5564bad1b590690a43a235f4dbfbd). Полезная BUILD/transport-граница сохранена и прошла повторную проверку в терминальной ветке. Закрываю как superseded; код не удалён.

@lemone112 lemone112 closed this Aug 2, 2026
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