Files
agent-pet-companion/.github/workflows/ci.yml
T
xjxandgd-ops 790046d9a8 Add protected parallel delivery workflow (#6)
## Development lane / 开发通道

- Lane: `direct-to-main` bootstrap
- Base branch: `main`
- Active train: `n/a`
- Owning Agent/session: workflow coordinator

## Change / 改动

- Split authoritative CI into parallel static, contract, Rust lint/test
shards, Swift interaction, stress, overlay, bundle, and stable `Required
CI` jobs.
- Make every ready PR to `main` a complete gate while keeping task PRs
to `gd-ops/train/*` path-scoped.
- Add direct/train worktree coordination, bounded changelog fragments,
protected main/train ruleset automation, and safe same-repository squash
auto-merge.
- Let GitHub Release promote an exact successful main commit, reuse its
source proof, and create a missing release tag only after proof
validation.
- Keep local pre-push validation bounded to basic syntax, formatting,
contracts, and compilation; complete duplicate proof stays in GitHub CI.

This is the one bootstrap PR: the auto-merge workflow and required rules
do not exist on the base branch yet. After this PR passes and is merged
once, the exact `main` push must pass `Required CI`; then the
fail-closed applicator can activate both rulesets and all later ready
`gd-ops/*` PRs follow the automated path.

## Validation / 验证

- `actionlint .github/workflows/ci.yml .github/workflows/release.yml
.github/workflows/auto-merge.yml`
- `./script/validate_source_syntax.sh`
- `./script/validate_build_scripts_safety.sh --skip-source-syntax`
- Exact staged diff was reapplied to a clean detached worktree before
the final validation run.
- 28 validation-tooling tests, 40 release-distribution tests, macOS
build-contract tests, Release shell contracts, and test-isolation
validation passed.

## Risk / 风险

- No product runtime or credential access is added.
- `pull_request_target` never checks out or executes PR code and only
enables auto-merge after API verification of active PR and `Required CI`
rules.
- Full ruleset activation fails closed until the exact remote main
commit has a trusted successful GitHub Actions push run.
- Reversible repository settings are already enabled: auto-merge,
squash-only, update branch, and delete merged branches.

---------

Co-authored-by: gd-ops <gd-ops@xmfunny.com>
2026-08-11 20:28:02 +08:00

608 lines
24 KiB
YAML

name: CI
on:
pull_request:
types: [opened, synchronize, reopened, ready_for_review, converted_to_draft]
push:
branches: [main]
permissions:
contents: read
concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
APC_VALIDATE_HOST_UI: "0"
APC_VALIDATE_REAL_AGENT_CONNECTORS: "0"
APC_VALIDATE_REAL_APP_SERVER: "0"
CARGO_TERM_COLOR: always
jobs:
scope:
name: Classify change once
runs-on: macos-26
timeout-minutes: 10
outputs:
base: ${{ steps.validation_base.outputs.base }}
docs_only: ${{ steps.validation_scope.outputs.docs_only }}
localization: ${{ steps.validation_scope.outputs.localization }}
scripts: ${{ steps.validation_scope.outputs.scripts }}
producer: ${{ steps.validation_scope.outputs.producer }}
connectors: ${{ steps.validation_scope.outputs.connectors }}
schemas: ${{ steps.validation_scope.outputs.schemas }}
plugin_version: ${{ steps.validation_scope.outputs.plugin_version }}
rust_mode: ${{ steps.validation_scope.outputs.rust_mode }}
swift_mode: ${{ steps.validation_scope.outputs.swift_mode }}
bundle: ${{ steps.validation_scope.outputs.bundle }}
computer_use: ${{ steps.validation_scope.outputs.computer_use }}
lane: ${{ steps.development_context.outputs.lane }}
full_candidate: ${{ steps.development_context.outputs.full_candidate }}
release_source: ${{ steps.development_context.outputs.release_source }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
fetch-depth: 0
- name: Resolve validation base
id: validation_base
env:
EVENT_NAME: ${{ github.event_name }}
PR_BASE: ${{ github.event.pull_request.base.sha }}
PUSH_BASE: ${{ github.event.before }}
run: |
if [[ "$EVENT_NAME" == "pull_request" ]]; then
base="$PR_BASE"
else
base="$PUSH_BASE"
fi
if [[ "$base" == "0000000000000000000000000000000000000000" ]]; then
base="$(git rev-parse HEAD^ 2>/dev/null || git rev-parse HEAD)"
fi
git rev-parse --verify "$base^{commit}" >/dev/null
echo "base=$base" >>"$GITHUB_OUTPUT"
- name: Classify changed paths
id: validation_scope
run: |
./script/validation_scope.py \
--base-ref "${{ steps.validation_base.outputs.base }}" \
--format github >>"$GITHUB_OUTPUT"
- name: Resolve direct, train, and main validation lane
id: development_context
env:
EVENT_NAME: ${{ github.event_name }}
PR_BASE_BRANCH: ${{ github.base_ref }}
PR_HEAD_BRANCH: ${{ github.head_ref }}
PR_DRAFT: ${{ github.event.pull_request.draft }}
run: |
if [[ "$EVENT_NAME" == "pull_request" ]]; then
./script/development_flow.py ci-context \
--event pull_request \
--base "$PR_BASE_BRANCH" \
--head "$PR_HEAD_BRANCH" \
--draft "${PR_DRAFT:-false}" \
--format github >>"$GITHUB_OUTPUT"
else
./script/development_flow.py ci-context \
--event push \
--base main \
--format github >>"$GITHUB_OUTPUT"
fi
static:
name: Static source contracts
needs: scope
runs-on: macos-26
timeout-minutes: 15
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
fetch-depth: 0
- name: Install common validation tooling
run: |
if ! command -v rg >/dev/null 2>&1; then
brew install ripgrep
fi
- name: Diff and source syntax
run: |
git diff --check "${{ needs.scope.outputs.base }}" --
./script/validate_source_syntax.sh
- name: Localization parity
if: needs.scope.outputs.full_candidate == '1' || needs.scope.outputs.localization == '1'
run: ./script/validate_localizations.py
- name: Static workflow and build-script contracts
if: needs.scope.outputs.full_candidate == '1' || needs.scope.outputs.scripts == '1'
run: ./script/validate_build_scripts_safety.sh --skip-source-syntax --static-only
- name: Validate parallel changelog fragments
run: ./script/changelog_fragments.py validate
- name: Require main-bound changelog consolidation
if: >-
needs.scope.outputs.full_candidate == '1' &&
needs.scope.outputs.lane != 'task-to-train'
run: ./script/changelog_fragments.py require-consumed
- name: Codex plugin and Skill version discipline for this change
if: needs.scope.outputs.plugin_version == '1'
run: ./script/validate_codex_plugin_version.py --base-ref "${{ needs.scope.outputs.base }}"
contracts:
name: Source and integration contracts
needs: scope
if: >-
needs.scope.outputs.full_candidate == '1' ||
needs.scope.outputs.docs_only != '1'
runs-on: macos-26
timeout-minutes: 30
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
fetch-depth: 0
- name: Install common validation tooling
run: |
if ! command -v rg >/dev/null 2>&1; then
brew install ripgrep
fi
- name: Prepare pinned Python validation environment
if: needs.scope.outputs.full_candidate == '1' || needs.scope.outputs.producer == '1' || needs.scope.outputs.bundle == '1'
run: |
python3 -m venv "$RUNNER_TEMP/apc-validation-python"
"$RUNNER_TEMP/apc-validation-python/bin/python" -m pip install \
--disable-pip-version-check --no-deps --only-binary=:all: "Pillow==11.3.0"
"$RUNNER_TEMP/apc-validation-python/bin/python" - <<'PY'
from PIL import Image, features
if Image.__version__ != "11.3.0" or not features.check("webp_anim"):
raise SystemExit("pinned Pillow lacks the required animated WebP support")
PY
echo "$RUNNER_TEMP/apc-validation-python/bin" >>"$GITHUB_PATH"
- name: Restore contract build products
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-${{ runner.arch }}-apc-contracts-${{ hashFiles('rust-toolchain.toml', 'Cargo.lock') }}
restore-keys: |
${{ runner.os }}-${{ runner.arch }}-apc-contracts-
${{ runner.os }}-${{ runner.arch }}-apc-rust-
- name: Complete build and workflow contracts
if: needs.scope.outputs.full_candidate == '1' || needs.scope.outputs.scripts == '1'
run: ./script/validate_build_scripts_safety.sh --skip-source-syntax
- name: App lifecycle contract
if: needs.scope.outputs.full_candidate == '1' || needs.scope.outputs.swift_mode != 'none'
run: ./script/validate_app_lifecycle_contract.sh
- name: Schema contracts
if: needs.scope.outputs.full_candidate == '1' || needs.scope.outputs.schemas == '1' || needs.scope.outputs.producer == '1'
run: |
./script/validate_schema_fixtures.sh
./script/validate_petpack_spec_schemas.sh
- name: Portable producer contracts
if: needs.scope.outputs.full_candidate == '1' || needs.scope.outputs.producer == '1'
run: |
./script/validate_pet_skills.sh
./script/validate_portable_pet_maker.sh
- name: Generated connector runtime
if: needs.scope.outputs.full_candidate == '1' || needs.scope.outputs.connectors == '1'
run: ./script/validate_connectors_runtime.sh
- name: Security boundaries
if: >-
needs.scope.outputs.full_candidate == '1' ||
needs.scope.outputs.rust_mode != 'none' ||
needs.scope.outputs.schemas == '1' ||
needs.scope.outputs.producer == '1' ||
needs.scope.outputs.connectors == '1'
run: ./script/validate_security_boundaries.sh
rust_lint:
name: Rust formatting and linting
needs: scope
if: needs.scope.outputs.full_candidate == '1' || needs.scope.outputs.rust_mode != 'none'
runs-on: macos-26
timeout-minutes: 20
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- name: Verify Rust toolchain
run: rustup show
- name: Restore Rust lint cache
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-${{ runner.arch }}-apc-rust-lint-${{ hashFiles('rust-toolchain.toml', 'Cargo.lock') }}
restore-keys: |
${{ runner.os }}-${{ runner.arch }}-apc-rust-
- name: Rust formatting
run: cargo fmt --all -- --check
- name: Strict Rust linting
run: cargo clippy --workspace --all-targets --all-features --locked -- -D warnings
rust_tests:
name: Rust tests (${{ matrix.shard }})
needs: scope
if: needs.scope.outputs.full_candidate == '1' || needs.scope.outputs.rust_mode != 'none'
strategy:
fail-fast: false
matrix:
shard: [core, integration-a, integration-b, integration-c, integration-d]
runs-on: macos-26
timeout-minutes: 25
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- name: Verify Rust toolchain
run: rustup show
- name: Restore Rust test cache
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-${{ runner.arch }}-apc-rust-${{ matrix.shard }}-${{ hashFiles('rust-toolchain.toml', 'Cargo.lock') }}
restore-keys: |
${{ runner.os }}-${{ runner.arch }}-apc-rust-${{ matrix.shard }}-
${{ runner.os }}-${{ runner.arch }}-apc-rust-
- name: Run inventory-checked Rust shard
run: ./script/validate_rust_test_shards.py --shard "${{ matrix.shard }}"
swift_interaction:
name: Swift and interaction proof
needs: scope
if: needs.scope.outputs.full_candidate == '1' || needs.scope.outputs.bundle == '1' || needs.scope.outputs.swift_mode != 'none'
runs-on: macos-26
timeout-minutes: 25
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- name: Verify App build toolchain
run: ./script/validate_macos_build_contract.py toolchain
- name: Restore Swift build products
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6
with:
path: apps/macos/.build
key: ${{ runner.os }}-${{ runner.arch }}-apc-swift-${{ hashFiles('apps/macos/Package.swift', 'apps/macos/Package.resolved') }}
restore-keys: |
${{ runner.os }}-${{ runner.arch }}-apc-swift-
- name: Run complete Swift suite and create source interaction proof
env:
APC_BUILD_ID: source.${{ github.sha }}
run: |
./script/prepare_interaction_attestation.sh \
--output "$RUNNER_TEMP/interaction-attestation.json" \
--swift-scope all
- name: Upload source interaction proof
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: ci-interaction-attestation-${{ github.sha }}
if-no-files-found: error
retention-days: 3
path: ${{ runner.temp }}/interaction-attestation.json
stress:
name: Bounded event-storm stress
needs: scope
if: needs.scope.outputs.full_candidate == '1'
runs-on: macos-26
timeout-minutes: 15
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- name: Restore Rust stress cache
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-${{ runner.arch }}-apc-rust-stress-${{ hashFiles('rust-toolchain.toml', 'Cargo.lock') }}
restore-keys: |
${{ runner.os }}-${{ runner.arch }}-apc-rust-
- name: Run release-grade bounded event storm
run: ./script/validate_event_storm.sh
overlay:
name: Offline overlay contracts
needs: [scope, swift_interaction]
if: >-
always() &&
(needs.scope.outputs.full_candidate == '1' || needs.scope.outputs.bundle == '1' || needs.scope.outputs.swift_mode != 'none') &&
needs.swift_interaction.result == 'success'
runs-on: macos-26
timeout-minutes: 20
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
with:
name: ci-interaction-attestation-${{ github.sha }}
path: ${{ runner.temp }}/interaction-proof
- name: Restore Swift build products
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6
with:
path: apps/macos/.build
key: ${{ runner.os }}-${{ runner.arch }}-apc-swift-${{ hashFiles('apps/macos/Package.swift', 'apps/macos/Package.resolved') }}
restore-keys: |
${{ runner.os }}-${{ runner.arch }}-apc-swift-
- name: Run offline overlay geometry, scheduler, accessibility, frame, and pointer contracts
run: |
./script/validate_overlay_offline.sh \
--interaction-attestation "$RUNNER_TEMP/interaction-proof/interaction-attestation.json"
bundle:
name: Packaged development App proof
needs: [scope, contracts, rust_lint, rust_tests, swift_interaction, overlay]
if: >-
always() &&
(needs.scope.outputs.full_candidate == '1' || needs.scope.outputs.bundle == '1')
runs-on: macos-26
timeout-minutes: 30
steps:
- name: Require successful source dependencies
env:
CONTRACTS_RESULT: ${{ needs.contracts.result }}
RUST_LINT_RESULT: ${{ needs.rust_lint.result }}
RUST_TESTS_RESULT: ${{ needs.rust_tests.result }}
SWIFT_RESULT: ${{ needs.swift_interaction.result }}
OVERLAY_RESULT: ${{ needs.overlay.result }}
run: |
for result in "$CONTRACTS_RESULT" "$RUST_LINT_RESULT" "$RUST_TESTS_RESULT" "$SWIFT_RESULT" "$OVERLAY_RESULT"; do
case "$result" in
success|skipped) ;;
*) echo "bundle dependency did not succeed: $result" >&2; exit 1 ;;
esac
done
test "$SWIFT_RESULT" = "success"
test "$OVERLAY_RESULT" = "success"
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
with:
name: ci-interaction-attestation-${{ github.sha }}
path: ${{ runner.temp }}/interaction-proof
- name: Rebind source interaction proof to the development build identity
id: development_identity
run: |
version="$(awk -F'"' '/^version = / {print $2; exit}' crates/petcore/Cargo.toml)"
variant="debug|$(uname -m)|universal=0|signed=1"
fingerprint="$(
./script/validation_fingerprint.py \
--root "$GITHUB_WORKSPACE" \
--scope runtime \
--extra "$variant"
)"
build_id="$version.1.develop.${fingerprint:0:16}"
APC_BUILD_ID="$build_id" \
./script/prepare_interaction_attestation.sh \
--output "$RUNNER_TEMP/interaction-proof/development-attestation.json" \
--proof-in "$RUNNER_TEMP/interaction-proof/interaction-attestation.json"
echo "build_id=$build_id" >>"$GITHUB_OUTPUT"
- name: Prepare pinned Python validation environment
run: |
python3 -m venv "$RUNNER_TEMP/apc-validation-python"
"$RUNNER_TEMP/apc-validation-python/bin/python" -m pip install \
--disable-pip-version-check --no-deps --only-binary=:all: "Pillow==11.3.0"
echo "$RUNNER_TEMP/apc-validation-python/bin" >>"$GITHUB_PATH"
- name: Restore Rust build products
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-${{ runner.arch }}-apc-rust-bundle-${{ hashFiles('rust-toolchain.toml', 'Cargo.lock') }}
restore-keys: |
${{ runner.os }}-${{ runner.arch }}-apc-rust-
- name: Restore Swift build products
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6
with:
path: apps/macos/.build
key: ${{ runner.os }}-${{ runner.arch }}-apc-swift-${{ hashFiles('apps/macos/Package.swift', 'apps/macos/Package.resolved') }}
restore-keys: |
${{ runner.os }}-${{ runner.arch }}-apc-swift-
- name: Build and fully validate development App from the proven interaction contract
env:
APC_BUILD_ID: ${{ steps.development_identity.outputs.build_id }}
run: |
./script/build_app_bundle.sh \
--configuration debug \
--interaction-attestation "$RUNNER_TEMP/interaction-proof/development-attestation.json" \
--validation full
source_proof:
name: Bind release source proof to main commit
needs: [scope, static, contracts, rust_lint, rust_tests, swift_interaction, stress, overlay, bundle]
if: always() && needs.scope.outputs.release_source == '1'
runs-on: macos-26
timeout-minutes: 15
permissions:
contents: read
env:
GH_TOKEN: ${{ github.token }}
steps:
- name: Require every release source gate
env:
STATIC_RESULT: ${{ needs.static.result }}
CONTRACTS_RESULT: ${{ needs.contracts.result }}
RUST_LINT_RESULT: ${{ needs.rust_lint.result }}
RUST_TESTS_RESULT: ${{ needs.rust_tests.result }}
SWIFT_RESULT: ${{ needs.swift_interaction.result }}
STRESS_RESULT: ${{ needs.stress.result }}
OVERLAY_RESULT: ${{ needs.overlay.result }}
BUNDLE_RESULT: ${{ needs.bundle.result }}
run: |
for result in "$STATIC_RESULT" "$CONTRACTS_RESULT" "$RUST_LINT_RESULT" "$RUST_TESTS_RESULT" "$SWIFT_RESULT" "$STRESS_RESULT" "$OVERLAY_RESULT" "$BUNDLE_RESULT"; do
case "$result" in
success) ;;
*) echo "release source dependency did not succeed: $result" >&2; exit 1 ;;
esac
done
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
fetch-depth: 0
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
with:
name: ci-interaction-attestation-${{ github.sha }}
path: ${{ runner.temp }}/interaction-proof
- name: Verify and record proof-host toolchains
run: ./script/validate_macos_build_contract.py toolchain
- name: Resolve latest stable release baseline
id: release_baseline
run: |
previous_tag="$(
gh api \
-H 'Accept: application/vnd.github+json' \
-H 'X-GitHub-Api-Version: 2026-03-10' \
"repos/$GITHUB_REPOSITORY/releases/latest" \
--jq '.tag_name'
)"
[[ "$previous_tag" =~ ^v[0-9]+[.][0-9]+[.][0-9]+$ ]]
echo "previous_tag=$previous_tag" >>"$GITHUB_OUTPUT"
- name: Recheck Codex plugin and bundled Skill version discipline
run: ./script/validate_codex_plugin_version.py --base-ref "${{ steps.release_baseline.outputs.previous_tag }}"
- name: Create exact-commit source proof
run: |
mkdir -p "$RUNNER_TEMP/release-source-proof"
cp "$RUNNER_TEMP/interaction-proof/interaction-attestation.json" \
"$RUNNER_TEMP/release-source-proof/interaction-attestation.json"
./script/release_source_proof.py create \
--repository "$GITHUB_REPOSITORY" \
--commit "$GITHUB_SHA" \
--previous-release-tag "${{ steps.release_baseline.outputs.previous_tag }}" \
--run-id "$GITHUB_RUN_ID" \
--run-attempt "$GITHUB_RUN_ATTEMPT" \
--attestation "$RUNNER_TEMP/release-source-proof/interaction-attestation.json" \
--output "$RUNNER_TEMP/release-source-proof/source-proof.json"
- name: Upload exact-commit release source proof
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: release-source-proof-${{ github.sha }}
if-no-files-found: error
retention-days: 7
path: ${{ runner.temp }}/release-source-proof
required:
name: Required CI
needs: [scope, static, contracts, rust_lint, rust_tests, swift_interaction, stress, overlay, bundle, source_proof]
if: always()
runs-on: macos-26
timeout-minutes: 10
steps:
- name: Require every scheduled job
env:
SCOPE_RESULT: ${{ needs.scope.result }}
STATIC_RESULT: ${{ needs.static.result }}
CONTRACTS_RESULT: ${{ needs.contracts.result }}
RUST_LINT_RESULT: ${{ needs.rust_lint.result }}
RUST_TESTS_RESULT: ${{ needs.rust_tests.result }}
SWIFT_RESULT: ${{ needs.swift_interaction.result }}
STRESS_RESULT: ${{ needs.stress.result }}
OVERLAY_RESULT: ${{ needs.overlay.result }}
BUNDLE_RESULT: ${{ needs.bundle.result }}
SOURCE_PROOF_RESULT: ${{ needs.source_proof.result }}
FULL_CANDIDATE: ${{ needs.scope.outputs.full_candidate }}
RELEASE_SOURCE: ${{ needs.scope.outputs.release_source }}
run: |
for result in \
"$SCOPE_RESULT" "$STATIC_RESULT" "$CONTRACTS_RESULT" \
"$RUST_LINT_RESULT" "$RUST_TESTS_RESULT" "$SWIFT_RESULT" \
"$STRESS_RESULT" "$OVERLAY_RESULT" "$BUNDLE_RESULT" "$SOURCE_PROOF_RESULT"; do
case "$result" in
success|skipped) ;;
*) echo "scheduled CI job did not succeed: $result" >&2; exit 1 ;;
esac
done
if [[ "$FULL_CANDIDATE" == "1" ]]; then
for result in \
"$STATIC_RESULT" "$CONTRACTS_RESULT" "$RUST_LINT_RESULT" \
"$RUST_TESTS_RESULT" "$SWIFT_RESULT" "$STRESS_RESULT" \
"$OVERLAY_RESULT" "$BUNDLE_RESULT"; do
case "$result" in
success) ;;
*) echo "complete main-bound job did not succeed: $result" >&2; exit 1 ;;
esac
done
fi
if [[ "$RELEASE_SOURCE" == "1" ]]; then
test "$SOURCE_PROOF_RESULT" = "success"
fi
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- name: Record live UI validation routing
env:
DEVELOPMENT_LANE: ${{ needs.scope.outputs.lane }}
run: |
printf 'Development lane: %s.\n' "$DEVELOPMENT_LANE" >>"$GITHUB_STEP_SUMMARY"
if [[ "${{ needs.scope.outputs.full_candidate }}" == "1" ]]; then
echo 'This is a complete main-bound candidate gate.' >>"$GITHUB_STEP_SUMMARY"
else
echo 'This is a change-scoped task-to-train or draft gate.' >>"$GITHUB_STEP_SUMMARY"
fi
if [[ "${{ needs.scope.outputs.computer_use }}" == "recommended" ]]; then
echo 'UI source changed: Computer Use is recommended for a human-owned acceptance session, but is never auto-run in CI.' >>"$GITHUB_STEP_SUMMARY"
else
echo 'No live UI or Computer Use validation is required for this change scope.' >>"$GITHUB_STEP_SUMMARY"
fi
- name: Reject tracked build output and caches
run: |
tracked_generated="$(
git ls-files \
| grep -E '(^|/)(__pycache__/|[^/]+\.py[co]$|DerivedData/|target/|\.build/|[^/]+\.petpack$|generation-jobs/)' \
| grep -Ev '^apps/macos/Sources/AgentPetCompanion/Resources/BuiltInPets/(pet_bytebudcodex|pet_pinklace|pet_xingwutuanzi)\.petpack$' \
|| true
)"
if [[ -n "$tracked_generated" ]]; then
printf '%s\n' "$tracked_generated"
echo 'Tracked generated output or cache detected' >&2
exit 1
fi
- name: Verify clean generated state
run: git diff --check