Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/actionlint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
self-hosted-runner:
labels:
- labcolors-ephemeral
230 changes: 230 additions & 0 deletions .github/workflows/arb.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@
name: Arb evaluator build and runtime

on:
workflow_dispatch:
push:
branches: [main]
paths:
- .github/workflows/arb.yml
- crates/labcolors-core/contracts/contextual-region-formula-v1.lcir
- proof/region/v1/**
pull_request:
paths:
- .github/workflows/arb.yml
- crates/labcolors-core/contracts/contextual-region-formula-v1.lcir
- proof/region/v1/**

permissions:
contents: read

concurrency:
group: arb-evaluator-build-runtime-${{ github.event_name == 'pull_request' && github.event.pull_request.number || github.run_id }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}

jobs:
diagnostic-build-runtime:
name: two offline builds and runtime tests (no artifact)
# Docker is root-equivalent, so this label is provisioned only on a fresh
# one-job VM whose runner group is bound to this exact workflow revision.
runs-on: [self-hosted, Linux, X64, labcolors-ephemeral]
timeout-minutes: 360
env:
PYTHONDONTWRITEBYTECODE: "1"
PYTHONHASHSEED: "0"
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false

- name: complete fast Arb contract with exact skip manifest
shell: bash
run: |
set -euo pipefail
python3 proof/region/v1/arb/tests/gate.py
PYTHONOPTIMIZE=2 python3 proof/region/v1/arb/tests/gate.py

- name: bind run-local native paths after the fast gate
shell: bash
run: |
set -euo pipefail
scope="/sys/fs/cgroup/labcolors-$GITHUB_RUN_ID-$GITHUB_RUN_ATTEMPT"
binary="$RUNNER_TEMP/arb-native-$GITHUB_RUN_ID-$GITHUB_RUN_ATTEMPT"
{
echo "LABCOLORS_CGROUP_SCOPE_V1=$scope"
echo "LABCOLORS_EXECUTOR_CGROUP_V1=$scope/proof"
echo "LABCOLORS_ARB_NATIVE_BINARY=$binary"
} >> "$GITHUB_ENV"

- name: acquire and hash-check exact source archives
shell: bash
run: |
set -euo pipefail
source_dir="$RUNNER_TEMP/arb-source-$GITHUB_RUN_ID-$GITHUB_RUN_ATTEMPT"
install -d -m 0700 "$source_dir"
echo "LABCOLORS_ARB_SOURCE_DIR=$source_dir" >> "$GITHUB_ENV"
export PYTHONPATH="$GITHUB_WORKSPACE/proof/region/v1"
python3 - <<'PY' > "$source_dir/lock.tsv"
import provenance

for source in provenance.arb_source_lock_v1().sources:
print(
source.role.name,
source.archive_url,
source.archive_sha256.hex(),
source.archive_length,
sep="\t",
)
PY
count=0
while IFS=$'\t' read -r role url digest length; do
archive="$source_dir/${role}.archive"
curl --fail --location --silent --show-error \
--connect-timeout 30 --max-time 600 --retry 3 --retry-all-errors \
"$url" --output "$archive"
test "$(stat --format=%s "$archive")" = "$length"
echo "$digest $archive" | sha256sum --check --strict
case "$role" in
GMP) echo "LABCOLORS_GMP_ARCHIVE=$archive" >> "$GITHUB_ENV" ;;
MPFR) echo "LABCOLORS_MPFR_ARCHIVE=$archive" >> "$GITHUB_ENV" ;;
FLINT_ARB) echo "LABCOLORS_FLINT_ARCHIVE=$archive" >> "$GITHUB_ENV" ;;
*) exit 64 ;;
esac
count=$((count + 1))
done < "$source_dir/lock.tsv"
Comment thread
coderabbitai[bot] marked this conversation as resolved.
test "$count" -eq 3

- name: acquire the exact pinned OCI manifest
shell: bash
run: |
set -euo pipefail
export PYTHONPATH="$GITHUB_WORKSPACE/proof/region/v1:$GITHUB_WORKSPACE/proof/region/v1/arb"
docker_path="$(realpath "$(command -v docker)")"
test -f "$docker_path"
test ! -L "$docker_path"
image="$(python3 - <<'PY'
import pipeline
print(pipeline.OCI_IMAGE_REFERENCE_V1)
PY
)"
"$docker_path" image inspect "$image" >/dev/null 2>&1 ||
/usr/bin/timeout --signal=TERM --kill-after=30s 15m \
"$docker_path" pull "$image"
echo "LABCOLORS_ARB_PIPELINE_DOCKER=$docker_path" >> "$GITHUB_ENV"

- name: require the exact diagnostic Docker boundary
shell: bash
run: |
set -euo pipefail
export PYTHONPATH="$GITHUB_WORKSPACE/proof/region/v1:$GITHUB_WORKSPACE/proof/region/v1/arb"
export LABCOLORS_ARB_PIPELINE_DOCKER
python3 - <<'PY'
import os
import sys
from pathlib import Path

import pipeline

docker = pipeline.NativeDockerBuildBackendV1(
Path(os.environ["LABCOLORS_ARB_PIPELINE_DOCKER"])
).probe()
print(repr(docker))
if type(docker) is not pipeline.DockerSupportedV1:
sys.exit(78)
PY

- name: delegate one disposable cgroup subtree
shell: bash
run: |
set -euo pipefail
test -f /proc/sys/kernel/apparmor_restrict_unprivileged_userns
original_userns="$(cat /proc/sys/kernel/apparmor_restrict_unprivileged_userns)"
case "$original_userns" in
0|1) ;;
*) exit 78 ;;
esac
echo "LABCOLORS_APPARMOR_USERNS_V1=$original_userns" >> "$GITHUB_ENV"
sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0
test "$(cat /proc/sys/kernel/apparmor_restrict_unprivileged_userns)" = 0
Comment thread
coderabbitai[bot] marked this conversation as resolved.
scope="$LABCOLORS_CGROUP_SCOPE_V1"
sudo mkdir "$scope"
sudo chown "$(id -u):$(id -g)" \
"$scope" \
"$scope/cgroup.procs" \
"$scope/cgroup.threads" \
"$scope/cgroup.subtree_control"
printf '+memory +pids' > "$scope/cgroup.subtree_control"
mkdir "$scope/tasks" "$scope/proof"
printf '+memory +pids' > "$scope/proof/cgroup.subtree_control"
printf '2' > "$scope/proof/pids.max"
mkdir "$scope/proof/observer"
grep --fixed-strings --quiet 'memory' "$scope/proof/cgroup.subtree_control"
grep --fixed-strings --quiet 'pids' "$scope/proof/cgroup.subtree_control"
test "$(cat "$scope/proof/pids.max")" = 2

- name: two fresh offline builds and evaluator runtime
shell: bash
run: |
set -euo pipefail
echo "$$" | sudo tee \
"$LABCOLORS_CGROUP_SCOPE_V1/tasks/cgroup.procs" >/dev/null
python3 proof/region/v1/arb/tests/native_gate.py build
test -f "$LABCOLORS_ARB_NATIVE_BINARY"
test "$(stat --format=%a "$LABCOLORS_ARB_NATIVE_BINARY")" = 400

- name: native containment under an atomic two-task subtree
shell: bash
run: |
set -euo pipefail
echo "$$" | sudo tee \
"$LABCOLORS_EXECUTOR_CGROUP_V1/observer/cgroup.procs" >/dev/null
exec python3 proof/region/v1/arb/tests/native_gate.py executor

# No upload step: the static binary is an ephemeral observation until a
# linker/member inventory plus notices/source/relink distribution gate exists.

- name: remove disposable inputs and cgroup
if: always()
shell: bash
run: |
set -uo pipefail
status=0
record_failure() {
local code="$?"
if (( status == 0 )); then
status="$code"
fi
}
if [[ -n "${LABCOLORS_ARB_SOURCE_DIR:-}" ]]; then
rm -rf -- "$LABCOLORS_ARB_SOURCE_DIR" || record_failure
fi
if [[ -n "${LABCOLORS_ARB_NATIVE_BINARY:-}" ]]; then
rm -f -- "$LABCOLORS_ARB_NATIVE_BINARY" || record_failure
fi
if [[ -n "${LABCOLORS_CGROUP_SCOPE_V1:-}" && \
-d "$LABCOLORS_CGROUP_SCOPE_V1" ]]; then
if [[ -f "$LABCOLORS_CGROUP_SCOPE_V1/cgroup.kill" ]]; then
echo 1 | sudo tee "$LABCOLORS_CGROUP_SCOPE_V1/cgroup.kill" \
>/dev/null || record_failure
fi
if [[ -f "$LABCOLORS_CGROUP_SCOPE_V1/cgroup.events" ]]; then
for _ in {1..100}; do
grep --fixed-strings --quiet 'populated 0' \
"$LABCOLORS_CGROUP_SCOPE_V1/cgroup.events" && break
sleep 0.01
done
grep --fixed-strings --quiet 'populated 0' \
"$LABCOLORS_CGROUP_SCOPE_V1/cgroup.events" || record_failure
fi
for child in proof/observer proof tasks; do
if [[ -d "$LABCOLORS_CGROUP_SCOPE_V1/$child" ]]; then
sudo rmdir "$LABCOLORS_CGROUP_SCOPE_V1/$child" || record_failure
fi
done
sudo rmdir "$LABCOLORS_CGROUP_SCOPE_V1" || record_failure
fi
if [[ -n "${LABCOLORS_APPARMOR_USERNS_V1:-}" ]]; then
sudo sysctl -w \
"kernel.apparmor_restrict_unprivileged_userns=$LABCOLORS_APPARMOR_USERNS_V1" \
>/dev/null || record_failure
fi
exit "$status"
94 changes: 77 additions & 17 deletions proof/region/v1/PROTOCOL.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ processes. `region_proof_protocol.py` определяет только structur
admission функций сравнения. Текущий `controller.py` безопасно читает и
повторно проверяет пять frozen protocol fixtures; он ещё не строит и не
запускает evaluator, не разрешает comparator manifest и не создаёт provenance
receipt. Ни один текущий модуль не вычисляет цвет или interval enclosure и не
создаёт semantic proof type.
receipt. Structural protocol и controller не вычисляют formula или interval
enclosure. Диагностический `arb/evaluator` вычисляет Arb-enclosures и выпускает
связанные transcript bytes, но не проверяет их независимым replay и не создаёт
semantic proof type.

`V5b2c-0` определяет protocol/admission, но сам не является математическим
proof. В c0 нет `DualProofReceiptV1`: structural agreement кодируется
Expand All @@ -30,11 +32,14 @@ diversity.

## Wire и identity

Все целые беззнаковые и записаны big-endian как `u8`, `u32be` или `u64be`.
`digest` — ровно 32 ненулевых bytes SHA-256. `blob` равен
`u64be(length) || bytes`. Enum занимает один `u8` и принимает только
перечисленные значения. Padding, alignment, reserved fields и trailing bytes
отсутствуют.
Для wire-artifact-ов из `region_proof_protocol.py` все целые беззнаковые и
записаны big-endian как `u8`, `u32be` или `u64be`; `digest` — ровно 32
ненулевых bytes SHA-256, а `blob` равен `u64be(length) || bytes`.
`SourceReleaseLockV1` и связанные provenance-artifact-ы имеют отдельный codec
в `provenance.py`: его `blob` равен `u32be(length) || bytes`; grammar также
содержит свои `u16` и 20-byte OpenPGP/SHA-1 coordinates. Enum занимает один
`u8` и принимает только перечисленные значения. Padding, alignment, reserved
fields и trailing bytes отсутствуют.

До allocation и цикла по records parser проверяет арифметику длины без
переполнения, остаток input, точный или минимальный wire-размер всех
Expand All @@ -53,12 +58,15 @@ artifact, а повторный encode обязан вернуть byte-identica
| `ReducedDomainManifestV1` | `LCDOM1\0\0` | `labcolors.proof-region.domain.v1` |
| `ProofPolicyV1` | `LCPOL1\0\0` | `labcolors.proof-region.policy.v1` |
| `ProofJobV1` | `LCJOB1\0\0` | `labcolors.proof-region.job.v1` |
| `ComparatorManifestV1` | `LCMAN1\0\0` | `labcolors.proof-region.comparator-manifest.v1` |
| `ComparatorManifestV2` | `LCMAN2\0\0` | `labcolors.proof-region.comparator-manifest.v2` |
| `DecisionTranscriptV1` | `LCTRN1\0\0` | `labcolors.proof-region.transcript.v1` |
| `RunClaimV1` | `LCRUN1\0\0` | `labcolors.proof-region.run-claim.v1` |
| `EvaluatorProvenanceClaimV1` | `LCPRV1\0\0` | `labcolors.proof-region.evaluator-provenance-claim.v1` |
| `DualComparisonClaimV1` | `LCCMP1\0\0` | `labcolors.proof-region.dual-comparison.v1` |

Версия принадлежит отдельному artifact type. Composite V1 wire связывает
identity независимо версионированного comparator manifest как opaque digest.

## `ContextualRegionDefinitionV1`

Definition не получает protocol magic. Это точный V5b2b canonical preimage:
Expand Down Expand Up @@ -144,26 +152,78 @@ definition. Job задаёт единственный канонический i
вычислителей; только controlled-executor slice сможет доказать отсутствие
ambient inputs. Альтернативный JSON/TOML definition запрещён протоколом.

## `ComparatorManifestV1`

Wire после `LCMAN1\0\0` содержит comparator kind `u8`
## Source lock и integrity observations

`SourceReleaseLockV1` фиксирует bytes и структурный состав архива. Поле
`.integrity` содержит один `SourceIntegrityPolicyV1`; это требование проверки,
а не заявление о publisher origin. Поле
`legal_files` — только точный project-pinned набор находящихся в архиве legal
files; оно не заявляет полноту legal-набора или compliance распространяемого
бинарника. Несовпадение этого набора имеет отдельную причину
`legal_files_mismatch`.

Для GMP и MPFR locked detached signature, key packets и исторический
`VALIDSIG` связываются только в
`HistoricalPathRecheckedSignatureDiagnosticV1`. Digest и version запущенного
`gpgv` остаются диагностикой. Запуск принадлежит переданному клиентом
`DiagnosticProcessRunnerV1`: Core ограничивает и парсит возвращённые bytes, но
не выдаёт runner за sandbox, containment или provenance authority. Встроенного
`Popen` fallback нет. Этот тип не устанавливает текущего publisher,
текущий статус или отзыв ключа, происхождение полученных bytes и exact sealed
execution verifier. Такой diagnostic не может заменить будущий source-bound
receipt.

Для FLINT `GitContentRelationPolicyV1` фиксирует commit, tree, исключённые
paths и отдельные `project_pinned_release_only_files`. `run_git_tree` принимает
такой же client-owned diagnostic runner, после чего Core независимо
пересчитывает commit, commit-to-tree edge, recursive tree и каждый
blob. Поэтому admission создаёт один `RecomputedGitContentRelationV1`: paths
архива должны быть точным дизъюнктным объединением общих Git files и
project-pinned release-only files, а исключённые paths обязаны отсутствовать.
Git executable/version, repository URL и tag являются диагностикой или
координатами поиска и не входят в authority этой relation. Relation доказывает
совпадение content graph, но не publisher или канал получения архива.

## Diagnostic execution boundary

`ControlledExecutorV1` — единственный владелец one-shot capability: новый,
неуспешный, перекрывающийся probe или замена backend отзывают ранее выданный
объект до RUN. Capability выпускается контроллером для одного probe-поколения
и одного process id; fork не дублирует право запуска. Backend сообщает только
наблюдённые свойства хоста, получает guard текущего probe и не может продлить
жизнь capability повторно используемым report-объектом.

Linux backend допускается лишь в отдельном helper process. Helper находится в
прямом дочернем cgroup объявленного parent, а весь parent subtree имеет
`pids.max = 2` и перед probe содержит ровно observer. Эти два task slots имеют
не эвристический смысл: один занимает observer, второй — либо новый thread,
либо единственный controlled child. Kernel pids controller атомарно разрешает
только один из вариантов; поэтому check→fork race не маскируется повторным
опросом `/proc`. Execution child дополнительно получает собственный
`pids.max = 1`, memory limit и `cgroup.kill`; фактические limits читаются назад
до запуска. Отсутствие этой структуры возвращает typed unsupported/setup
outcome. Этот runtime остаётся diagnostic observation и не создаёт receipt.

## `ComparatorManifestV2`

Wire после `LCMAN2\0\0` содержит comparator kind `u8`
(`1 = Arb`, `2 = MPFI`), затем десять digest coordinates в фиксированном
порядке:

1. engine release;
2. upstream source;
3. arithmetic closure;
3. arithmetic input set;
4. wrapper source;
5. evaluator source;
6. build identity, включая compiler, target и exact flags;
7. operation allowlist;
8. test receipt;
9. license closure;
8. test observation;
9. legal file set;
10. exclusions.

Результат wire parse — только raw `ComparatorManifestV1`: его ненулевые
Результат wire parse — только raw `ComparatorManifestV2`: его ненулевые
coordinates являются заявленными content addresses, а не доказанным
source binding. `ContentResolvedComparatorManifestV1` создаётся только
source binding. `ContentResolvedComparatorManifestV2` создаётся только
после того, как переданный вызывающим `resolve_content_address` для каждой из десяти
coordinates вернул exact `bytes` или `Iterable[bytes]`. Сам protocol повторяет
SHA-256 по этим bytes/chunks и сравнивает результат с coordinate. Boolean,
Expand Down Expand Up @@ -331,7 +391,7 @@ raw claim. Он никогда не возвращает admitted candidate. Н
refined type.

Candidate строится в canonical order Arb → MPFI из двух
`ContentResolvedComparatorManifestV1`, согласованных `RunClaimV1` и
`ContentResolvedComparatorManifestV2`, согласованных `RunClaimV1` и
structurally admitted transcripts. Все bindings ведут к одному job, definition,
domain и policy; `domain_point_count` равен count связанного manifest.
Unresolved counters равны нулю, decision payloads совпадают побайтно,
Expand Down
Loading
Loading