Skip to content
Merged
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
21 changes: 16 additions & 5 deletions .github/workflows/validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
# Convenience only. Required-check and host policy need separate migration.
if: ${{ vars.CI_FLEET_HOSTED_VALIDATION == 'true' && (github.event_name != 'pull_request' || github.event.pull_request.state == 'open') }}
runs-on: ubuntu-latest
timeout-minutes: 5
timeout-minutes: 20
steps:
- name: Require independently pinned validator
env:
Expand Down Expand Up @@ -55,8 +55,19 @@ jobs:
persist-credentials: false
fetch-depth: 0

- name: Check out trusted executor
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
repository: RandomDevelopment/ci-fleet
ref: 689c7c00deb0eebcb25f2284334a9f7168a25575
path: .ci-fleet-executor
persist-credentials: false
fetch-depth: 0

- name: Install validation tools
run: sudo apt-get update && sudo apt-get install -y shellcheck
run: |
sudo apt-get update && sudo apt-get install -y shellcheck
sudo python3 -I "$GITHUB_WORKSPACE/.ci-fleet-executor/scripts/local_validation_executor.py" --prepare --disposable-host

- name: Run complete local validation
env:
Expand All @@ -74,7 +85,7 @@ jobs:
main="$BASE"
title_args+=(--pr-title "$PR_TITLE")
fi
python3 -I "$GITHUB_WORKSPACE/.ci-fleet-suite/scripts/local_validate.py" \
sudo python3 -I "$GITHUB_WORKSPACE/.ci-fleet-suite/scripts/local_validate.py" \
--repository "$GITHUB_WORKSPACE/candidate" --repository-name "$REPOSITORY" \
--source "$SOURCE" --base "$BASE" --main "$main" \
--policy-repository "$GITHUB_WORKSPACE/.ci-fleet-validator" --policy "$VALIDATOR" \
Expand All @@ -83,6 +94,6 @@ jobs:
- name: Show validation report
if: always()
run: |
if [[ -f "$RUNNER_TEMP/local-validation/result.json" ]]; then
cat "$RUNNER_TEMP/local-validation/result.json"
if sudo test -f "$RUNNER_TEMP/local-validation/result.json"; then
sudo cat "$RUNNER_TEMP/local-validation/result.json"
fi
42 changes: 26 additions & 16 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ complete exact-source suite from a clean, independently reviewed template
checkout, with an independently pinned engine validator:

```bash
python3 -I /trusted/template/scripts/local_validate.py \
sudo python3 -I /trusted/template/scripts/local_validate.py \
--repository /work/config --repository-name OWNER/REPOSITORY \
--source SOURCE_SHA --base BASE_SHA --main MAIN_SHA \
--policy-repository /trusted/ci-fleet --policy REVIEWED_ENGINE_VALIDATOR_SHA \
Expand All @@ -41,7 +41,10 @@ requires independently reviewed full engine and standalone-suite SHAs in
`CI_FLEET_VALIDATOR_REVISION` and `CI_FLEET_SUITE_REVISION`. The workflow runs
the pinned public standalone suite with the separate candidate checkout only
as its source input. Neither enabling it nor a local developer result changes
required checks or trusted host policy.
required checks or trusted host policy. The optional full-suite job has a
documented 20-minute developer-acceptance budget because complete validation
exceeds five minutes. Restore five minutes only after setup and complete
coverage reliably fit a four-minute payload. Ordinary task jobs keep five minutes.
Preserve existing required checks until an authorized policy migration and
tested recovery are complete. Core local-evidence support merged at
`67beabbddaad73c19f15bc3baa227779bc88dc96`; template release, compatible-manager
Expand All @@ -53,12 +56,13 @@ Required regression inventories come from the pinned suite for both upstream
and adopter validation. Candidate programs, optional workflows and upstream
release/setup documents supply inputs, never replacement required tests.
Candidate-added IDs run only after the required corpus. The mapped runner
requires unique planned IDs and matching execution counts. No actual skips are
accepted. Keep the trusted public
fixtures and derived upstream-probe applicability intact.
Run the pinned caller, supervisor and candidate-runner definitions against the
requires unique planned IDs and matching execution counts. Its standard-library
process worker must return a normal integer result; zero-status process exit
cannot substitute for test completion. Systemd owns deadlines and cleanup.
No actual skips are accepted. Keep the trusted public fixtures and derived upstream-probe applicability intact.
Run the pinned caller, executor-binding and candidate-runner definitions against the
candidate harness programs once in both upstream and adopter modes. Keep the
outer driver/supervisor pinned and runner self-test workflow inputs trusted;
outer driver and core executor pinned and runner self-test workflow inputs trusted;
those fixture inputs must not restore an absent candidate workflow.
In adopter policy, updater and release-update stages, run the complete public
and candidate-mapped corpora concurrently through the pinned runner in separate
Expand All @@ -70,7 +74,9 @@ Fresh verified source, engine-policy and trusted-suite checkouts for each stage
prevent persistent cross-stage substitution. Initial narrow Git fetches build
the seeds. Freeze their effective origin/main metadata before manifests, then
restore independent stage copies with symlinks and modes preserved, without
hardlinks or repeated fetches. Check seeds before restoration, require each
hardlinks or repeated fetches. Symlinks must resolve inside their own worktree
and outside `.git`; reject trusted-sibling and external targets, including
dangling ones, before candidate stages. Check seeds before restoration, require each
copied target to match that frozen seed manifest before candidate execution,
and check both seeds and stage trees afterward. All orchestrator Git calls and
stage environments must filter inherited and supplied `GIT_*` variables and
Expand All @@ -79,16 +85,20 @@ grafts. Preserve trusted fixture overrides such as the updater's private index.
These checks are not a sandbox against hostile root or same-stage transient
tampering. Independently review candidate
programs and the harness, and supervise execution on a disposable Linux machine
with mounted `/proc`, child subreaper and pidfd support, and Python 3.11 or newer.
The command supervisor never enables or changes the caller's existing
subreaper flag. It preserves either initial value, 0 or 1. It must confirm
complete descendant cleanup; missing results or forced cleanup after the
60-second grace fail validation. An external hard kill of the harness or
supervisor, or lost supervision, requires discarding the disposable execution
machine before another run.
with systemd 255 or newer, cgroup v2 and Python 3.11 or newer.
Prepare the shared core executor from the independently reviewed revision named
by `EXECUTOR_REVISION`. Require its protected installed revision/hash manifest;
never load an executor supplied by the candidate or add a fallback supervisor.
The root launcher gives ordinary stages a locked unprivileged account, read-only
trusted inputs and separate writable source/home/scratch paths. Harness fixtures
that exercise the root launcher remain disposable-machine-only. The system
manager must confirm cgroup cleanup; missing receipts and forced termination
fail. Lost-worker runs are incomplete. Export one complete verified result
bundle outside the worker before disposal. Signing authority remains separate.
Preflight rejects standard installed fleet and signing-role markers, including
broken symlinks. Platform and host admission happen before Git inspection,
output-directory creation, tool probes or candidate execution. Early admission
output-directory creation, tool probes or candidate execution. Installed-executor
revision, permission and host admission also precedes Git output discovery. Early admission
failures or invalid output locations return nonzero with a diagnostic on stderr
and create no output directory or report. Verify custom installations and the
execution machine's role separately, and keep the signing authority elsewhere.
Expand Down
19 changes: 11 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,14 @@ Optional `--default-bridge-cidr 192.0.2.1/24` also prints a review-only Docker n

## Complete local validation

Run this command on a supervised disposable Linux machine with `/proc` mounted,
kernel support for child subreapers and pidfds, Bash, Git, Python 3.11 or newer
and the documented validation tools. Replace every SHA placeholder with a full
Run this command as a trusted root launcher on a prepared disposable Linux
worker with systemd 255 or newer, cgroup v2, Bash, Git, Python 3.11 or newer
and the documented validation tools. The shared core executor runs ordinary
configuration stages unprivileged and keeps trusted inputs read-only. Replace every SHA placeholder with a full
reviewed commit identity:

```bash
python3 -I /trusted/template/scripts/local_validate.py \
sudo python3 -I /trusted/template/scripts/local_validate.py \
--repository /work/config --repository-name OWNER/REPOSITORY \
--source SOURCE_SHA --base BASE_SHA --main MAIN_SHA \
--policy-repository /trusted/ci-fleet --policy REVIEWED_ENGINE_VALIDATOR_SHA \
Expand All @@ -82,8 +83,8 @@ their ancestry, without unrelated branches or tags. Each stage restores an
independent copy of the verified frozen seeds, including Git metadata, modes
and symlinks. Files are not hardlinked back to a seed. Git identity checks use stored
objects with replacement refs and grafts disabled; orchestration and stage
environments filter caller-supplied `GIT_*` settings. A separate command
supervisor owns descendants through cleanup. It preserves the standalone policy, updater,
environments filter caller-supplied `GIT_*` settings. The installed, revision-pinned core executor delegates process ownership and
cleanup to the system manager. It preserves the standalone policy, updater,
exact-core, release-update and initializer checks. It writes per-check logs,
tool versions, identities and digests to the new output directory. Public
fictional fixtures remain distinct from strict initialized-adopter validation.
Expand All @@ -99,9 +100,9 @@ workflow inputs in trusted fictional fixtures. Upstream checks also use the
candidate's release/setup documents. Candidate-added test IDs run afterward as
supplemental coverage; they cannot replace the required definitions. The
mapped runner requires unique planned IDs and matching execution counts.
Actual skips fail validation. The pinned caller, supervisor and runner tests
Actual skips fail validation. The pinned caller, executor-binding and runner tests
exercise the candidate harness programs once in both upstream and adopter runs;
the outer execution driver and supervisor remain independently pinned. Runner
the outer execution driver and installed core executor remain independently pinned. Runner
self-tests use pinned workflow fixtures without restoring an absent candidate
workflow. Initialized adopters retain the complete trusted public policy,
updater, release and workflow corpus as well.
Expand All @@ -115,6 +116,8 @@ to the literal `true`. Independently pin `CI_FLEET_VALIDATOR_REVISION` to a
reviewed full engine commit SHA and `CI_FLEET_SUITE_REVISION` to a compatible
reviewed full commit in `RandomDevelopment/ci-fleet-config-template`.
The workflow runs that trusted suite's entry point with read-only permissions.
Its complete developer-acceptance suite has a 20-minute job limit; ordinary task
jobs retain five minutes. See the [budget and setup guidance](docs/LOCAL-VALIDATION.md#optional-hosted-convenience).
The candidate, trusted suite and engine use separate sibling checkouts with no
persisted checkout credentials. Missing or malformed pins fail validation. Set the flag to `false`, delete it, or remove that
workflow to stop hosted validation. Local validation still works. The flag
Expand Down
Loading